"use client"; import { motion } from "motion/react"; import { ChartFrame } from "./chart-frame"; import { formatNumber } from "@/lib/format"; export type FunnelStage = { label: string; value: number }; type FunnelChartProps = { data: FunnelStage[]; width?: number; height?: number; className?: string; }; /** FunnelChart — trapezoid stages clip/scaleX open from the center axis, cascading top→bottom. */ export function FunnelChart({ data, width = 560, height = 380, className }: FunnelChartProps) { const max = Math.max(...data.map((d) => d.value), 1); const cx = width / 2; const top = 16; const gap = 8; const stageH = (height - top * 2 - gap * (data.length - 1)) / data.length; const halfW = (v: number) => (v / max) * (width / 2 - 24); return ( {({ inView, reduce }) => ( <> {data.map((d, i) => { const y = top + i * (stageH + gap); const wTop = halfW(d.value); const next = data[i + 1]; const wBot = halfW(next ? next.value : d.value * 0.92); const path = `M${cx - wTop},${y} L${cx + wTop},${y} L${cx + wBot},${y + stageH} L${cx - wBot},${y + stageH} Z`; const shade = 0.85 - i * (0.5 / data.length); return ( {d.label} · {formatNumber(d.value)} ); })} )} ); }