Docs Components
Charts (TrendChart / BarList / Histogram / Sparkline / ChartCard)experimental
Charts drawn like newsprint: the data series in ink, the comparison period in a lighter tone, and at most one red mark for the point that matters. Never a rainbow of lines — two series maximum, and every chart offers a table view for anyone who wants exact numbers.
Color contract
Four semantic slots only: chart.ink (the series), chart.context (previous period / reference — sub-3:1 by declared design, relieved by labels and the table view), chart.accent (a single highlighted mark, hanko-stamp sized, never a series fill), chart.grid (follows border.hairline). Validated with the dataviz six-checks script: CVD separation ΔE 47 (paper) / 29 (sumi) and normal-vision ΔE 47/29 both clear their floors decisively; the lightness-band and chroma-floor checks fail BY DESIGN — they gate hue-identity palettes, and this palette is deliberately achromatic. The consequence is a hard cap: max two series per chart (ink + context), and anything needing more folds, facets, or becomes a table.
Mark specs
Lines 2px round join/cap; markers r=4 with a 2px surface ring; bars ≤16px with a 4px rounded data-end and square baseline; area wash 8% ink, and only when the ink series stands alone; gridlines 1px solid chart.grid, recessive. Values wear text tokens, never the series color.
Interaction
TrendChart ships a crosshair that snaps to the nearest X with one tooltip listing every series (value leads, label follows, line keys); the same readout follows keyboard focus (arrows, Home/End, Escape) and mirrors to a polite live region. BarList and Histogram direct-label every value, so they carry no tooltip. Tooltips enhance, never gate: every plotted value is also in ChartCard's table view.
API
| Prop | Type | Description |
|---|---|---|
TrendChart: labels / series / formatValue required | string[] / {id,label,tone:'ink'|'context',values}[] / (n)=>string | Max two series: one ink, one context. A legend renders only when both are present. |
BarList: items required | {label,value,hint?}[] | Nominal single series — same ink for every bar, value at the data end, tail folded to 'Other' past 8 rows. |
Histogram: buckets required | {label,count}[] | ≤10 buckets; every cap is labeled. |
ChartCard: title / caption / tableHeaders / tableRows required | string / string / string[] / (string|number)[][] | Frame with a Chart/Table SegmentedControl. The table view is mandatory — it is the relief channel for the sub-3:1 context series and for hover-only detail. |
Sparkline: values required | number[] | Decorative (aria-hidden) 12-point trend in context gray with the last point stamped in accent; only inside StatCard, whose value and delta text carry the information. |
Guidelines
- must-notNever introduce a third series hue. More than ink + context means small multiples, a fold to 'Other', or a table.
- mustStatus colors never appear in charts as series; when a measure means good/bad it reads through status tokens in text (StatCard delta), not through mark color.
- mustOne axis per chart — never a dual-axis plot; two measures of different scale get two charts.
- mustFilters (date range) sit in one row above the charts and scope everything below them.