Component
Donut Chart
Donut pie chart with five segments and a centred total-visitors label. Uses chart-* color tokens so it adapts to any active theme.
Usage
Use donut charts to show part-to-whole relationships when you want to highlight a single summary value in the centre. Keep to 3–6 segments for readability.
Playground
Preview
Configure
Code
const chartData = [
{ browser: "chrome", visitors: 275, fill: "var(--color-chrome)" },
{ browser: "safari", visitors: 200, fill: "var(--color-safari)" },
{ browser: "firefox", visitors: 287, fill: "var(--color-firefox)" },
{ browser: "edge", visitors: 173, fill: "var(--color-edge)" },
{ browser: "other", visitors: 190, fill: "var(--color-other)" },
]
const chartConfig = {
visitors: { label: "Visitors" },
chrome: { label: "Chrome", color: "var(--chart-1)" },
safari: { label: "Safari", color: "var(--chart-2)" },
firefox: { label: "Firefox", color: "var(--chart-3)" },
edge: { label: "Edge", color: "var(--chart-4)" },
other: { label: "Other", color: "var(--chart-5)" },
} satisfies ChartConfig
const totalVisitors = chartData.reduce((acc, curr) => acc + curr.visitors, 0)
<Card className="flex flex-col">
<CardHeader className="items-center pb-0">
<CardTitle>Donut Chart</CardTitle>
<CardDescription>January – June 2024</CardDescription>
</CardHeader>
<CardContent className="flex-1 pb-0">
<ChartContainer config={chartConfig} className="mx-auto aspect-square max-h-[250px]">
<PieChart>
<ChartTooltip cursor={false} content={<ChartTooltipContent hideLabel />} />
<Pie
data={chartData}
dataKey="visitors"
nameKey="browser"
innerRadius={60}
strokeWidth={5}
stroke="var(--card)"
>
<Label
content={({ viewBox }) => {
if (viewBox && "cx" in viewBox && "cy" in viewBox) {
return (
<text x={viewBox.cx} y={viewBox.cy} textAnchor="middle" dominantBaseline="middle">
<tspan x={viewBox.cx} y={viewBox.cy} className="fill-foreground text-3xl font-bold">
{totalVisitors.toLocaleString()}
</tspan>
<tspan x={viewBox.cx} y={(viewBox.cy ?? 0) + 24} className="fill-muted-foreground">
Visitors
</tspan>
</text>
)
}
}}
/>
</Pie>
</PieChart>
</ChartContainer>
</CardContent>
<CardFooter className="flex-col gap-2 text-sm">
<div className="flex items-center gap-2 leading-none font-medium">
Trending up by 5.2% this month <TrendUp className="size-4" />
</div>
<div className="leading-none text-muted-foreground">
Showing total visitors for the last 6 months
</div>
</CardFooter>
</Card>Do
- Limit segments to 3–6, more slices become difficult to distinguish
- Use chart-* color tokens so segments adapt automatically when the theme changes
- Add a centred label to surface the most important aggregate value
Don't
- Don't use a pie or donut chart for comparing precise values, use a bar chart instead
- Don't label individual slices with both a legend and inline text, pick one