26 lines
1.2 KiB
TypeScript
26 lines
1.2 KiB
TypeScript
export function DonutChart({ segments }: { segments: { label: string; value: number; color: string }[] }) {
|
|
let offset = 25;
|
|
const total = segments.reduce((sum, segment) => sum + segment.value, 0);
|
|
return (
|
|
<div className="flex items-center gap-5">
|
|
<svg viewBox="0 0 42 42" className="size-28 -rotate-90">
|
|
<circle cx="21" cy="21" r="15.9" fill="none" stroke="currentColor" strokeWidth="6" className="text-forest/10 dark:text-white/10" />
|
|
{segments.map((segment) => {
|
|
const dash = (segment.value / total) * 100;
|
|
const circle = <circle key={segment.label} cx="21" cy="21" r="15.9" fill="none" stroke={segment.color} strokeDasharray={`${dash} ${100 - dash}`} strokeDashoffset={offset} strokeWidth="6" />;
|
|
offset -= dash;
|
|
return circle;
|
|
})}
|
|
</svg>
|
|
<div className="space-y-2">
|
|
{segments.map((segment) => (
|
|
<div key={segment.label} className="flex items-center gap-2 text-sm text-ink/70 dark:text-paper/70">
|
|
<span className="size-2.5 rounded-full" style={{ background: segment.color }} />
|
|
{segment.label} · {segment.value}%
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|