Chart

Bar, line, area, donut and sparkline. Pure SVG, token-coloured, theme-aware, no dependencies.

v1.0.0·Updated Jul 11, 2026 · 15:00
Charts, drawn honestly

Five ways to show numbers: bar, line, area, donut and sparkline. Each is pure SVG with no dependency, coloured from the categorical --element tokens, so a chart follows the dark or light theme on the page like everything else. Hover for a tooltip, click a legend to toggle a series.

The five charts
Bar · grouped
Two series per category, side by side. Hover for a tooltip; click the legend to toggle a series.
Bar · stacked
Series stack into one bar per category.
Line · multi-series
Smooth-curved lines with data dots and a hover guide.
Area · gradient
A line with a gradient fill to the baseline.
Donut · proportions
Segments with a centre total and a value legend.
100
Enterprise4848%
Growth3232%
Starter2020%
Sparkline · inline trend
Tiny, axis-free trend for tables and cards. Colour follows direction.
SOL+4.7%
BTC−1.6%
Cash+12%
Kinds
ChartUse it for
BarVertical columns for comparing categories. Grouped puts series side by side; stacked adds them into one bar.
LineOne or more series over an ordered axis. Straight or smooth-curved, with data dots and a hover guide.
AreaA line with a gradient fill to the baseline, for a single trending magnitude.
DonutProportions of a whole, with a centre total and a value legend.
SparklineA tiny, axis-free trend for tables and cards; the colour follows the direction.
Props
PropTypeNotes
typebar | line | areaThe chart family for the cartesian <Chart>. Donut and Sparkline are separate exports.
categoriesstring[]The x-axis labels, one per data point.
series{ name, data: number[], color? }[]One entry per line or bar group; colours auto-assign from the --element palette.
stackedbooleanBars (or areas) add up into one column per category instead of grouping.
curvedbooleanSmooth the line/area with a Catmull-Rom spline.
grid / legendbooleanHorizontal gridlines, and a click-to-toggle series legend.
yFormat(v) => stringFormat the y-axis ticks and tooltip values, e.g. currency or units.
heightnumberPlot height in pixels; width is measured from the container.
Donut segments{ label, value, color? }[]Each slice; pass total to show the sum (or any node) in the centre.
Sparkline datanumber[]The trend values; add area for a gradient fill under the line.
Code
tsx
import { Chart, Donut, Sparkline } from "./ui/components/chart/chart";

<Chart
  type="line" curved
  categories={["Jan", "Feb", "Mar", "Apr"]}
  series={[
    { name: "Focus", data: [24, 31, 28, 40] },
    { name: "Distraction", data: [30, 22, 26, 18] },
  ]}
  yFormat={(v) => `${v}k`}
/>

<Donut total segments={[
  { label: "Enterprise", value: 48 },
  { label: "Growth", value: 32 },
  { label: "Starter", value: 20 },
]} />

<Sparkline data={[3, 5, 4, 6, 5, 8, 7, 9]} />