
A donut with the total number of users displayed in the center of the ring.
@esuiss
components/charts/pie-chart-donut-text.tsx
"use client"
import { Pie, PieChart } from "recharts"
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card"
import {
type ChartConfig,
ChartContainer,
ChartTooltip,
ChartTooltipContent,
} from "@/components/ui/chart"
const chartData = [
{ device: "phone", users: 275, fill: "var(--color-phone)" },
{ device: "laptop", users: 200, fill: "var(--color-laptop)" },
{ device: "tablet", users: 187, fill: "var(--color-tablet)" },
{ device: "watch", users: 173, fill: "var(--color-watch)" },
{ device: "other", users: 90, fill: "var(--color-other)" },
]
const chartConfig = {
users: { label: "Users" },
phone: { label: "Phone", color: "var(--chart-1)" },
laptop: { label: "Laptop", color: "var(--chart-2)" },
tablet: { label: "Tablet", color: "var(--chart-3)" },
watch: { label: "Watch", color: "var(--chart-4)" },
other: { label: "Other", color: "var(--chart-5)" },
} satisfies ChartConfig
const total = chartData.reduce((sum, item) => sum + item.users, 0)
export function PieChartDonutText() {
return (
<Card variant="filled" size="sm">
<CardHeader>
<CardTitle>Total in the middle</CardTitle>
<CardDescription>A summary inside the ring</CardDescription>
</CardHeader>
<CardContent>
<div className="relative">
<ChartContainer
config={chartConfig}
className="aspect-auto h-52 w-full"
>
<PieChart accessibilityLayer>
<ChartTooltip
cursor={false}
content={<ChartTooltipContent hideLabel nameKey="device" />}
/>
<Pie
data={chartData}
dataKey="users"
nameKey="device"
innerRadius="62%"
outerRadius="88%"
strokeWidth={0}
paddingAngle={1}
cornerRadius={3}
/>
</PieChart>
</ChartContainer>
<div className="pointer-events-none absolute inset-0 flex flex-col items-center justify-center text-center">
<span className="text-2xl font-semibold tracking-tight tabular-nums">
{total.toLocaleString("en-US")}
</span>
<span className="text-xs text-muted-foreground">users</span>
</div>
</div>
</CardContent>
</Card>
)
}































