Pie Chart

Charts

Pie 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