Design System
Patterns & Recipes

How do I build a chart?

LineChart and AreaChartWithThreshold — dependency-free SVG, by design.

Prescribed: ui-kit's LineChart and AreaChartWithThreshold. There is deliberately no third-party charting library here — not Recharts, not visx, not Chart.js. Both components are hand-rolled, dependency-free SVG, built the same way: scales computed from the data extents, --accent/--info/--success/--warning token-driven series colours (so they re-theme correctly under data-brand), and the same built-in isLoading/error/onRetry states as everything else in this catalog. If a future need genuinely outgrows what these two can do, that's a real decision to make explicitly — not something to route around by quietly npm-installing a chart library into one app.

Trend lines: LineChart

One or more series, each a plain array of { x, y } points. x can be numeric (a real linear axis) or a category label (month names, below) — the component figures out which from the data.

Bookings by month
0k20k40k60k80kJanFebMarAprMay
  • This year
  • Last year

A single series against a target: AreaChartWithThreshold

The same idea, filled under its line, plus a horizontal dashed threshold line (e.g. a break-even point) that's always kept in view regardless of the data's own range.

Simulated sellout curve
020406080JanFebMarAprMayBreak-even

Do / Don't

  • Do pass yFormat/xFormat to render units ($, %, k) instead of hand-formatting the data before it reaches the chart — the axis labels are the only thing these touch.
  • Do use isLoading/error/onRetry for chart data backed by a real fetch, same as any other data-driven component in this catalog.
  • Don't add a charting library dependency to reach for a chart type these two don't cover — raise it as a design-system decision first; a one-off dependency in a single app is exactly the kind of drift this catalog exists to prevent.

On this page