Donut Chart
A donut and pie chart for visualizing part-to-whole relationships. Supports center labels, click interactions, and custom tooltips. Powered by Recharts, inspired by Tremor.
Donut
Basic donut chart with a value formatter.
Center Label
Enable showLabel to show the sum of all values in the center. Pass a custom label to override it.
Auto total
Custom label
Thickness
Control the ring width with thickness (0–100). 0 is a thin ring, 100 is a solid pie.
10
25
50
100
Custom Colors
Override the default palette with any ChartColor[].
Legend
Enable showLegend to show category labels and values alongside the chart. Control placement with legendPosition.
right (default)
left
bottom
top
No Tooltip
Disable the hover tooltip with showTooltip={false}.
Interactive
Click a segment to select it — others dim to 30% opacity. Click again or the background to deselect.
onValueChange: null
DonutChart
A donut (or pie) chart for visualizing part-to-whole relationships. Supports an optional center label, click interactions, custom tooltip, and tooltip callbacks. Powered by Recharts, inspired by Tremor.
Usage
import { DonutChart } from "@/components/charts/donut-chart"
// Basic donut
<DonutChart
data={data}
category="browser"
value="share"
valueFormatter={(v) => `${v}%`}
/>
// With center label showing total
<DonutChart
data={data}
category="browser"
value="share"
showLabel
valueFormatter={(v) => `${v}%`}
/>
// Solid pie (thickness=100)
<DonutChart
data={data}
category="region"
value="revenue"
thickness={100}
valueFormatter={(v) => `$${v.toLocaleString()}`}
/>
// Interactive
<DonutChart
data={data}
category="browser"
value="share"
onValueChange={(v) => console.log(v)}
/>DonutChart Props
| Prop | Type | Default | Description |
|---|---|---|---|
| data* | Record<string, any>[] | — | Array of data objects. Each object needs a key for category labels and a key for numeric values. |
| category* | string | — | Key in each data object used as the segment label (e.g. "browser", "region"). |
| value* | string | — | Key in each data object used as the segment's numeric value. |
| colors | ChartColor[] | CHART_COLORS | Color palette for each segment. Cycles if fewer colors than segments. |
| thickness | number | 25 | Ring thickness from 0 (thin) to 100 (solid pie). Controls the inner radius: innerRadius = (100 - thickness)%. |
| valueFormatter | (value: number) => string | v => v.toString() | Formats tooltip values and the center label total. |
| label | string | — | Custom text shown in the center (donut only). When omitted, the sum of all values is shown. |
| showLabel | boolean | false | Show a label in the center of the donut. Has no effect on the pie variant. |
| showTooltip | boolean | true | Show or hide the tooltip on hover. |
| showLegend | boolean | false | Show a legend with category labels and formatted values alongside the chart. |
| legendPosition | "top" | "bottom" | "left" | "right" | "right" | Position of the legend relative to the chart. Left/right stacks items vertically; top/bottom lays them out horizontally. |
| onValueChange | (value: DonutChartEventProps) => void | — | Callback when a segment is clicked. Returns { eventType: "sector", categoryClicked, ...dataRow } or null on deselect. |
| tooltipCallback | (content: TooltipProps) => void | — | Callback fired whenever the tooltip active state or hovered category changes. |
| customTooltip | React.ComponentType<TooltipProps> | — | Custom tooltip component. Receives active and payload props. |
| className | string | — | Additional CSS classes. The chart has min-h-40 and aspect-square by default — it fills the parent height while staying circular. Without a legend, applied to the outer wrapper. With a legend, applied to the chart portion only. |