Prodular UI

Donut chart

A donut or pie with the total in the center and a legend with values and shares. Hovering a segment or legend row shows that part in the center.

npx prodular-ui add donut-chart

Parts of a total

Total in the center, legend on the right with each part's share. Colors follow chart-1 to chart-5.

Seats by plan
Paid seats across 312 workspaces
  • Enterprise46%1,840
  • Team30.4%1,215
  • Pro16%640
  • Starter7.6%305

Enterprise: 1,840, Team: 1,215, Pro: 640, Starter: 305

Pick a segment

onValueChange with activeKey turns segments and legend rows into a filter. Click again to clear.

Q3 vendor spend
Pick a category to filter the report

Cloud infrastructure: 128,400, Contractors: 61,900, Software: 38,100, Travel: 12,750

Pie, loading and empty

variant="pie" for two or three parts, a skeleton ring while loading, a muted ring when there is nothing to show.

Pie, two parts

  • Paid on time84.9%214
  • Paid late15.1%38

Paid on time: 214, Paid late: 38

Loading

Empty

Anatomy

<DonutChart  data={[{ name: "Enterprise", value: 1840 }, { name: "Team", value: 1215 }]}  centerLabel="Seats"  legend="right"/>

Guidance

Use it when

  • Parts of one total with five or fewer parts: seats by plan, spend by category, tickets by status.
  • The center for the total, so the chart answers how much and how it splits at once.
  • onValueChange when choosing a part should filter a table or report next to it.

Avoid

  • More than five parts. Group the smallest into Other, or use Bar list.
  • Comparing parts across periods. Use a stacked bar chart.
  • variant="pie" for more than three parts, since angles are hard to compare.

Rules for AI agents

Published in llms-full.txt, the registry and the MCP server, so coding agents follow them when they build with this component.

  • Pass data as { name, value }[]. Leave color out to get chart-1 to chart-5 in order; set color only to a var(--chart-N) token.
  • Format the center and legend values with valueFormatter, for example compact currency.
  • Use legend="bottom" in narrow cards and legend="right" from about 420px wide.
  • Set centerLabel to the unit (Seats, Invoices). centerValue overrides the total, for example 62% used.
  • Show loading while data is fetched and pass empty with what is missing, like No invoices.

API

DonutChart

PropTypeDefaultDescription
data{ name, value, key?, color? }[]Segments in drawing order, clockwise from the top.
variant"donut" | "pie""donut"Pie fills the center and drops the center text.
sizenumber176Diameter in pixels.
thicknessnumber22Ring width in pixels.
valueFormatter(value: number) => ReactNodeFormats the center and legend values.
centerLabel / centerValueReactNode"Total" / the totalCenter text when nothing is hovered.
legend"right" | "bottom" | "none""right"Legend placement. Right stacks under the chart on small screens.
activeKey / onValueChangestring | null / (item | null) => voidMakes segments and legend rows selectable.
loadingbooleanfalseShows a skeleton ring and legend.
emptyReactNode"No data"Center text when the total is zero.

Installation

The Prodular UI CLI adds the source to components/ui with everything it depends on. In a project that already uses shadcn/ui, the shadcn CLI installs it from the Prodular registry too. See Installation for the first setup.

npx prodular-ui add donut-chart# or, with the registry in components.jsonnpx shadcn@latest add @prodular/donut-chart