Pie Chart
ChartsPie or donut chart with legend.
Preview
React
Vue
Angular
Svelte
Usage
example.jsx
import { PieChart } from "@/components/ui/pie-chart";
export default function Example() {
return <PieChart />;
}Source Code
Copy this file into components/ui/pie-chart.jsx in your project.
pie-chart.jsx
"use client";
import { forwardRef } from "react";
import { cn } from "@/lib/utils";
const COLORS = ["#6366f1", "#ec4899", "#f59e0b", "#10b981", "#3b82f6", "#8b5cf6", "#ef4444", "#06b6d4"];
const PieChart = forwardRef(({ className, data = [], size = 200, donut = false, ...props }, ref) => {
const total = data.reduce((sum, d) => sum + d.value, 0) || 1;
const cx = size / 2, cy = size / 2, r = size / 2 - 10;
let cumAngle = -90;
const slices = data.map((d, i) => {
const angle = (d.value / total) * 360;
const startAngle = cumAngle;
cumAngle += angle;
const endAngle = cumAngle;
const startRad = (startAngle * Math.PI) / 180;
const endRad = (endAngle * Math.PI) / 180;
const x1 = cx + r * Math.cos(startRad);
const y1 = cy + r * Math.sin(startRad);
const x2 = cx + r * Math.cos(endRad);
const y2 = cy + r * Math.sin(endRad);
const largeArc = angle > 180 ? 1 : 0;
const path = `M${cx},${cy} L${x1},${y1} A${r},${r} 0 ${largeArc} 1 ${x2},${y2} Z`;
return { path, color: d.color || COLORS[i % COLORS.length], label: d.label };
});
return (
<div ref={ref} className={cn("inline-block", className)} {...props}>
<svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
{slices.map((s, i) => <path key={i} d={s.path} fill={s.color} opacity="0.85" />)}
{donut && <circle cx={cx} cy={cy} r={r * 0.55} className="fill-background" />}
</svg>
<div className="mt-2 flex flex-wrap gap-3">
{data.map((d, i) => (
<div key={i} className="flex items-center gap-1.5 text-xs">
<span className="h-2.5 w-2.5 rounded-full" style={{ backgroundColor: d.color || COLORS[i % COLORS.length] }} />
{d.label}
</div>
))}
</div>
</div>
);
});
PieChart.displayName = "PieChart";
export { PieChart };
Quick Install
Make sure you have the cn() utility set up. It requires clsx and tailwind-merge.
npm install clsx tailwind-merge