Loading...
Loading...
Build composable, responsive React charts with Recharts library. Use when creating data visualizations including line charts, area charts, bar charts, pie charts, scatter plots, and composed charts. Handles chart customization, responsive sizing, tooltips, legends, axes configuration, performance optimization, and accessibility.
npx skill4agent add ansanabria/skills rechartsnpm install rechartsimport { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer } from 'recharts';
const data = [
{ name: 'Jan', sales: 4000, profit: 2400 },
{ name: 'Feb', sales: 3000, profit: 1398 },
{ name: 'Mar', sales: 2000, profit: 9800 },
];
<ResponsiveContainer width="100%" height={300}>
<LineChart data={data}>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="name" />
<YAxis />
<Tooltip />
<Legend />
<Line type="monotone" dataKey="sales" stroke="#8884d8" />
<Line type="monotone" dataKey="profit" stroke="#82ca9d" />
</LineChart>
</ResponsiveContainer>const data = [
{ month: 'Jan', revenue: 4000, expenses: 2400 },
{ month: 'Feb', revenue: 3000, expenses: 1398 },
];dataKeydataKey="revenue"dataKey={(entry) => entry.revenue - entry.expenses}responsiveResponsiveContainerwidthheightLineChartBarChartAreaChartPieChartScatterChartComposedChartRadarChartRadialBarChartXAxisYAxisCartesianGridTooltipLegendLineBarAreaPie<LineChart data={data}>
<XAxis dataKey="name" />
<YAxis />
<CartesianGrid strokeDasharray="3 3" />
<Tooltip />
<Legend />
<Line type="monotone" dataKey="value" stroke="#8884d8" strokeWidth={2} dot={{ r: 4 }} />
</LineChart>typestrokestrokeWidthdotfalseactiveDotconnectNulls<AreaChart data={data}>
<defs>
<linearGradient id="colorValue" x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor="#8884d8" stopOpacity={0.8}/>
<stop offset="95%" stopColor="#8884d8" stopOpacity={0}/>
</linearGradient>
</defs>
<XAxis dataKey="name" />
<YAxis />
<CartesianGrid strokeDasharray="3 3" />
<Tooltip />
<Area type="monotone" dataKey="value" stroke="#8884d8" fillOpacity={1} fill="url(#colorValue)" />
</AreaChart><Area type="monotone" dataKey="sales" stackId="1" stroke="#8884d8" fill="#8884d8" />
<Area type="monotone" dataKey="profit" stackId="1" stroke="#82ca9d" fill="#82ca9d" /><BarChart data={data}>
<XAxis dataKey="name" />
<YAxis />
<CartesianGrid strokeDasharray="3 3" />
<Tooltip />
<Legend />
<Bar dataKey="sales" fill="#8884d8" radius={[4, 4, 0, 0]} />
<Bar dataKey="profit" fill="#82ca9d" radius={[4, 4, 0, 0]} />
</BarChart>fillradiusbarSizestackIdshape<Bar dataKey="sales" stackId="a" fill="#8884d8" />
<Bar dataKey="profit" stackId="a" fill="#82ca9d" />BarStackimport { BarStack } from 'recharts';
<BarChart data={data}>
<BarStack stackId="a" radius={[4, 4, 0, 0]}>
<Bar dataKey="sales" fill="#8884d8" />
<Bar dataKey="profit" fill="#82ca9d" />
</BarStack>
</BarChart>const COLORS = ['#0088FE', '#00C49F', '#FFBB28', '#FF8042'];
<PieChart>
<Pie
data={data}
dataKey="value"
nameKey="name"
cx="50%"
cy="50%"
innerRadius={60}
outerRadius={80}
paddingAngle={5}
shape={(props) => <Sector {...props} fill={COLORS[props.index % COLORS.length]} />}
/>
<Tooltip />
<Legend />
</PieChart>innerRadiusouterRadiuspaddingAnglestartAngleendAnglelabelshapeCell<ScatterChart>
<XAxis type="number" dataKey="x" name="X Axis" />
<YAxis type="number" dataKey="y" name="Y Axis" />
<CartesianGrid />
<Tooltip cursor={{ strokeDasharray: '3 3' }} />
<Scatter name="Series A" data={data} fill="#8884d8" />
</ScatterChart><ComposedChart data={data}>
<XAxis dataKey="name" />
<YAxis />
<CartesianGrid stroke="#f5f5f5" />
<Tooltip />
<Legend />
<Area type="monotone" dataKey="total" fill="#8884d8" stroke="#8884d8" />
<Bar dataKey="sales" barSize={20} fill="#413ea0" />
<Line type="monotone" dataKey="profit" stroke="#ff7300" />
</ComposedChart>responsiveresponsive<LineChart data={data} width="100%" height={300} responsive>
{/* chart components */}
</LineChart>style<LineChart data={data} responsive style={{ maxWidth: 800, width: '100%', aspectRatio: '16/9' }}>
{/* chart components */}
</LineChart>ResponsiveContainerResponsiveContainer<ResponsiveContainer width="100%" height={300}>
<LineChart data={data}>
{/* chart components */}
</LineChart>
</ResponsiveContainer>ResponsiveContainerwidthheight<LineChart data={data} width={600} height={300}>
{/* chart components */}
</LineChart><XAxis
dataKey="name" // property to display
type="category" // "category" or "number"
domain={[0, 'dataMax']} // axis range
tick={{ fill: '#666' }} // tick styling
tickFormatter={(value) => `$${value}`} // format labels
angle={-45} // rotate labels
textAnchor="end" // text alignment
height={60} // extra space for labels
/>// Fixed range
<YAxis domain={[0, 100]} />
// Auto with padding
<YAxis domain={[0, 'auto']} />
// Data-based with overflow allowed
<YAxis domain={[0, 'dataMax + 100']} allowDataOverflow />
// Logarithmic scale
<YAxis type="number" scale="log" domain={['auto', 'auto']} />const CustomTooltip = ({ active, payload, label }) => {
if (active && payload && payload.length) {
return (
<div className="custom-tooltip">
<p className="label">{`${label}`}</p>
<p className="intro">{`Sales: ${payload[0].value}`}</p>
<p className="desc">Additional info...</p>
</div>
);
}
return null;
};
<Tooltip content={<CustomTooltip />} />const CustomLegend = ({ payload }) => (
<ul>
{payload.map((entry, index) => (
<li key={`item-${index}`} style={{ color: entry.color }}>
{entry.value}
</li>
))}
</ul>
);
<Legend content={<CustomLegend />} />const CustomBar = (props) => {
const { x, y, width, height, fill } = props;
return <path d={`M${x},${y} ...`} fill={fill} />;
};
<Bar shape={<CustomBar />} dataKey="sales" />
// OR
<Bar shape={(props) => <CustomBar {...props} />} dataKey="sales" /><Line
dataKey="sales"
label={{ position: 'top', fill: '#666', fontSize: 12 }}
/>
// Custom label component
<Line
dataKey="sales"
label={<CustomLabel />}
/><LineChart style={{ backgroundColor: '#f5f5f5' }}><XAxis
axisLine={{ stroke: '#666' }}
tickLine={{ stroke: '#666' }}
tick={{ fill: '#666', fontSize: 12 }}
/><CartesianGrid strokeDasharray="3 3" stroke="#e0e0e0" />TooltipactiveIndexdefaultIndexactivetrigger"hover""click"content() => nullcursorfalse{/* Click-based interaction with hidden tooltip text */}
<Tooltip trigger="click" content={() => null} cursor={false} />
{/* Default highlighted item on render */}
<Tooltip defaultIndex={2} /><LineChart onClick={(e) => console.log(e)}>
<Bar
dataKey="sales"
onClick={(data, index) => console.log('Bar clicked:', data)}
/>
</LineChart>syncId<LineChart data={data1} syncId="anyId">
{/* components */}
</LineChart>
<LineChart data={data2} syncId="anyId">
{/* components - tooltips synchronize */}
</LineChart><LineChart data={data}>
{/* other components */}
<Brush dataKey="name" height={30} stroke="#8884d8" />
</LineChart>useMemouseCallback// BAD - new function on every render
<Line dataKey={(entry) => entry.sales * 2} />
// GOOD - stable reference
const dataKey = useCallback((entry) => entry.sales * 2, []);
<Line dataKey={dataKey} />const MemoizedChart = React.memo(({ data }) => (
<LineChart data={data}>
{/* components */}
</LineChart>
));const Chart = () => {
const [hoveredData, setHoveredData] = useState(null);
return (
<LineChart>
{/* Static components */}
<Line dataKey="sales" />
{/* Dynamic overlay */}
<ReferenceLine x={hoveredData?.x} stroke="red" />
</LineChart>
);
};import { useDebouncedCallback } from 'use-debounce';
const handleMouseMove = useDebouncedCallback((e) => {
setPosition(e.activeLabel);
}, 10);
<LineChart onMouseMove={handleMouseMove}>// Bin data before rendering
const binnedData = useMemo(() => {
return d3.bin().value(d => d.x)(rawData);
}, [rawData]);<LineChart accessibilityLayer={true}>
<Line dataKey="sales" name="Monthly Sales" />
</LineChart><LineChart role="img" aria-label="Sales chart showing monthly revenue"><LineChart data={data}>
<XAxis dataKey="month" />
<YAxis />
<Tooltip />
<Legend />
<Line type="monotone" dataKey="productA" name="Product A" stroke="#8884d8" />
<Line type="monotone" dataKey="productB" name="Product B" stroke="#82ca9d" />
<Line type="monotone" dataKey="productC" name="Product C" stroke="#ffc658" />
</LineChart><BarChart layout="vertical" data={data}>
<XAxis type="number" />
<YAxis type="category" dataKey="name" />
<Bar dataKey="value" />
</BarChart>const COLORS = ['#0088FE', '#00C49F', '#FFBB28', '#FF8042'];
<PieChart>
<Pie
data={data}
innerRadius={60}
outerRadius={80}
paddingAngle={5}
dataKey="value"
shape={(props) => <Sector {...props} fill={COLORS[props.index % COLORS.length]} />}
/>
</PieChart>Note:component is deprecated and will be removed in Recharts 4.0. Use theCellprop onshape,Bar,Pie, etc. instead.Scatter
<LineChart data={data}>
{/* ... */}
<ReferenceLine y={5000} label="Target" stroke="red" strokeDasharray="3 3" />
<ReferenceArea x1="Jan" x2="Mar" fill="#8884d8" fillOpacity={0.1} />
</LineChart><ScatterChart>
<Scatter data={data}>
<ErrorBar dataKey="errorX" width={4} strokeWidth={2} />
<ErrorBar dataKey="errorY" width={4} strokeWidth={2} direction="y" />
</Scatter>
</ScatterChart>const SalesChart = () => {
const [timeRange, setTimeRange] = useState('month');
const data = useSelector(state => selectSalesData(state, timeRange));
return (
<ResponsiveContainer>
<LineChart data={data}>
{/* components */}
</LineChart>
</ResponsiveContainer>
);
};const RealtimeChart = () => {
const [data, setData] = useState([]);
useEffect(() => {
const interval = setInterval(() => {
setData(prev => [...prev.slice(-20), newDataPoint]);
}, 1000);
return () => clearInterval(interval);
}, []);
return (
<LineChart data={data}>
<XAxis dataKey="time" />
<YAxis domain={['auto', 'auto']} />
<Line type="monotone" dataKey="value" isAnimationActive={false} />
</LineChart>
);
};zIndex<Line dataKey="sales" zIndex={10} /> // Render on topzIndexZIndexLayerimport { ZIndexLayer } from 'recharts';
<ZIndexLayer zIndex={5}>
<CustomAnnotation />
</ZIndexLayer>x="March"y=5000ReferenceLineReferenceDotReferenceAreausePlotArea()useOffset()useChartWidth()getRelativeCoordinate(event, element)useXAxisScale()useYAxisScale()useXAxisInverseScale()useYAxisInverseScale()ResponsiveContainer<XAxis angle={-45} textAnchor="end" height={80} /><XAxis interval={0} /><Line isAnimationActive={false} /><Line animationDuration={500} />