# Pie Chart

> Show a simple part-to-whole relationship with a small number of categories.

Source: https://www.honestui.com/docs/charts/pie-chart/static

### Basic Chart

```tsx
"use client";

import { PieChart, type ChartConfig } from "honestui/charts";

// Scenario: Trail usage
const data = [
  { category: "hiking", visits: 320 },
  { category: "cycling", visits: 245 },
  { category: "running", visits: 190 },
  { category: "climbing", visits: 135 },
  { category: "picnics", visits: 85 },
];

const chartConfig = {
  hiking: {
    label: "Hiking",
    colors: {
      light: ["#3b82f6"],
      dark: ["#60a5fa"],
    },
  },
  cycling: {
    label: "Cycling",
    colors: {
      light: ["#10b981"],
      dark: ["#34d399"],
    },
  },
  running: {
    label: "Running",
    colors: {
      light: ["#f59e0b"],
      dark: ["#fbbf24"],
    },
  },
  climbing: {
    label: "Climbing",
    colors: {
      light: ["#8b5cf6"],
      dark: ["#a78bfa"],
    },
  },
  picnics: {
    label: "Picnics",
    colors: {
      light: ["#6b7280"],
      dark: ["#9ca3af"],
    },
  },
} satisfies ChartConfig;

export function ExamplePieChart() {
  return (
    <PieChart
      className="h-full w-full p-4"
      data={data}
      dataKey="visits"
      nameKey="category"
      config={chartConfig}
    >
      <PieChart.Legend isClickable />
      <PieChart.Tooltip />
      <PieChart.Pie isClickable />
    </PieChart>
  );
}

```

## Overview [#overview]

Use a pie or donut chart to show a simple part-to-whole relationship with a small number of categories. Use a bar chart when values are close, there are many categories, or precise comparison matters.

## Anatomy [#anatomy]

`PieChart` owns the data, configuration, selection, and loading state. `Pie` controls the sectors and their geometry, while optional `Label`, `Legend`, `Tooltip`, and `Background` parts add context.

## Accessibility [#accessibility]

Canvas charts need a nearby text summary or data table when exact values or proportions are important. Label sectors directly when space allows and pair every color with a category name and value. Tooltip and direct sector selection are pointer-operated; provide equivalent controls when those interactions are required.

## Installation [#installation]

<CommandBlock commands="[&#x22;honestui&#x22;]" />

## Usage [#usage]

`<PieChart>` owns the data, theme configuration, and shared state. Add a legend, tooltip, background, and one `<PieChart.Pie>` part as needed. The Pie sets its radius, spacing, corners, labels, and selection behavior.

```tsx
import { PieChart, type ChartConfig } from "honestui/charts";
```

```tsx
const data = [
  { category: "hiking", visits: 320 },
  { category: "cycling", visits: 245 },
  { category: "running", visits: 190 },
];

const chartConfig = {
  hiking: {
    label: "Hiking",
    colors: { light: ["#3b82f6"], dark: ["#60a5fa"] },
  },
  cycling: {
    label: "Cycling",
    colors: { light: ["#10b981"], dark: ["#34d399"] },
  },
  running: {
    label: "Running",
    colors: { light: ["#f59e0b"], dark: ["#fbbf24"] },
  },
} satisfies ChartConfig;
```

```tsx
<PieChart data={data} dataKey="visits" nameKey="category" config={chartConfig}>
  <PieChart.Legend isClickable />
  <PieChart.Tooltip />
  <PieChart.Pie isClickable innerRadius={60} paddingAngle={4} cornerRadius={8}>
    <PieChart.Label />
  </PieChart.Pie>
</PieChart>
```

The root compiles its children into an ECharts option and renders the plot on a canvas. The `config` prop maps each sector key to its label and theme colors. See [Chart Config](/docs/charts/chart-config) for the complete shape.

> 
  
    Canvas rendering has a few implementation details to keep in mind: per-sector gradients paint across each sector's own bounding box, sector gaps are constant-width background borders (parallel-edged from rim to center, not a wedge-shaped angular pad), and the `<Background>` pattern is an SVG layer behind the transparent canvas.
  


### Interactive Selection [#interactive-selection]

Add `isClickable` to the `<Pie>` (and `<Legend>`) to make sectors selectable. Selecting one pops it radially outward, the offset-slice look, while the others dim; select again to reset. Handle selection events with the `onSelectionChange` callback on `<PieChart>`:

