Documentation Index
Fetch the complete documentation index at: https://mintlify.com/recharts/recharts/llms.txt
Use this file to discover all available pages before exploring further.
Recharts is highly customizable. You can create custom components to extend functionality or achieve unique designs.
Custom components in Recharts 3
The Customized wrapper is deprecatedStarting from Recharts 3.x, you can render custom components directly without the Customized wrapper. The wrapper will be removed in version 4.0.
Render custom components directly
In Recharts 3.x and later, add custom elements anywhere in your chart:
function MyCustomComponent() {
return (
<g>
<rect x={100} y={100} width={50} height={50} fill="red" />
<text x={125} y={125} textAnchor="middle" fill="white">
Custom
</text>
</g>
);
}
function ChartWithCustom() {
return (
<LineChart width={600} height={300} data={data}>
<XAxis dataKey="month" />
<YAxis />
<Line dataKey="value" stroke="#8884d8" />
{/* No wrapper needed! */}
<MyCustomComponent />
</LineChart>
);
}
Source: https://github.com/recharts/recharts/blob/main/src/component/Customized.tsx:22-28
Custom shapes
Custom dots on lines
Replace default dots with custom shapes:
const CustomDot = (props) => {
const { cx, cy, value } = props;
if (value > 500) {
return (
<circle cx={cx} cy={cy} r={6} fill="red" stroke="white" strokeWidth={2} />
);
}
return (
<circle cx={cx} cy={cy} r={4} fill="#8884d8" />
);
};
<Line
dataKey="value"
stroke="#8884d8"
dot={<CustomDot />}
/>
Dot component receives:
cx, cy: Center coordinates
r: Radius
fill, stroke: Colors
value: Data value
payload: Complete data point
index: Point index
Custom bar shapes
Create custom shapes for bars:
const CustomBar = (props) => {
const { x, y, width, height, fill } = props;
return (
<g>
<rect
x={x}
y={y}
width={width}
height={height}
fill={fill}
rx={8}
ry={8}
/>
{/* Add a gradient */}
<rect
x={x}
y={y}
width={width}
height={height / 2}
fill="url(#barGradient)"
rx={8}
ry={8}
/>
</g>
);
};
<BarChart width={600} height={300} data={data}>
<defs>
<linearGradient id="barGradient" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stopColor="white" stopOpacity={0.3} />
<stop offset="100%" stopColor="white" stopOpacity={0} />
</linearGradient>
</defs>
<Bar dataKey="value" shape={<CustomBar />} fill="#8884d8" />
</BarChart>
Custom labels
Custom axis tick labels
Create custom tick components:
const CustomTick = (props) => {
const { x, y, payload } = props;
return (
<g transform={`translate(${x},${y})`}>
<text
x={0}
y={0}
dy={16}
textAnchor="middle"
fill="#666"
fontSize={12}
fontWeight="bold"
>
{payload.value}
</text>
</g>
);
};
<XAxis dataKey="month" tick={<CustomTick />} />
Custom label list
Add labels to data points:
const CustomLabel = (props) => {
const { x, y, value } = props;
return (
<text
x={x}
y={y}
dy={-10}
fill="#666"
fontSize={12}
textAnchor="middle"
>
${value}
</text>
);
};
import { LabelList } from 'recharts';
<Bar dataKey="value" fill="#8884d8">
<LabelList content={<CustomLabel />} />
</Bar>
See the Tooltips and legends guide for detailed tooltip customization.
Custom legends
See the Tooltips and legends guide for detailed legend customization.
Accessing chart context
Custom components can access chart data and layout using hooks.
Access chart dimensions
import { useChartWidth, useChartHeight } from 'recharts';
function CustomOverlay() {
const width = useChartWidth();
const height = useChartHeight();
return (
<rect
x={0}
y={0}
width={width}
height={height}
fill="rgba(0, 0, 0, 0.1)"
pointerEvents="none"
/>
);
}
<LineChart width={600} height={300} data={data}>
<CustomOverlay />
<Line dataKey="value" stroke="#8884d8" />
</LineChart>
Custom annotations
Threshold line
Draw a horizontal line at a specific value:
function ThresholdLine({ value, label }) {
return (
<g>
<ReferenceLine
y={value}
stroke="red"
strokeDasharray="3 3"
label={{ value: label, position: 'right' }}
/>
</g>
);
}
import { ReferenceLine } from 'recharts';
<LineChart width={600} height={300} data={data}>
<YAxis />
<Line dataKey="value" stroke="#8884d8" />
<ReferenceLine y={500} stroke="red" strokeDasharray="3 3" label="Target" />
</LineChart>
Reference area
Highlight a specific range:
import { ReferenceArea } from 'recharts';
<LineChart width={600} height={300} data={data}>
<XAxis dataKey="month" />
<YAxis />
<Line dataKey="value" stroke="#8884d8" />
<ReferenceArea
x1="Feb"
x2="Apr"
fill="#8884d8"
fillOpacity={0.1}
label="Q1 Performance"
/>
</LineChart>
Custom active shapes
Animated active dot
const CustomActiveDot = (props) => {
const { cx, cy } = props;
return (
<g>
{/* Outer ring */}
<circle
cx={cx}
cy={cy}
r={12}
fill="none"
stroke="#8884d8"
strokeWidth={2}
opacity={0.3}
/>
{/* Inner dot */}
<circle
cx={cx}
cy={cy}
r={6}
fill="#8884d8"
stroke="white"
strokeWidth={2}
/>
</g>
);
};
<Line
dataKey="value"
stroke="#8884d8"
activeDot={<CustomActiveDot />}
/>
Custom active bar
const CustomActiveBar = (props) => {
const { x, y, width, height, fill } = props;
return (
<rect
x={x - 2}
y={y - 2}
width={width + 4}
height={height + 4}
fill={fill}
stroke="#333"
strokeWidth={2}
rx={4}
/>
);
};
<Bar
dataKey="value"
fill="#8884d8"
activeBar={<CustomActiveBar />}
/>
SVG patterns and gradients
Gradient fills
function ChartWithGradient() {
return (
<AreaChart width={600} height={300} 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="month" />
<YAxis />
<Area
type="monotone"
dataKey="value"
stroke="#8884d8"
fill="url(#colorValue)"
/>
</AreaChart>
);
}
Pattern fills
function ChartWithPattern() {
return (
<BarChart width={600} height={300} data={data}>
<defs>
<pattern id="stripe" patternUnits="userSpaceOnUse" width={8} height={8} patternTransform="rotate(45)">
<line x1="0" y1="0" x2="0" y2="8" stroke="#8884d8" strokeWidth={4} />
</pattern>
</defs>
<XAxis dataKey="category" />
<YAxis />
<Bar dataKey="value" fill="url(#stripe)" />
</BarChart>
);
}
Custom chart backgrounds
function CustomBackground() {
return (
<g>
<rect x={0} y={0} width="100%" height="100%" fill="#f5f5f5" />
<line x1={0} y1="50%" x2="100%" y2="50%" stroke="#ddd" strokeWidth={1} />
</g>
);
}
<LineChart width={600} height={300} data={data}>
<CustomBackground />
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="month" />
<YAxis />
<Line dataKey="value" stroke="#8884d8" />
</LineChart>
Interactive custom components
Clickable annotations
function ClickableAnnotation({ x, y, label, onClick }) {
return (
<g
onClick={onClick}
style={{ cursor: 'pointer' }}
onMouseEnter={(e) => e.currentTarget.style.opacity = '0.7'}
onMouseLeave={(e) => e.currentTarget.style.opacity = '1'}
>
<circle cx={x} cy={y} r={20} fill="#8884d8" />
<text
x={x}
y={y}
textAnchor="middle"
fill="white"
fontSize={12}
dy={4}
>
{label}
</text>
</g>
);
}
function InteractiveChart() {
const handleAnnotationClick = () => {
alert('Annotation clicked!');
};
return (
<LineChart width={600} height={300} data={data}>
<XAxis dataKey="month" />
<YAxis />
<Line dataKey="value" stroke="#8884d8" />
<ClickableAnnotation
x={200}
y={100}
label="!"
onClick={handleAnnotationClick}
/>
</LineChart>
);
}
Best practices
Use SVG primitivesCustom components should return SVG elements (<g>, <rect>, <circle>, <text>, etc.), not HTML elements.
Avoid complex calculations in renderIf your custom component does heavy calculations, memoize the results:import { useMemo } from 'react';
function HeavyCustomComponent({ data }) {
const processedData = useMemo(() => {
// Expensive calculation
return data.map(/* ... */);
}, [data]);
return <g>{/* render with processedData */}</g>;
}
Coordinate systemsRemember that SVG coordinates start at the top-left (0, 0). Positive Y goes down, not up.
Migration from Recharts 2
If upgrading from Recharts 2.x:
{/* ❌ Recharts 2.x */}
<Customized component={<MyCustomComponent />} />
{/* ✅ Recharts 3.x */}
<MyCustomComponent />
Source: https://github.com/recharts/recharts/blob/main/src/component/Customized.tsx:23-27