Donut
Proportions chart. Hand-rolled SVG, no dependencies. Each segment is a same-radius circle with a stroke-dasharray arc and per-segment rotation. Set thickness to 50 for a pie chart. Pair with the Donut Legend list for a side-by-side breakdown.
a11y (built in): the SVG renders as one role="img" node whose aria-label is a generated summary of the whole series (Donut chart of 100: Mobile: 60, Desktop: 32, Tablet: 8, or Donut chart (no data) when empty), so the chart is never a silent graphic; each arc additionally carries a <title> for the native hover tooltip. The .lb-donut__center slot survives every re-render as ordinary DOM text, so the headline number is read as text rather than baked into the drawing.
Usage: <div data-lb-donut> with a <script type="application/json"> child holding { data, colors, thickness, gap }. data is an array of { label, value }.
Default
Three segments, default thickness, default colors from the data palette.
With center value
Add a .lb-donut__center child to the donut for the headline number — typical for goal-vs-target or percent-complete charts.
Thickness — thin ring → pie
The thickness config (0–50, in viewBox units) controls the donut hole. 50 closes the hole entirely (pie chart).
With legend
Compose the donut with a .lb-donut-legend list. Segments take --lb-data-1…--lb-data-8 in data order unless the config passes a colors array, so give each swatch the matching var(--lb-data-N) — as the demo below does.
- Acquisition 42%
- Retention 28%
- Expansion 20%
- Other 10%
In a Card — quota widget
The donut + center value pattern, wrapped in a Card with a label and caption.
- Used 42.8 GB
- Free 57.2 GB