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.

The FunnelChart component visualizes progressive reduction of data through stages of a process. It’s commonly used for conversion rates, sales pipelines, and sequential workflows.

Basic funnel chart

import { FunnelChart, Funnel, Tooltip, LabelList } from 'recharts';

const data = [
  { name: 'Impressions', value: 100000, fill: '#8884d8' },
  { name: 'Clicks', value: 50000, fill: '#83a6ed' },
  { name: 'Add to Cart', value: 25000, fill: '#8dd1e1' },
  { name: 'Checkout', value: 12500, fill: '#82ca9d' },
  { name: 'Purchase', value: 5000, fill: '#a4de6c' },
];

function Example() {
  return (
    <FunnelChart width={500} height={400}>
      <Tooltip />
      <Funnel
        dataKey="value"
        data={data}
        isAnimationActive
      >
        <LabelList position="right" fill="#000" stroke="none" dataKey="name" />
      </Funnel>
    </FunnelChart>
  );
}

With labels inside

<FunnelChart width={500} height={400}>
  <Tooltip />
  <Funnel dataKey="value" data={data}>
    <LabelList position="inside" fill="#fff" stroke="none" />
  </Funnel>
</FunnelChart>

Custom colors

const COLORS = ['#0088FE', '#00C49F', '#FFBB28', '#FF8042', '#8884D8'];

const dataWithColors = [
  { name: 'Stage 1', value: 100 },
  { name: 'Stage 2', value: 80 },
  { name: 'Stage 3', value: 50 },
  { name: 'Stage 4', value: 30 },
  { name: 'Stage 5', value: 10 },
];

<FunnelChart width={500} height={400}>
  <Tooltip />
  <Funnel dataKey="value" data={dataWithColors}>
    {dataWithColors.map((entry, index) => (
      <Cell key={`cell-${index}`} fill={COLORS[index]} />
    ))}
    <LabelList position="right" fill="#000" stroke="none" dataKey="name" />
  </Funnel>
</FunnelChart>

Multiple funnels

const data1 = [
  { value: 100, fill: '#8884d8' },
  { value: 80, fill: '#83a6ed' },
  { value: 50, fill: '#8dd1e1' },
];

const data2 = [
  { value: 100, fill: '#82ca9d' },
  { value: 70, fill: '#a4de6c' },
  { value: 40, fill: '#d0ed57' },
];

<FunnelChart width={700} height={400}>
  <Tooltip />
  <Funnel dataKey="value" data={data1} x="10%" width="40%" />
  <Funnel dataKey="value" data={data2} x="55%" width="40%" />
</FunnelChart>

Custom shape with active state

import { Trapezoid } from 'recharts';
import { useState } from 'react';

function Example() {
  const [activeIndex, setActiveIndex] = useState(0);

  return (
    <FunnelChart width={500} height={400}>
      <Tooltip />
      <Funnel
        dataKey="value"
        data={data}
        activeIndex={activeIndex}
        activeShape={{
          fill: '#ff0000',
          stroke: '#000',
          strokeWidth: 2,
        }}
        onMouseEnter={(_, index) => setActiveIndex(index)}
      >
        <LabelList position="right" fill="#000" stroke="none" dataKey="name" />
      </Funnel>
    </FunnelChart>
  );
}

With conversion rate labels

const dataWithRate = [
  { name: 'Impressions', value: 100000 },
  { name: 'Clicks', value: 50000 },
  { name: 'Add to Cart', value: 25000 },
  { name: 'Purchase', value: 5000 },
];

const CustomLabel = (props) => {
  const { x, y, width, height, index } = props;
  if (index === 0) return null;
  
  const rate = ((dataWithRate[index].value / dataWithRate[index - 1].value) * 100).toFixed(1);
  
  return (
    <text
      x={x + width + 10}
      y={y + height / 2}
      fill="#666"
      textAnchor="start"
      dominantBaseline="middle"
    >
      {rate}%
    </text>
  );
};

<FunnelChart width={600} height={400}>
  <Tooltip />
  <Funnel dataKey="value" data={dataWithRate}>
    <LabelList content={<CustomLabel />} />
  </Funnel>
</FunnelChart>

Reversed funnel (pyramid)

const pyramidData = [
  { name: 'Base', value: 5000, fill: '#a4de6c' },
  { name: 'Level 2', value: 12500, fill: '#82ca9d' },
  { name: 'Level 3', value: 25000, fill: '#8dd1e1' },
  { name: 'Level 4', value: 50000, fill: '#83a6ed' },
  { name: 'Top', value: 100000, fill: '#8884d8' },
];

<FunnelChart width={500} height={400}>
  <Tooltip />
  <Funnel
    dataKey="value"
    data={pyramidData}
    isAnimationActive
  >
    <LabelList position="right" fill="#000" stroke="none" dataKey="name" />
  </Funnel>
</FunnelChart>

Animations

<FunnelChart width={500} height={400}>
  <Tooltip />
  <Funnel
    dataKey="value"
    data={data}
    isAnimationActive={true}
    animationBegin={0}
    animationDuration={800}
    animationEasing="ease-in-out"
  >
    <LabelList position="right" fill="#000" stroke="none" dataKey="name" />
  </Funnel>
</FunnelChart>

Custom trapezoid shape

<FunnelChart width={500} height={400}>
  <Tooltip />
  <Funnel
    dataKey="value"
    data={data}
    shape={(props) => {
      const { x, y, width, height, fill } = props;
      return (
        <g>
          <Trapezoid
            x={x}
            y={y}
            width={width}
            height={height}
            fill={fill}
            upperWidth={width}
            lowerWidth={width * 0.7}
          />
        </g>
      );
    }}
  />
</FunnelChart>

Event handlers

<FunnelChart width={500} height={400}>
  <Tooltip />
  <Funnel
    dataKey="value"
    data={data}
    onClick={(data, index) => console.log('Clicked:', data, index)}
    onMouseEnter={(data, index) => console.log('Mouse enter:', data, index)}
    onMouseLeave={() => console.log('Mouse leave')}
  >
    <LabelList position="right" fill="#000" stroke="none" dataKey="name" />
  </Funnel>
</FunnelChart>

Common pitfalls

  • Data order: Data should be ordered from largest to smallest value for a traditional funnel. Reverse the order for a pyramid chart.
  • Missing fill: Each data item should have a fill property, or you must provide colors via Cell components.
  • Label positioning: Use position="right" for labels outside the funnel, or position="inside" for labels within segments.
  • Width calculation: Funnel width is automatically calculated based on values. Segments with larger values are wider.
  • Tooltip event type: FunnelChart only supports 'item' tooltip event type.
  • Multiple funnels: When showing multiple funnels side by side, use the x and width props to position them correctly.