2

Pie Chart

PreviousNext

Circular charts for visualizing proportional data with support for multiple variants including pie, donut, interactive, and labeled styles.

"use client"

import { PieChart } from "@/components/ui/charts"

const data = [
  { label: "Chrome", value: 275, color: "#2563eb" },
  { label: "Safari", value: 200, color: "#3b82f6" },
  { label: "Firefox", value: 187, color: "#60a5fa" },
  { label: "Edge", value: 173, color: "#93c5fd" },
  { label: "Other", value: 90, color: "#bfdbfe" },
]

export function PieChartDemo() {
  return (
    <div className="w-full max-w-md">
      <PieChart data={data} />
    </div>
  )
}

About

The Pie Chart component displays data as proportional slices of a circle. Built with D3.js for precise control over rendering, it supports various configurations including:

  • Pie and donut chart styles
  • Active segment highlighting with expansion effects
  • Center text for displaying totals or selected values
  • External labels with connector lines
  • Interactive selection with dropdown controls
  • Custom tooltips with theme-aware styling

Installation

pnpm dlx shadcn@latest add https://ui.simplifying.ai/r/pie-chart.json

Usage

import { PieChart } from "@/components/ui/charts"
 
const data = [
  { label: "Chrome", value: 275 },
  { label: "Safari", value: 200 },
  { label: "Firefox", value: 187 },
  { label: "Edge", value: 173 },
  { label: "Other", value: 90 },
]
 
export function MyChart() {
  return <PieChart data={data} />
}

Examples

Default

The default pie chart displays data as filled slices with smooth hover transitions. Each segment can be hovered to show a tooltip with the exact value and percentage.

"use client"

import { PieChart } from "@/components/ui/charts"

const data = [
  { label: "Chrome", value: 275, color: "#2563eb" },
  { label: "Safari", value: 200, color: "#3b82f6" },
  { label: "Firefox", value: 187, color: "#60a5fa" },
  { label: "Edge", value: 173, color: "#93c5fd" },
  { label: "Other", value: 90, color: "#bfdbfe" },
]

export function PieChartDemo() {
  return (
    <div className="w-full max-w-md">
      <PieChart data={data} />
    </div>
  )
}

Donut

A donut chart adds an inner radius creating a ring shape. This variant is useful when you want to place additional information in the center or simply prefer the aesthetic.

"use client"

import { PieChart } from "@/components/ui/charts"

const data = [
  { label: "Chrome", value: 275, color: "#2563eb" },
  { label: "Safari", value: 200, color: "#3b82f6" },
  { label: "Firefox", value: 187, color: "#60a5fa" },
  { label: "Edge", value: 173, color: "#93c5fd" },
  { label: "Other", value: 90, color: "#bfdbfe" },
]

export function PieChartDonutDemo() {
  return (
    <div className="w-full max-w-md">
      <PieChart data={data} variant="donut" />
    </div>
  )
}
<PieChart data={data} variant="donut" />

The variant="donut" automatically sets an appropriate inner radius. You can customize it further with the innerRadius prop.

Donut with Active Segment

This variant highlights the currently hovered or active segment by expanding it outward. The active segment grows by 10px while other segments dim, creating a clear visual focus.

"use client"

import { PieChart } from "@/components/ui/charts"

const data = [
  { label: "Chrome", value: 275, color: "#2563eb" },
  { label: "Safari", value: 200, color: "#3b82f6" },
  { label: "Firefox", value: 187, color: "#60a5fa" },
  { label: "Edge", value: 173, color: "#93c5fd" },
  { label: "Other", value: 90, color: "#bfdbfe" },
]

export function PieChartDonutActiveDemo() {
  return (
    <div className="w-full max-w-md">
      <PieChart data={data} variant="donut-active" />
    </div>
  )
}
<PieChart data={data} variant="donut-active" />

Use this variant when you want to emphasize user interaction and make segment selection more prominent.

Donut with Center Text

Display a total value or the currently active segment's value in the center of the donut. When hovering over a segment, the center text updates to show that segment's value and label.

1,125Visitors
"use client"

import { PieChart } from "@/components/ui/charts"

const data = [
  { label: "Chrome", value: 275, color: "#2563eb" },
  { label: "Safari", value: 200, color: "#3b82f6" },
  { label: "Firefox", value: 287, color: "#60a5fa" },
  { label: "Edge", value: 173, color: "#93c5fd" },
  { label: "Other", value: 190, color: "#bfdbfe" },
]

export function PieChartDonutTextDemo() {
  return (
    <div className="w-full max-w-md">
      <PieChart
        data={data}
        variant="donut-text"
        centerLabel="Visitors"
        showTotal
      />
    </div>
  )
}
<PieChart data={data} variant="donut-text" centerLabel="Visitors" showTotal />

The showTotal prop displays the sum of all values when no segment is hovered. You can also provide custom centerLabel and centerValue props for static content.

With Labels

External labels with connector lines help identify each segment without requiring hover interaction. This is ideal for static displays, print, or when you need all information visible at once.

275Chrome200Safari187Firefox173Edge90Other
"use client"

import { PieChart } from "@/components/ui/charts"

const data = [
  { label: "Chrome", value: 275, color: "#2563eb" },
  { label: "Safari", value: 200, color: "#3b82f6" },
  { label: "Firefox", value: 187, color: "#60a5fa" },
  { label: "Edge", value: 173, color: "#93c5fd" },
  { label: "Other", value: 90, color: "#bfdbfe" },
]

