Print Desk

The Atom design system, rendered live from its own tokens and components — it cannot drift from what ships.

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.

chartdatavizanalyticstrendbarhistogramsparkline

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

PropTypeDescription
TrendChart: labels / series / formatValue requiredstring[] / {id,label,tone:'ink'|'context',values}[] / (n)=>stringMax 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 requiredstring / 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 requirednumber[]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.