"use client"; import { motion } from "motion/react"; import { ChartFrame } from "./chart-frame"; import { linearScale, niceTicks, linePath, smoothPath, catColor, type Point } from "@/lib/chart-utils"; export type LineSeries = { label: string; data: Point[] }; type LineChartProps = { series: LineSeries[]; /** Category labels along x (aligned to x = 0..n-1). */ xLabels?: string[]; smooth?: boolean; yMin?: number; yMax?: number; width?: number; height?: number; className?: string; }; const M = { top: 16, right: 18, bottom: 34, left: 44 }; /** * LineChart — multi-series line. Each line draws via `pathLength` 0→1 (staggered * by series), points fade in once the line lands. Colors from `--cat-*`. */ export function LineChart({ series, xLabels, smooth = false, yMin, yMax, width = 640, height = 380, className, }: LineChartProps) { const all = series.flatMap((s) => s.data); const xs = all.map((p) => p.x); const ys = all.map((p) => p.y); const xDomain: [number, number] = [Math.min(...xs), Math.max(...xs)]; const yDomain: [number, number] = [yMin ?? Math.min(0, ...ys), yMax ?? Math.max(...ys)]; const sx = linearScale(xDomain, [M.left, width - M.right]); const sy = linearScale(yDomain, [height - M.bottom, M.top]); const ticks = niceTicks(yDomain[0], yDomain[1], 4); return ( {({ inView }) => ( <> {/* y gridlines + labels */} {ticks.map((t) => ( {t} ))} {/* x labels */} {xLabels?.map((lab, i) => ( {lab} ))} {/* lines */} {series.map((s, si) => { const pts = s.data.map((p) => ({ x: sx(p.x), y: sy(p.y) })); const d = smooth ? smoothPath(pts) : linePath(pts); const color = catColor(si); return ( {pts.map((p, i) => ( ))} ); })} )} ); }