import { CartesianGrid, Line, LineChart, ReferenceLine, ResponsiveContainer, Tooltip, XAxis, YAxis, } from 'recharts'; import type { TooltipProps } from 'recharts'; import { formatNumber } from './format'; export interface MetricPoint { /** Whatever the x axis is counting: checkpoint, step, arm name. */ x: string | number; y: number; } export interface MetricChartProps { data: MetricPoint[]; /** The rule the headline number is being compared against. */ baseline?: { value: number; label: string }; height: number; /** Off under `prefers-reduced-motion`; recharts animates on mount by default. */ animate: boolean; digits?: number; } /* * Every colour is an `hsl(var(--…))` string read from the token layer at paint * time, so the chart follows the theme toggle without a re-render and no hex * ever lands in this file. The series takes `--tab-underline`, which is the * one token that is the accent fill in dark and the accent INK in light — a * 2px line on the page ground is a state indicator, and the raw accent is * 1.47:1 against white. */ const SERIES = 'hsl(var(--tab-underline))'; const GRID = 'hsl(var(--border))'; const BASELINE = 'hsl(var(--border-strong))'; const TICK = 'hsl(var(--muted))'; /** * The chart, in its own module so `React.lazy` can hold recharts out of the * entry chunk. Nothing else in the shell may import this file directly — an * ordinary import here defeats the whole arrangement and the entry chunk grows * by ~100 kB without anyone noticing. */ export default function MetricChart({ data, baseline, height, animate, digits = 3, }: MetricChartProps) { return (
{String(label)}
{typeof value === 'number' ? formatNumber(value, digits) : '—'}