shadcn.io is not affiliated with official shadcn/ui
Two-Ring Donut Stats Block for Solid
A headcount donut with two rings: the departments' groups inside and their teams outside, each team sitting in its own group's arc, with a nested legend whose shares add up at every level.
Installation
Overview
A two-ring donut for Solid with Ark UI. A split: at the start, two concentric rings, the groups (Product, Customer) inside and their teams (Engineering, Design, Data, Sales, Support) outside, with the headcount rolling up once in the hole. Each team's arc sits outside its own group's arc, because both rings are cut from one running sum, so the outer arcs always end where the inner ones do. The arcs start at twelve o'clock and run clockwise in solid foreground weights (100, 65, 40, 20 and 10 percent) with a 2 px gap, and each group takes the weight of its first team, so the dark family is one group and the light family the other. At the end, past a divider that runs up to the page's top rule, a header ("141 people, 60% of them in Product") sits over a nested legend: every group with its teams, each with headcount and share. The shares are rounded in two steps (the groups share 100, then each group's teams share the group's own share), so every level adds up. On a phone the header comes first, then the rings, then the legend, separated by rules with + marks. It's built from Guides and SlidingNumber, with SVG circles for the rings.
FAQ
How do I change the groups and teams?
Edit GROUPS at the top of the file: each group is a label and its teams (a label and the people). The group's head count, every share, both rings, the legend and the header's headline are computed from it. Up to five teams have a weight in WEIGHTS; add weights to draw more.
How do the outer arcs line up with the inner ones?
Both rings are drawn with the same method (a circle with a dash pattern, turned to start at twelve o'clock) from the same running sum of head counts. A group's arc starts where the sum reaches its first team and ends where it reaches its last, and so do the teams' arcs, so the boundaries coincide. The gap is two units on each ring, so a ring with a smaller radius gets a slightly larger share of its length.
How are the shares rounded?
In two steps, each by the largest-remainder method: the groups share 100, and then each group's teams share that group's own whole number. Rounding every team against 100 on its own can make a group's teams add up to one more or less than the group, which looks like a mistake in a nested list.
Is it accessible?
The legend is a nested list (a heading for each group, its teams as list items with headcount and share), so a screen reader reads every number in the order of the arcs. The rings are hidden from assistive technology because the list says the same, and a caption says which ring is which. The total in the hole is real text; with reduced motion the arcs and the digits appear at once.
How does the divider reach the top rule?
The page column is the split itself, so its cells carry the padding and the divider is a start border running down the end cells from the top rule. On a phone the divider is replaced by rules with + marks between the header, the rings and the legend. The legend ends the block, so there is no bottom rule: the next section's top rule closes it.