Heartwood Health · How to Build

04 · Arc Donut.

← components.html
all how-tos
04
Arc Donut

Part-to-whole · ring with legend

Use sparingly. A donut earns its space when 3–6 categories sum to a meaningful 100% and one segment dominates.

When to use

Patient origin by county, revenue by service line, traffic by source. 3–6 categories. With more than that, segments shrink into illegibility — switch to a horizontal bar. With only 2, use a single inline stat ("54% from Eagle County").

How it animates

Each arc is a <circle> with stroke-dasharray set to the segment length. Initial dashoffset hides the stroke; transitioning to final = circ − segLen reveals it. Each segment's <g> wrapper is rotated by the cumulative angle so segments stack correctly. Stagger 200ms between arcs.

Data shape
patientOrigin: {
  categories: [
    { label: 'Eagle County',  value: 54,
      color: 'var(--primary)' },
    { label: 'Summit County', value: 28,
      color: 'var(--tertiary)' },
    // values may be counts OR %, chart normalizes
  ],
}
Build pattern
const r = 40, circ = 2 * Math.PI * r;
let cumulative = 0;
data.forEach((c, i) => {
  const segLen = (c.value / total) * circ;
  g.setAttribute('transform',
    `rotate(${(cumulative/circ)*360} 50 50)`);
  seg.setAttribute('stroke-dasharray',
    `${segLen} ${circ - segLen}`);
  cumulative += segLen;
});