# Funnel Chart

> An animated funnel chart with multi-layer halo rings, hover interactions, and staggered entrance animations

Source: https://ui.cortexcn.dev/docs/charts/funnel-chart

## Installation

```bash
npx shadcn@latest add @cortexcn/funnel-chart
```

## Usage

The Funnel Chart is a standalone component that renders an animated funnel visualization. Each segment represents a stage in a pipeline, with the width (or height in vertical mode) proportional to the value.

```tsx
import { FunnelChart } from "@/components/charts";

const data = [
  { label: "Visitors", value: 12400, displayValue: "12.4k" },
  { label: "Leads", value: 6800, displayValue: "6.8k" },
  { label: "Qualified", value: 3200, displayValue: "3.2k" },
  { label: "Proposals", value: 1500, displayValue: "1.5k" },
  { label: "Closed", value: 620, displayValue: "620" },
];

export default function SalesFunnel() {
  return <FunnelChart data={data} color="var(--chart-1)" layers={3} />;
}
```

## Props

### FunnelChart

| Prop               | Type                                       | Default            | Description                                        |
| ------------------ | ------------------------------------------ | ------------------ | -------------------------------------------------- |
| `data`             | `FunnelStage[]`                            | required           | Array of funnel stages                             |
| `orientation`      | `"horizontal" \| "vertical"`               | `"horizontal"`     | Layout direction                                   |
| `color`            | `string`                                   | `"var(--chart-1)"` | Default color for all segments                     |
| `layers`           | `number`                                   | `3`                | Number of concentric halo rings per segment        |
| `edges`            | `"curved" \| "straight"`                   | `"curved"`         | Edge style for segment shapes                      |
| `gap`              | `number`                                   | `4`                | Gap between segments in pixels                     |
| `staggerDelay`     | `number`                                   | `0.12`             | Stagger delay between segment animations (seconds) |
| `showPercentage`   | `boolean`                                  | `true`             | Show percentage badges                             |
| `showValues`       | `boolean`                                  | `true`             | Show value labels                                  |
| `showLabels`       | `boolean`                                  | `true`             | Show stage name labels                             |
| `formatPercentage` | `(pct: number) => string`                  | rounds to integer  | Custom percentage formatter                        |
| `formatValue`      | `(value: number) => string`                | locale string      | Custom value formatter                             |
| `labelLayout`      | `"spread" \| "grouped"`                    | `"spread"`         | How labels are arranged within each segment        |
| `labelOrientation` | `"vertical" \| "horizontal"`               | auto               | Stack direction for grouped labels                 |
| `labelAlign`       | `"center" \| "start" \| "end"`             | `"center"`         | Alignment of grouped labels                        |
| `hoveredIndex`     | `number \| null`                           | -                  | Controlled hover state (segment index)             |
| `onHoverChange`    | `(index: number \| null) => void`          | -                  | Callback when hover state changes                  |
| `grid`             | `boolean \| GridConfig`                    | `false`            | Background bands and grid lines                    |
| `renderPattern`    | `(id: string, color: string) => ReactNode` | -                  | Custom SVG pattern for the innermost ring          |
| `className`        | `string`                                   | -                  | Additional CSS class                               |
| `style`            | `CSSProperties`                            | -                  | Additional inline styles                           |

### FunnelStage

| Property       | Type                    | Description                                       |
| -------------- | ----------------------- | ------------------------------------------------- |
| `label`        | `string`                | Stage name displayed below the segment            |
| `value`        | `number`                | Numeric value (first item is treated as 100%)     |
| `displayValue` | `string?`               | Custom display string (overrides formatted value) |
| `color`        | `string?`               | Override the chart-level color for this segment   |
| `gradient`     | `FunnelGradientStop[]?` | Linear gradient for this segment                  |

### GridConfig

When passing an object to `grid`, the following options are available:

| Property      | Type      | Default                | Description                       |
| ------------- | --------- | ---------------------- | --------------------------------- |
| `bands`       | `boolean` | `true`                 | Show alternating background bands |
| `bandColor`   | `string`  | `"var(--color-muted)"` | Color of the background bands     |
| `lines`       | `boolean` | `true`                 | Show grid lines between segments  |
| `lineColor`   | `string`  | `"var(--chart-grid)"`  | Color of the grid lines           |
| `lineOpacity` | `number`  | `1`                    | Opacity of the grid lines         |
| `lineWidth`   | `number`  | `1`                    | Width of the grid lines in pixels |

See the [charts gallery](https://ui.cortexcn.dev/charts/funnel-chart) for vertical layouts, per-segment colors, patterns, and legend sync.