> ## 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.

# Custom components

> Extend Recharts with custom shapes, labels, and visualizations

Recharts is highly customizable. You can create custom components to extend functionality or achieve unique designs.

## Custom components in Recharts 3

<Note>
  **The `Customized` wrapper is deprecated**

  Starting from Recharts 3.x, you can render custom components directly without the `Customized` wrapper. The wrapper will be removed in version 4.0.
</Note>

### Render custom components directly

In Recharts 3.x and later, add custom elements anywhere in your chart:

```jsx theme={null}
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:

```jsx theme={null}
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:

```jsx theme={null}
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:

```jsx theme={null}
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:

```jsx theme={null}
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](/guides/tooltips-and-legends) guide for detailed tooltip customization.

## Custom legends

See the [Tooltips and legends](/guides/tooltips-and-legends) guide for detailed legend customization.

## Accessing chart context

Custom components can access chart data and layout using hooks.

### Access chart dimensions

```jsx theme={null}
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:

```jsx theme={null}
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:

```jsx theme={null}
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

```jsx theme={null}
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

```jsx theme={null}
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

```jsx theme={null}
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

```jsx theme={null}
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

```jsx theme={null}
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

```jsx theme={null}
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

<Tip>
  **Use SVG primitives**

  Custom components should return SVG elements (`<g>`, `<rect>`, `<circle>`, `<text>`, etc.), not HTML elements.
</Tip>

<Warning>
  **Avoid complex calculations in render**

  If your custom component does heavy calculations, memoize the results:

  ```jsx theme={null}
  import { useMemo } from 'react';

  function HeavyCustomComponent({ data }) {
    const processedData = useMemo(() => {
      // Expensive calculation
      return data.map(/* ... */);
    }, [data]);
    
    return <g>{/* render with processedData */}</g>;
  }
  ```
</Warning>

<Note>
  **Coordinate systems**

  Remember that SVG coordinates start at the top-left (0, 0). Positive Y goes down, not up.
</Note>

## Migration from Recharts 2

If upgrading from Recharts 2.x:

```jsx theme={null}
{/* ❌ Recharts 2.x */}
<Customized component={<MyCustomComponent />} />

{/* ✅ Recharts 3.x */}
<MyCustomComponent />
```

**Source:** `https://github.com/recharts/recharts/blob/main/src/component/Customized.tsx:23-27`
