Funnel Chart

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

Installation

pnpm dlx shadcn@latest add @bklit/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.

import { FunnelChart } from "@bklitui/ui/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

PropTypeDefaultDescription
dataFunnelStage[]requiredArray of funnel stages
orientation"horizontal" | "vertical""horizontal"Layout direction
colorstring"var(--chart-1)"Default color for all segments
layersnumber3Number of concentric halo rings per segment
edges"curved" | "straight""curved"Edge style for segment shapes
gapnumber4Gap between segments in pixels
staggerDelaynumber0.12Stagger delay between segment animations (seconds)
showPercentagebooleantrueShow percentage badges
showValuesbooleantrueShow value labels
showLabelsbooleantrueShow stage name labels
formatPercentage(pct: number) => stringrounds to integerCustom percentage formatter
formatValue(value: number) => stringlocale stringCustom value formatter
labelLayout"spread" | "grouped""spread"How labels are arranged within each segment
labelOrientation"vertical" | "horizontal"autoStack direction for grouped labels
labelAlign"center" | "start" | "end""center"Alignment of grouped labels
hoveredIndexnumber | null-Controlled hover state (segment index)
onHoverChange(index: number | null) => void-Callback when hover state changes
gridboolean | GridConfigfalseBackground bands and grid lines
renderPattern(id: string, color: string) => ReactNode-Custom SVG pattern for the innermost ring
classNamestring-Additional CSS class
styleCSSProperties-Additional inline styles

FunnelStage

PropertyTypeDescription
labelstringStage name displayed below the segment
valuenumberNumeric value (first item is treated as 100%)
displayValuestring?Custom display string (overrides formatted value)
colorstring?Override the chart-level color for this segment
gradientFunnelGradientStop[]?Linear gradient for this segment

GridConfig

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

PropertyTypeDefaultDescription
bandsbooleantrueShow alternating background bands
bandColorstring"var(--color-muted)"Color of the background bands
linesbooleantrueShow grid lines between segments
lineColorstring"var(--chart-grid)"Color of the grid lines
lineOpacitynumber1Opacity of the grid lines
lineWidthnumber1Width of the grid lines in pixels

See the charts gallery for vertical layouts, per-segment colors, patterns, and legend sync.