Charts
Four types, each ONE component configured by props — not a family of near
duplicates to choose between. registry/components/brand/charts.tsx, built on
Recharts through the shadcn chart.tsx primitive, both ported from the clients
portal rather than written fresh.
| Component | For | The switches |
|---|---|---|
Trend | A value over time | area, reference, legend, series[] |
Bars | A value across categories | stacked, legend, series[] |
Share | Parts of one whole | donut |
Ranking | Which is biggest, and by how much | max, slot, onSelect, muted per row |
Two shapes of input, and the difference is not an accident
Trend and Bars take data + x + series[] — a dataset, plus which
field is the axis and which fields to plot. That is Recharts' own shape, and it
is right when one row holds several series.
Ranking takes rows of { key, label, value } — rows already resolved,
because a ranking has exactly one value per row and nothing to select from it.
The prop name is the tell: data is "here is a dataset, plot these fields";
rows is "here are the rows". Renaming one to match the other would hide a real
difference in what the component needs.
Ranking is not a Recharts chart at all. Horizontal bars are divs with a
width — the same call the sparkline makes. Mounting a chart library to lay out
five rows costs a layout pass and an SVG for something CSS does exactly, and it
would lose the thing that makes a ranking useful: the rows are real DOM, so they
take a click, a hover and a link.
Five fixed hues, and a chart does NOT follow the brand
--chart-1 … --chart-5 are five hues chosen to be told apart, one set per
theme. They were derived from the accent and the semantics until 2026-08-20, and
that was wrong twice over:
- It broke in the parent brand.
iq's accent ink and--positiveare both#036B4E, so a two-series chart drew both series in ONE colour. Measured on the deployed site: two lines, one unique stroke. - A categorical series is not a state. Series 2 does not mean "good", it means "the second thing". Borrowing the semantic palette fuses two vocabularies, so a reader who has learned that red is a failure meets a red that means "Solar".
So a chart's colours are the same in all three brands, for the same reason the map's scale is. Every hue clears 3:1 against both surfaces in its theme — the floor for a graphical object that carries meaning, and the reason the light and dark sets are different values rather than the same ones.
If a series genuinely IS a state — covered vs gap — use the band scale and say so, rather than hoping series 2 lands on green.
Five series is the cap, and it is a hard one (SERIES_MAX). The eye cannot
hold six categorical colours and the palette has no sixth value to give. A sixth
series is a chart that should be a table.
Rules
- Axis labels and every figure are
font-mono+tabular-nums. Series names are.mono-caps. - A legend only when there is more than one series to name. One series with a legend is a label pretending to be a key.
areais for ONE series. Two filled areas fight, and the one behind loses.- A reference line is a target the reader is measuring against — not a mean, not a decoration.
- No shadow, no gradient fill, no 3D. The surface rules apply inside a chart.
- Every component takes its data as a prop and computes nothing about the domain: what a number MEANS is the caller's.
mutedon a ranking row recedes it without recolouring it — for rows outside the window in force. Colour is a state, never a rank: a row does not turn red for scoring badly.
When not to use one
A single figure is a Metric, not a chart. Twelve points in a line of text is a
Sparkline — hand-drawn SVG, no library. Recharts earns its place where the
axes, the ticks and the tooltip are the actual work.