export function PieChartLabelDemo() {
  return (
    <div className="w-full max-w-lg">
      <PieChart data={data} variant="label" showLabels />
    </div>
  )
}
<PieChart data={data} variant="label" showLabels />

Labels are automatically positioned around the chart with connecting lines from each segment's centroid.

Interactive

An interactive pie chart with a dropdown selector for choosing the active segment. The selected segment displays with a double-ring effect (outer ring) and center text updates to show the selection.

186January
"use client"

import * as React from "react"

import { PieChart } from "@/components/ui/charts"

const data = [
  { label: "January", value: 186, color: "#2563eb" },
  { label: "February", value: 305, color: "#3b82f6" },
  { label: "March", value: 237, color: "#60a5fa" },
  { label: "April", value: 173, color: "#93c5fd" },
  { label: "May", value: 209, color: "#bfdbfe" },
]

const selectionOptions = [
  { key: "january", label: "January" },
  { key: "february", label: "February" },
  { key: "march", label: "March" },
  { key: "april", label: "April" },
  { key: "may", label: "May" },
]

export function PieChartInteractiveDemo() {
  const [selectedKey, setSelectedKey] = React.useState("january")

  return (
    <div className="w-full max-w-md">
      <PieChart
        data={data}
        variant="interactive"
        selectionOptions={selectionOptions}
        selectedKey={selectedKey}
        onSelectionChange={setSelectedKey}
        centerLabel="Visitors"
      />
    </div>
  )
}
import { useState } from "react"
 
const selectionOptions = [
  { key: "january", label: "January" },
  { key: "february", label: "February" },
  { key: "march", label: "March" },
  { key: "april", label: "April" },
  { key: "may", label: "May" },
]
 
export function InteractiveChart() {
  const [selectedKey, setSelectedKey] = useState("january")
 
  return (
    <PieChart
      data={data}
      variant="interactive"
      selectionOptions={selectionOptions}
      selectedKey={selectedKey}
      onSelectionChange={setSelectedKey}
    />
  )
}

Use this variant for dashboards where users need to drill down into specific data segments.

API Reference

PropTypeDefaultDescription
dataPieChartDataPoint[]requiredArray of data points to display
variant"default" | "donut" | "donut-active" | "donut-text" | "label" | "interactive""default"Chart style variant
configChartConfig-Color and label configuration
widthnumber400Chart width in pixels
heightnumber400Chart height in pixels
innerRadiusnumber0 (60 for donut)Inner radius for donut effect
outerRadiusnumberautoOuter radius (auto-calculated from dimensions)
padAnglenumber0.02Gap between slices in radians
cornerRadiusnumber4Corner rounding of segments
startAnglenumber0Starting angle in radians
endAnglenumberEnding angle in radians
sortValuesbooleanfalseSort segments by value (largest first)
showLabelsbooleanfalseShow labels on/around segments
labelType"percent" | "value" | "label""percent"Format for displayed labels
showLegendbooleantrueShow legend below chart
showTooltipbooleantrueEnable tooltip on hover
activeIndexnumber-Controlled active segment index
centerLabelReactNode-Custom center label (donut-text variant)
centerValueReactNode-Custom center value (donut-text variant)
showTotalbooleantrueShow total in center when idle
valueFormatter(value: number, total: number) => stringpercentageCustom value formatter
onSegmentClick(data: PieChartDataPoint, index: number) => void-Callback when segment is clicked
selectionOptionsArray<{ key: string; label: string }>-Dropdown options (interactive variant)
selectedKeystring-Currently selected key (interactive variant)
onSelectionChange(key: string) => void-Selection change callback

Data Types

interface PieChartDataPoint {
  label: string // Segment label displayed in tooltip/legend
  value: number // Numeric value determining segment size
  color?: string // Optional: override default color for this segment
}

Customization

Custom Colors

Use the config prop to define colors for each segment, or set colors directly in your data:

// Using config
const config = {
  Chrome: { label: "Chrome", color: "hsl(var(--chart-1))" },
  Safari: { label: "Safari", color: "hsl(var(--chart-2))" },
  Firefox: { label: "Firefox", color: "hsl(var(--chart-3))" },
}
 
<PieChart data={data} config={config} />
 
// Or using data colors
const data = [
  { label: "Success", value: 80, color: "#22c55e" },
  { label: "Warning", value: 15, color: "#eab308" },
  { label: "Error", value: 5, color: "#ef4444" },
]
 
<PieChart data={data} />

Custom Value Formatter

Format how values are displayed in tooltips and labels:

<PieChart
  data={data}
  valueFormatter={(value, total) => {
    const percent = ((value / total) * 100).toFixed(0)
    return `${value.toLocaleString()} (${percent}%)`
  }}
/>

Half Donut / Gauge

Create a half-circle chart by adjusting the start and end angles:

<PieChart
  data={data}
  variant="donut"
  startAngle={-Math.PI / 2}
  endAngle={Math.PI / 2}
/>

Accessibility

  • Segments are keyboard accessible with clear focus indicators
  • Tooltips provide detailed information on hover/focus
  • Color schemes maintain WCAG contrast requirements
  • Legend provides an alternative way to identify segments

Notes

  • Pie charts work best with 5-7 segments; too many segments can make the chart difficult to read
  • Consider using a donut variant when you want to display additional information in the center
  • For data comparisons across multiple categories, consider using a bar chart instead
  • The interactive variant is ideal for dashboards where users need to focus on specific segments
  • Use external labels (variant="label") when you need all information visible without user interaction
  • Sort segments by value (sortValues=true) to make it easier to compare segment sizes
  • The component uses D3.js for precise arc calculations and smooth animations