Donut chart
FreeParts of a whole as a ring, with the total in the centre.
pnpm dlx shadcn@latest add https://caliperui.site/r/donut-chart.jsonCustomers by plan. Visible total 820 .
| Category | Value | Share |
|---|---|---|
| Solo | 420 | 51% |
| Team | 310 | 38% |
| Studio | 90 | 11% |
When to use #
Use it for
- Three to six parts that add up to something meaningful.
- A quick sense of composition.
Skip it when
- Many small parts; use a treemap or bar chart.
Installation #
terminal
pnpm dlx shadcn@latest add https://caliperui.site/r/donut-chart.json
Adds its 5 files to components/ui/, each with its own stylesheet, and installs their packages. No account needed. The first part also adds Caliper UI’s tokens; import them once as in Installation.
Usage #
This is the code behind the preview above.
example.tsx
import { DonutChart } from "@/components/ui/donut-chart" export function PlanMix() { return ( <div className="w-full max-w-sm"> <DonutChart label="Customers by plan" data={[ { id: "solo", label: "Solo", value: 420 }, { id: "team", label: "Team", value: 310 }, { id: "studio", label: "Studio", value: 90 }, ]} /> </div> ); }
API reference #
DonutChart
component
PropTypeDefault
label *string—
data *readonly ChartPart[]—
unitstring""
classNamestring—
loadingboolean—
errorstring—
Accessibility #
It exposes group and status semantics, with aria-label, aria-busy, aria-hidden and aria-pressed kept in step with state. Changes that matter are announced through a live region.
KeyBehaviour
EscapeCloses or cancels, then returns focus to where it came from.
Motion #
Transitions use the shared duration and easing tokens. Under prefers-reduced-motion those tokens collapse to instant and travel distances go to zero, so state changes still happen without movement.