Skip to main content

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>

Custom tooltips

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