Donut chart

Pro

Parts of a whole. Six parts at most; the rest fold into "Other" in neutral grey rather than a seventh hue. Segments are separated by a 2px gap; the total sits in the middle. The legend carries each part's value and share, so nothing depends on matching colours.

Markdown

Preview

Install

With the Candor CLI

First time? Get started sets up the registry and theme. Or with shadcn directly: npx shadcn@latest add @candor/donut-chart

Brings in: chart-frame, data, locale, scale

Usage

TSX · The example above
"use client"

import { DonutChart, type DonutPart } from "@/components/donut-chart"

const changes: DonutPart[] = [
  { label: "API handlers", value: 14 },
  { label: "UI components", value: 22 },
  { label: "Migrations", value: 9 },
  { label: "Background jobs", value: 7 },
  { label: "Feature flags", value: 5 },
  { label: "Dashboards", value: 3 },
  { label: "Infrastructure config", value: 2 },
]

export default function Example() {
  return <DonutChart className="max-w-xl" title="What’s changing" subtitle="Changes in the 4.2 release" parts={changes} totalLabel="changes" />
}

<DonutChart>

PropTypeDefaultDescription
titlerequiredstring—What the chart shows, above it.
subtitlestring | undefined—A line under the title, e.g. the period or unit.
partsrequiredDonutPart[]—The parts of the whole; past six, the smallest fold into Other.
formatValueFormat | undefined"number"How values are written: number, percent (0–1), currency (USD) or duration (seconds). Defaults to number.
totalLabelstring | undefined—The word under the total in the middle. Defaults to "Total".
stateChartState | undefined—Loading, empty, partial or error. Parts that sum to zero show as empty.
classNamestring | undefined—Extra classes for the outer element.

Strings

The fixed words, in English by default. Change any of them under donutChart in <LocaleProvider strings={{ … }}>; the table is exported as donutChartStrings.

KeyEnglish
totalTotal
otherOther
emptyNothing to divide up yet.
valueValue
shareShare
ofTotalof total
part{label} {value}

Types

DonutPart
{ label: string; value: number }