Pie chart
Show the parts of a complete nonnegative whole as a pie or donut, with category patterns and source amounts.
On this page
Completed work
Illustrative category totals for one week
- Planned work
- Repairs
- Inspection
Code
import { PieChart, type PieChartDatum } from "@bosunkit/components/pie-chart";
import { ChartPanel } from "@bosunkit/components/chart-panel";
import { ChartLegend } from "@bosunkit/components/chart-legend";
import type { ChartRegistry } from "@bosunkit/components/chart-container";
import type { ReactElement } from "react";
export const description: string =
"Illustrative completed-work amounts form a whole, with patterned categories and a source table.";
const data: readonly PieChartDatum[] = [
{ key: "planned", value: 6 },
{ key: "repairs", value: 3 },
{ key: "inspection", value: 1 },
];
const values: Readonly<Record<number, string>> = { 0: "0 items", 1: "1 item", 3: "3 items", 6: "6 items" };
const write: (value: number) => string = (value: number): string => values[value] ?? "";
const config: ChartRegistry = {
planned: { label: "Planned work", formatValue: write },
repairs: { label: "Repairs", formatValue: write },
inspection: { label: "Inspection", formatValue: write },
};
export default function WorkComposition(): ReactElement {
return (
<ChartPanel
title="Completed work"
description="Illustrative category totals for one week"
legend={<ChartLegend config={config} mark="bar" label="Work categories" />}
footer="Items completed · all categories belong to the same whole"
>
<PieChart
data={data}
config={config}
label="Illustrative composition of completed work"
categoryLabel="Work category"
valueLabel="Completed items"
dataTableLabel="View completed amounts"
missingValueText="Not counted"
incompleteDataText="Some categories were not counted. View the known amounts in the table."
emptyDataText="No completed items were counted for this period."
/>
</ChartPanel>
);
}
A pie chart compares parts of one whole. Each datum has a stable key into the category registry and a nonnegative value. The registry defines the category's display name, operational palette slot, pattern and value formatter. A donut has the same data contract, with its hole size supplied by the chart token.
Use
Use one unit, one period and mutually exclusive categories that account for the entire whole. Use BarChart when precise comparisons between amounts matter, or when values can be negative. Limit categories to the kit's nine operational palette slots; combine small parts under a caller-named aggregate when appropriate.
Negative amounts and duplicate keys are rejected. Null or nonfinite amounts show incompleteDataText; the table retains known amounts. An empty or zero total shows emptyDataText and has no invented slice. The chart formats no percentages: pass percentage display text through your own category formatter when the comparison needs it.
There is no per-slice visibility toggle: hiding a part and recomputing the angles would change what the whole means. A caller can switch between complete datasets, while keeping the registry stable so category appearance stays consistent.
Examples
Pie
Completed work
Illustrative category totals for one week
- Planned work
- Repairs
- Inspection
Code
import { PieChart, type PieChartDatum } from "@bosunkit/components/pie-chart";
import { ChartPanel } from "@bosunkit/components/chart-panel";
import { ChartLegend } from "@bosunkit/components/chart-legend";
import type { ChartRegistry } from "@bosunkit/components/chart-container";
import type { ReactElement } from "react";
export const description: string =
"Illustrative completed-work amounts form a whole, with patterned categories and a source table.";
const data: readonly PieChartDatum[] = [
{ key: "planned", value: 6 },
{ key: "repairs", value: 3 },
{ key: "inspection", value: 1 },
];
const values: Readonly<Record<number, string>> = { 0: "0 items", 1: "1 item", 3: "3 items", 6: "6 items" };
const write: (value: number) => string = (value: number): string => values[value] ?? "";
const config: ChartRegistry = {
planned: { label: "Planned work", formatValue: write },
repairs: { label: "Repairs", formatValue: write },
inspection: { label: "Inspection", formatValue: write },
};
export default function WorkComposition(): ReactElement {
return (
<ChartPanel
title="Completed work"
description="Illustrative category totals for one week"
legend={<ChartLegend config={config} mark="bar" label="Work categories" />}
footer="Items completed · all categories belong to the same whole"
>
<PieChart
data={data}
config={config}
label="Illustrative composition of completed work"
categoryLabel="Work category"
valueLabel="Completed items"
dataTableLabel="View completed amounts"
missingValueText="Not counted"
incompleteDataText="Some categories were not counted. View the known amounts in the table."
emptyDataText="No completed items were counted for this period."
/>
</ChartPanel>
);
}
Donut
Completed work
Illustrative category totals for one week
- Planned work
- Repairs
- Inspection
Code
import { PieChart, type PieChartDatum } from "@bosunkit/components/pie-chart";
import { ChartPanel } from "@bosunkit/components/chart-panel";
import { ChartLegend } from "@bosunkit/components/chart-legend";
import type { ChartRegistry } from "@bosunkit/components/chart-container";
import type { ReactElement } from "react";
export const description: string =
"Illustrative completed-work amounts form a donut, with patterned categories and a source table.";
const data: readonly PieChartDatum[] = [
{ key: "planned", value: 6 },
{ key: "repairs", value: 3 },
{ key: "inspection", value: 1 },
];
const values: Readonly<Record<number, string>> = { 0: "0 items", 1: "1 item", 3: "3 items", 6: "6 items" };
const write: (value: number) => string = (value: number): string => values[value] ?? "";
const config: ChartRegistry = {
planned: { label: "Planned work", formatValue: write },
repairs: { label: "Repairs", formatValue: write },
inspection: { label: "Inspection", formatValue: write },
};
export default function WorkDonut(): ReactElement {
return (
<ChartPanel
title="Completed work"
description="Illustrative category totals for one week"
legend={<ChartLegend config={config} mark="bar" label="Work categories" />}
footer="Items completed · all categories belong to the same whole"
>
<PieChart
data={data}
config={config}
label="Illustrative composition of completed work"
variant="donut"
categoryLabel="Work category"
valueLabel="Completed items"
dataTableLabel="View completed amounts"
missingValueText="Not counted"
incompleteDataText="Some categories were not counted. View the known amounts in the table."
emptyDataText="No completed items were counted for this period."
/>
</ChartPanel>
);
}
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| callout | ChartCallout | undefined | – | A persistent caller-formatted summary bubble inside the drawing. |
| datarequired | readonly PieChartDatum[] | – | The complete set of parts of the whole. Missing parts suppress the drawing. |
| configrequired | ChartRegistry | – | Category definitions, with caller labels and value formatters. |
| labelrequired | string | – | The chart's accessible name, naming the quantity and time window. |
| categoryLabelrequired | string | – | The first table column's heading. |
| valueLabelrequired | string | – | The amount column's heading. |
| dataTableLabelrequired | string | – | The disclosure button and source table's accessible name. |
| missingValueTextrequired | string | – | Display text for missing amounts. |
| incompleteDataTextrequired | string | – | Explains that missing parts prevent the composition from being drawn. |
| emptyDataTextrequired | string | – | Explains that a zero or empty total has no composition to draw. |
| variant | "pie" | "donut" | undefined | "pie" | Pie or donut; pie by default. |
| height | string | undefined | "var(--bk-chart-height)" | Plot height as a CSS length, from the chart-height token by default. |
| motion | MotionProp | undefined | – | Entrance and exit motion; off by default. Slice values never interpolate. |
| children | ReactNode | undefined | – | Recharts annotations appended to the chart root. |
| className | string | undefined | – | Classes added to the root. |
| testId | string | undefined | – | Becomes data-testid on the root, with --plot and --table parts. |
| ref | Ref<HTMLDivElement> | undefined | – | The root element. |
Completed work
Illustrative category totals for one week
- Planned work
- Repairs
- Inspection
Explain the incomplete data and preserve the known amounts in the source table.
Related
- Bar chart: precise amount comparisons and signed values.
- Chart legend: category names and patterned swatches.
- Data visualization: comparable scales and missing measurements.