Skip to content

Data visualisation

One palette, four renderers, and one standard for how a chart is built. @pepperui/charts 1.1.5 holds both; ECharts and Chart.js read them in the browser, the PPTX exporter reads the same values in Python, and the Figma chart recipes cite them. No colour and no geometry is written in the package’s source — npm test fails on one, and reads every value back out of tokens.css.

Every chart on this page is drawn from those numbers, part by part, in the same HTML and CSS the slide previews use. What you see here is what a chart in a deck, a dashboard or a Figma frame is supposed to look like.

Twelve rules. They were settled on rendered pairs — the same chart drawn both ways, side by side — rather than described, and they live in one file so no renderer can hold its own copy. Eleven of them are about a chart’s shape; the twelfth is the one place colour is a rule rather than a palette.

A column stands on a baseline
0255075100
42
58
51
74
88
JanFebMarAprMay

The baseline is chart/rest at 2 px, heavier than the 1 px grid, and it belongs to the category axis. The value axis draws no line of its own.

A line at every tick
0255075100
42
58
51
74
88
JanFebMarAprMay

The grid keeps a horizontal line at every tick, behind the bars — the values can be read off the plot as well as off the labels.

Rounded on top, square at the foot
0255075100
42
58
51
74
88
JanFebMarAprMay

4 px on the top corners only, and never wider than 96. A column rounded all round reads as a floating pill.

A stack rounds its top segment only
0255075100
JanFebMarAprMay

The joints stay square: a rounded joint draws a gap between two values that is not in the data.

Two series are a comparison
0255075100
JanFebMarAprMay

A chart with exactly TWO series is one thing measured against the rest of it, so the second series is chart/rest — the same grey the two-slice donut uses, not the accent’s second tint. Three series or more take the accent’s own tints as before.

A dot at every point
0255075100
JanFebMarAprMayJunJul

The spline is 4 px and every point carries a 9 px marker. A line with no markers hides where the data actually is.

Largest first, and the name lane is measured
United States
88
Germany
71
Brazil
54
India
39
Japan
22
0255075100

A ranked list reads top-down from the largest, and the lane for the row names is as wide as the longest name — nothing is reserved in advance.

The forecast band, and the line under it
0255075100
JanFebMarAprMayJunJulAugSep

The band is the series colour at 12 % under the value it belongs to; the series it is compared against runs beneath as a dashed chart/4 line, 3 px, 6 on 6 off, and each line ends in a marker.

A donut writes its share in the legend
MobuppsX — 38%i/RTB — 27%MAFO — 21%Echo AI — 14%

The ring stays clean — no text on it, no leader lines out of it. The cutout is 72 % and the segment borders are 3 px in chart/on-fill. The legend lane is measured from its own entries, so the last one is never cut.

A donut with two slices
Share — 63%Rest — 37%

Exactly two slices read as share-against-rest: the share keeps the accent’s chart/1 and the remainder is always chart/rest, never chart/2 — two accent hues would read as two categories.

A sparkline

The line and nothing else: no axis, no grid, no labels. It sits inside a card that already says what the number is.

All three are correct, and the system carries all three rather than choosing for you. Pick the one the screen needs: one flat colour when the bars are one thing measured over time, the accent’s own tints when the bars are being compared with each other, and multicolor when the chart is set to it by hand.

One flat colour
0255075100
42
58
51
74
88
JanFebMarAprMay

Every bar in the accent’s chart/1. This is what “a chart follows the accent” means, and it is the default in an accent mode.

The accent’s own tints
0255075100
42
58
51
74
88
JanFebMarAprMay

chart/1 to chart/5, cycling — for a comparison across the bars.

Multicolor
0255075100
42
58
51
74
88
JanFebMarAprMay

The mode’s chart/1 to chart/5 — red, yellow, blue, grey, then the second red its palette continues with. Multicolor is set by hand, a deck chooses it and the machine never does, and a chart in it cycles across the bars rather than painting them all red.

Five colours per accent mode, in order. Blue and red lead with the accent’s two hues and end in greys; yellow’s second series is grey, because a yellow tint vanishes on the card; multicolor cycles red, yellow, blue, then grey — so a chart never has to invent a colour.

Mode Series 1–5
data-accent="blue"
data-accent="red"
data-accent="yellow"
multicolor (8)

Hover a swatch to see the token it comes from. The multicolor mode is the only palette longer than five, and its series are the three accents in turn rather than one accent’s tints.

  • The two-slice donut. Drawn above: the share in series 1, the remainder in chart/rest. A donut that arrives unstyled is restyled to 70 with no border rather than shipping as a default pie.
  • The narrow-band floor. When every value in a series sits inside a narrow high band — a spread under 5 % of the maximum — the axis floor lifts to just below the band so the variation is visible; an explicit axis minimum always wins.
Canvas Size Weight
slide 15 400
web-desktop 12 500

The face is Poppins, sans-serif and a strong label is weight 600. Ink, grid, the rest slice and the label inside a fill are token roles, not chart settings.

Three of the open contrast questions are here — a data label written in white inside a yellow fill, a yellow two-slice donut whose share and remainder are 1.15 apart, and the dashed forecast line, which reads 1.68 : 1 on its own band. All three are on Accessibility; none of them fails the build.

Pepper UI v1.5.0

The Mobupps design system. 386 tokens, 88 components, 65 pages in the workshop — every page of this site generated from the repository, so nothing here is typed twice.