Skip to content

No.306 · Analytics· New

Donut Chart

Parts of a whole as a ring with a hairline between parts. Point at a part, or its row in the legend, and it steps out of the ring while the middle shows its value and share; otherwise the middle counts up to the total as the ring draws in.

The prompt

Copy this text

Automatic copying is unavailable. Copy the selected text using your device’s copy command.

Written for the variant you picked above: Light

Build a donut chart card in SVG with no chart library: 'Marketing spend by channel, Q3' with five parts (Search, Social, Email, Events, Partners) in OMR. Card: the chart surface with a 1px hairline ring and 16px corners, the title at 16px semibold. Beside the ring (wrapping under it on narrow screens), a legend list: each row is a button with a 10px rounded swatch, the name in secondary ink, the value in semibold tabular ink and the share in muted tabular figures, right-aligned. Ring: 220px, outer radius 104 and inner 70, angles from 12 o'clock clockwise, a 0.022-radian gap between parts plus a 1px surface stroke, parts in the fixed categorical order. On first view a mask circle's dash offset sweeps the ring in clockwise over 1s while the middle counts up to the total (ease-out cubic). The middle shows 'Total spend', the total in 24px semibold tabular figures and '5 channels'. Pointing at a part, or hovering or focusing its legend row: the part translates 7px outward along its middle angle (0.3s), the others fade to 35%, the row gets a soft wash, and the middle shows that part's name, value and '38.9% of total spend'. A visually hidden table lists every part, value and share, and the total. Selected variant — Light (light): Palette for this theme (Light): --dnut-focus #2a78d6; --dnut-ink #0b0b0b; --dnut-ink-2 #52514e; --dnut-muted #898781; --dnut-ring rgb(11 11 11 / 0.1); --dnut-s1 #2a78d6; --dnut-s2 #eb6834; --dnut-s3 #1baf7a; --dnut-s4 #eda100; --dnut-s5 #e87ba4; --dnut-surface #fcfcfb; --dnut-wash rgb(11 11 11 / 0.04). Treat these as the root colour tokens, one value per role, and name them to suit your code. Select it with the theme option set to "light". Keep every dimension, spacing value, state and motion from the brief unchanged, and keep text at 4.5:1 contrast or better on these surfaces. This selection takes precedence over references to other themes or options in the general brief. Implement this selected appearance; do not add a variant picker or alternative appearances unless requested. Implementation requirements: Use React and TypeScript. Keep the component self-contained, with uniquely scoped CSS and no animation libraries. Include required imports, styles and font setup in the result. Interaction: Hover a part or a legend row, or Tab through the legend rows, to read each part in the middle. Motion: A 1s clockwise draw-in with the total counting up, and a 0.3s step-out on the active part. Reduced motion shows the finished ring and total at once and keeps only the fades. Accessibility: The legend rows are buttons whose names give the value and share, and a hidden table carries the same numbers, so no part is identified by colour alone. The SVG is decorative. Responsive behavior: The ring keeps its size; the legend sits beside it on wide screens and below it on narrow ones. Touch: Tapping a legend row or a part shows it in the middle. Preserve keyboard access, visible focus and reduced-motion behavior. Keep fictional demo data and simulated service calls in a separate usage example; expose callbacks for real actions and recover from rejected requests. Keep usage-example links inside the demo: use local buttons or prevent navigation. Demonstration links must not navigate to Vitrine routes or open other pages; preserve real URL support in the reusable component itself. Verify the result at narrow and wide viewport sizes, with keyboard input and reduced motion enabled.

Notes

Interaction
Hover a part or a legend row, or Tab through the legend rows, to read each part in the middle.
Motion
A 1s clockwise draw-in with the total counting up, and a 0.3s step-out on the active part. Reduced motion shows the finished ring and total at once and keeps only the fades.
Accessibility
The legend rows are buttons whose names give the value and share, and a hidden table carries the same numbers, so no part is identified by colour alone. The SVG is decorative.
Responsive
The ring keeps its size; the legend sits beside it on wide screens and below it on narrow ones.
On touch
Tapping a legend row or a part shows it in the middle.

Featured

402 components