```tsx
<PieChart
  data={data}
  dataKey="visits"
  nameKey="category"
  config={chartConfig}
  onSelectionChange={(selection) => {
    if (selection) {
      console.log("Selected:", selection.dataKey, "Value:", selection.value);
    } else {
      console.log("Deselected");
    }
  }}
>
  <PieChart.Legend isClickable />
  <PieChart.Tooltip />
  <PieChart.Pie isClickable />
</PieChart>
```

### Loading State [#loading-state]

### isLoading='true'

```tsx
"use client";

import { PieChart, type ChartConfig } from "honestui/charts";

// Scenario: Inventory status
const data = [
  { category: "available", units: 410 },
  { category: "reserved", units: 225 },
  { category: "transit", units: 170 },
  { category: "inspection", units: 90 },
  { category: "damaged", units: 35 },
];

const chartConfig = {
  available: {
    label: "Available",
    colors: {
      light: ["#3b82f6"],
      dark: ["#60a5fa"],
    },
  },
  reserved: {
    label: "Reserved",
    colors: {
      light: ["#10b981"],
      dark: ["#34d399"],
    },
  },
  transit: {
    label: "In transit",
    colors: {
      light: ["#f59e0b"],
      dark: ["#fbbf24"],
    },
  },
  inspection: {
    label: "Inspection",
    colors: {
      light: ["#8b5cf6"],
      dark: ["#a78bfa"],
    },
  },
  damaged: {
    label: "Damaged",
    colors: {
      light: ["#6b7280"],
      dark: ["#9ca3af"],
    },
  },
} satisfies ChartConfig;

export function ExamplePieChart() {
  return (
    <PieChart
      className="h-full w-full p-4"
      data={data}
      dataKey="units"
      nameKey="category"
      config={chartConfig}
      isLoading // [!code highlight]
    >
      <PieChart.Legend isClickable />
      <PieChart.Tooltip />
      <PieChart.Pie isClickable />
    </PieChart>
  );
}

```

> 
  
    Pass the `isLoading` prop to show an animated skeleton ring, a shimmer sweeps around the sectors while your data loads.
  


## Examples [#examples]

Examples of the pie chart in different configurations. Customize `innerRadius`, `paddingAngle`, `cornerRadius`, and more.

### Gradient Colors [#gradient-colors]

### gradient colors

```tsx
"use client";

import { PieChart, type ChartConfig } from "honestui/charts";

// Scenario: Electricity sources
const data = [
  { category: "solar", megawatts: 290 },
  { category: "wind", megawatts: 235 },
  { category: "hydro", megawatts: 180 },
  { category: "nuclear", megawatts: 150 },
  { category: "gas", megawatts: 95 },
];

const chartConfig = {
  solar: {
    label: "Solar",
    colors: {
      light: ["#93c5fd", "#3b82f6", "#2563eb", "#1d4ed8", "#1e40af"], // [!code highlight]
      dark: ["#bfdbfe", "#60a5fa", "#3b82f6", "#2563eb", "#1d4ed8"], // [!code highlight]
    },
  },
  wind: {
    label: "Wind",
    colors: {
      light: ["#6ee7b7", "#10b981", "#059669", "#047857", "#065f46"], // [!code highlight]
      dark: ["#a7f3d0", "#34d399", "#10b981", "#059669", "#047857"], // [!code highlight]
    },
  },
  hydro: {
    label: "Hydro",
    colors: {
      light: ["#fcd34d", "#f59e0b", "#d97706", "#b45309", "#92400e"], // [!code highlight]
      dark: ["#fde68a", "#fbbf24", "#f59e0b", "#d97706", "#b45309"], // [!code highlight]
    },
  },
  nuclear: {
    label: "Nuclear",
    colors: {
      light: ["#c4b5fd", "#8b5cf6", "#7c3aed", "#6d28d9", "#5b21b6"], // [!code highlight]
      dark: ["#ddd6fe", "#a78bfa", "#8b5cf6", "#7c3aed", "#6d28d9"], // [!code highlight]
    },
  },
  gas: {
    label: "Natural gas",
    colors: {
      light: ["#d1d5db", "#9ca3af", "#6b7280", "#4b5563", "#374151"], // [!code highlight]
      dark: ["#e5e7eb", "#d1d5db", "#9ca3af", "#6b7280", "#4b5563"], // [!code highlight]
    },
  },
} satisfies ChartConfig;

export function ExamplePieChart() {
  return (
    <PieChart
      className="h-full w-full p-4"
      data={data}
      dataKey="megawatts"
      nameKey="category"
      config={chartConfig}
    >
      <PieChart.Legend isClickable />
      <PieChart.Tooltip />
      <PieChart.Pie isClickable />
    </PieChart>
  );
}

```

### Donut Chart [#donut-chart]

### innerRadius={60}

```tsx
"use client";

import { PieChart, type ChartConfig } from "honestui/charts";

// Scenario: Household budget
const data = [
  { category: "housing", amount: 38 },
  { category: "food", amount: 24 },
  { category: "transport", amount: 16 },
  { category: "health", amount: 12 },
  { category: "savings", amount: 10 },
];

const chartConfig = {
  housing: {
    label: "Housing",
    colors: {
      light: ["#3b82f6"],
      dark: ["#60a5fa"],
    },
  },
  food: {
    label: "Food",
    colors: {
      light: ["#10b981"],
      dark: ["#34d399"],
    },
  },
  transport: {
    label: "Transport",
    colors: {
      light: ["#f59e0b"],
      dark: ["#fbbf24"],
    },
  },
  health: {
    label: "Health",
    colors: {
      light: ["#8b5cf6"],
      dark: ["#a78bfa"],
    },
  },
  savings: {
    label: "Savings",
    colors: {
      light: ["#6b7280"],
      dark: ["#9ca3af"],
    },
  },
} satisfies ChartConfig;

export function ExamplePieChart() {
  return (
    <PieChart
      className="h-full w-full p-4"
      data={data}
      dataKey="amount"
      nameKey="category"
      config={chartConfig}
    >
      <PieChart.Legend isClickable />
      <PieChart.Tooltip />
      <PieChart.Pie
        isClickable
        innerRadius={60} // [!code highlight]
      />
    </PieChart>
  );
}

```

> 
  
    Set `innerRadius` above 0 to create a donut chart, the inner radius carves the hole in the center.
  


### Padded Sectors [#padded-sectors]

### paddingAngle={4} cornerRadius={8}

```tsx
"use client";

import { PieChart, type ChartConfig } from "honestui/charts";

// Scenario: Course enrollment
const data = [
  { category: "science", students: 264 },
  { category: "arts", students: 218 },
  { category: "business", students: 176 },
  { category: "language", students: 132 },
  { category: "music", students: 88 },
];

const chartConfig = {
  science: {
    label: "Science",
    colors: {
      light: ["#3b82f6"],
      dark: ["#60a5fa"],
    },
  },
  arts: {
    label: "Arts",
    colors: {
      light: ["#10b981"],
      dark: ["#34d399"],
    },
  },
  business: {
    label: "Business",
    colors: {
      light: ["#f59e0b"],
      dark: ["#fbbf24"],
    },
  },
  language: {
    label: "Languages",
    colors: {
      light: ["#8b5cf6"],
      dark: ["#a78bfa"],
    },
  },
  music: {
    label: "Music",
    colors: {
      light: ["#6b7280"],
      dark: ["#9ca3af"],
    },
  },
} satisfies ChartConfig;

export function ExamplePieChart() {
  return (
    <PieChart
      className="h-full w-full p-4"
      data={data}
      dataKey="students"
      nameKey="category"
      config={chartConfig}
    >
      <PieChart.Legend isClickable />
      <PieChart.Tooltip />
      <PieChart.Pie
        isClickable
        innerRadius={30} // [!code highlight]
        paddingAngle={4} // [!code highlight]
        cornerRadius={8} // [!code highlight]
      />
    </PieChart>
  );
}

```

> 
  
    Use `paddingAngle` to space sectors apart and `cornerRadius` to round their corners. Combine with `innerRadius` for a modern donut look.
  


### innerRadius={60} paddingAngle={-25} cornerRadius={99}

```tsx
"use client";

import { PieChart, type ChartConfig } from "honestui/charts";

// Scenario: Shipment destinations
const data = [
  { category: "north", parcels: 275 },
  { category: "south", parcels: 230 },
  { category: "east", parcels: 195 },
  { category: "west", parcels: 160 },
  { category: "central", parcels: 115 },
];

const chartConfig = {
  north: {
    label: "North",
    colors: {
      light: ["#3b82f6"],
      dark: ["#60a5fa"],
    },
  },
  south: {
    label: "South",
    colors: {
      light: ["#10b981"],
      dark: ["#34d399"],
    },
  },
  east: {
    label: "East",
    colors: {
      light: ["#f59e0b"],
      dark: ["#fbbf24"],
    },
  },
  west: {
    label: "West",
    colors: {
      light: ["#8b5cf6"],
      dark: ["#a78bfa"],
    },
  },
  central: {
    label: "Central",
    colors: {
      light: ["#6b7280"],
      dark: ["#9ca3af"],
    },
  },
} satisfies ChartConfig;

export function ExamplePieChart() {
  return (
    <PieChart
      className="h-full w-full p-4"
      data={data}
      dataKey="parcels"
      nameKey="category"
      config={chartConfig}
    >
      <PieChart.Legend isClickable />
      <PieChart.Tooltip />
      <PieChart.Pie innerRadius={60} paddingAngle={-25} cornerRadius={99} />
    </PieChart>
  );
}

```

> 
  
    Pair a negative `paddingAngle` with a high `cornerRadius` for overlapping, petal-like sectors. A background-colored border separates the petals into a flower-shaped donut.
  


### Labels [#labels]

<ComponentPreview className="mb-0" title="<Label />" name="ex-labels-echarts-pie-chart" />

> 
  
    Compose a `<Label />` inside the `<Pie />` to draw labels on each sector. It shows the sector's value by default; set the `<Label />`'s `dataKey` for a different field.
  


### Outside Labels [#outside-labels]

<ComponentPreview className="mb-0" title="<Label position=&#x22;outside&#x22; />" name="ex-outside-labels-echarts-pie-chart" />

> 
  
    Set the `<Label />`'s `position` to `"outside"` to move each sector's name past the rim with a leader line, the classic ECharts pie layout ([pie-simple](https://echarts.apache.org/examples/en/editor.html?c=pie-simple)). Outside labels show the sector's name (from `config`) by default; inside labels show its value. Give the `<Pie />` a smaller `outerRadius` so the labels have room.
  


## API Reference [#api-reference]

The chart has several parts; the props below are grouped by part. On canvas each part is declarative config the root compiles.

<ApiHeading>
  PieChart
</ApiHeading>

The root container. It owns the data, shared selection state, loading skeleton, and intro reveal. Everything visual is composed as its children and compiled into the ECharts option.


  ### `data`

type: `TData[]`

The chart data, an array of objects, one per sector (`TData extends Record<string, unknown>`).

  ### `dataKey`

type: `keyof TData & string`

The data key for sector values, typically the numbers that size each sector.

  ### `nameKey`

type: `keyof TData & string`

The data key for sector names, used in labels and legend. Each name must match a key in `config`.

  ### `config`

type: `ChartConfig`

Defines the chart's sectors. Each key matches a value from your `nameKey` field, with a `label` and a per-theme `colors` array. Same contract as every Honest UI chart, see [Chart Config](/docs/charts/chart-config).

  ### `children`

type: `ReactNode`

The composed chart parts, `<Legend />`, `<Tooltip />`, `<Background />`, and one `<Pie />`.

  ### `className`

type: `string`

Extra CSS classes for the chart container.

  ### `animation`

type: `boolean` · default: `true`

Master switch for the intro draw-in. Pass `false` to render instantly. Use this as the canvas animation off-switch. The OS reduce-motion preference disables the entrance automatically.

  ### `defaultSelectedSector`

type: `string | null` · default: `null`

The sector selected on first render.

  ### `selectedSector`

type: `string | null`

Controlled selection. When provided it overrides the internal state, so a parent can drive which sector is selected, pair it with `onSelectionChange` to keep your own UI (a custom legend, stat cards) and the chart in sync.

  ### `onSelectionChange`



void">
    Fires when a sector is selected or deselected via a clickable `<Pie />` sector or `<Legend />` entry. Receives an object with `dataKey` (sector name) and `value` (sector value), or `null` when deselected.

  ### `isLoading`

type: `boolean` · default: `false`

Shows the animated loading skeleton while data loads.

  ### `chartOptions`



">
    Escape hatch merged over the underlying ECharts option object. See the [ECharts option documentation](https://echarts.apache.org/en/option.html).


<ApiHeading>
  Pie
</ApiHeading>

The pie series. Carries its own shape and clickability. When clickable, the selected sector pops radially outward. Compose a `<Label />` inside it to draw labels on each sector.


  ### `variant`

type: `&#x22;gradient&#x22;` · default: `&#x22;gradient&#x22;`

The fill style for the sectors. Each paints a diagonal gradient from its `config` colors, solid for a single color, or a multi-stop gradient across the sector.

  ### `innerRadius`

type: `number | string` · default: `0`

The pie's inner radius. Set above 0 for a donut. Accepts a number (pixels) or percentage string.

  ### `outerRadius`

type: `number | string` · default: `&#x22;80%&#x22;`

The pie's outer radius. Accepts a number (pixels) or percentage string.

  ### `cornerRadius`

type: `number` · default: `0`

The border radius for the corners of each sector in pixels.

  ### `paddingAngle`

type: `number` · default: `0`

The space between sectors. Positive values draw a constant-width, background-colored gap (parallel-edged from rim to center, not a wedge-shaped angular pad). Negative values overlap sectors into petals, kept distinct by a background-colored border.

  ### `startAngle`

type: `number` · default: `0`

The starting angle of the pie in degrees (0 is 3 o'clock, 90 is 12 o'clock). Sectors sweep counterclockwise from here.

  ### `endAngle`

type: `number` · default: `360`

The ending angle of the pie in degrees. Set to less than 360 for a partial pie.

  ### `isClickable`

type: `boolean` · default: `false`

Enables clicking a sector to select/deselect it. The selected sector pops radially outward from the center while the others dim.

  ### `children`

type: `ReactNode`

Optional `<Label />` composition that draws labels on each sector.


<ApiHeading>
  Label
</ApiHeading>

Per-sector labels composed inside a `<Pie />`. It renders nothing on its own, the parent `<Pie />` reads its props and draws the labels, either on each sector or outside the rim with a leader line.


  ### `position`

type: `&#x22;inside&#x22; | &#x22;outside&#x22;` · default: `&#x22;inside&#x22;`

Where the labels sit. `"inside"` draws the value on each sector; `"outside"` moves the sector's name past the rim with a leader line (the classic ECharts pie layout). When `"outside"` and no `dataKey` is set, the label shows the sector's name from `config` instead of its value.

  ### `dataKey`

type: `string`

The data key for label text. When omitted, inside labels fall back to the chart's `dataKey` (the sector value), outside labels to the sector's name.


<ApiHeading>
  Tooltip
</ApiHeading>

The hover tooltip. Its presence enables the tooltip; omit it and none shows. Hidden automatically while the chart is loading.


  ### `variant`

type: `&#x22;default&#x22; | &#x22;frosted-glass&#x22;` · default: `&#x22;default&#x22;`

The visual style of the tooltip surface.

  ### `roundness`

type: `&#x22;sm&#x22; | &#x22;md&#x22; | &#x22;lg&#x22; | &#x22;xl&#x22;` · default: `&#x22;lg&#x22;`

Controls the border-radius of the tooltip.

  ### `defaultIndex`

type: `number`

When set, the tooltip is visible by default at the specified sector index.

  ### `position`

type: `&#x22;fixed&#x22; | &#x22;variable&#x22;` · default: `&#x22;variable&#x22;`

How the tooltip is anchored. `"variable"` follows the pointer (the default); `"fixed"` pins the tooltip near the top and only tracks the pointer's X.


<ApiHeading>
  Legend
</ApiHeading>

The sector legend, rendered as HTML over the canvas. Its presence enables the legend; omit it and none shows. When `isClickable` is set, each entry toggles selection of its sector.


  ### `variant`

type: `&#x22;square&#x22; | &#x22;circle&#x22; | &#x22;circle-outline&#x22; | &#x22;rounded-square&#x22; | &#x22;rounded-square-outline&#x22; | &#x22;vertical-bar&#x22; | &#x22;horizontal-bar&#x22;`

The visual style of the legend indicators.

  ### `align`

type: `&#x22;left&#x22; | &#x22;center&#x22; | &#x22;right&#x22;` · default: `&#x22;center&#x22;`

Horizontal placement of the legend.

  ### `verticalAlign`

type: `&#x22;top&#x22; | &#x22;middle&#x22; | &#x22;bottom&#x22;` · default: `&#x22;bottom&#x22;`

Vertical placement of the legend.

  ### `isClickable`

type: `boolean` · default: `false`

Lets each legend entry toggle selection of its sector.


<ApiHeading>
  Background
</ApiHeading>

An optional decorative SVG pattern drawn behind the pie. Its presence renders the pattern; omit it and none shows.


  ### `variant`

type: `BackgroundVariant` · default: `&#x22;dots&#x22;`

The background pattern style, one of `"dots"`, `"grid"`, `"cross-hatch"`, `"diagonal-lines"`, `"plus"`, `"falling-triangles"`, `"4-pointed-star"`, `"tiny-checkers"`, `"overlapping-circles"`, `"wiggle-lines"`, or `"bubbles"`.
