Pie Chart
Show how a total divides into shares as a donut or pie chart.
- Documents: 200 GB
- Images: 350 GB
- Video: 100 GB
- Other: 120 GB
- Free: 230 GB
A Pie Chart shows a few shares of one total, as a donut by default or as a pie that fills the whole disc. The shares shade the brand color from strong to light, which suits the parts of one whole. Mark a share with empty when it is the unfilled rest, such as free storage. Hover a share to read its value; the card trails beside the share.
Installation
pnpm dlx shadcn@4.18.0 add @siteplane/pie-chartComplete the one-time setup first. Registry JSON lists source files and dependencies.
For this page’s examples, also install:
pnpm dlx shadcn@4.18.0 add @siteplane/toggle-groupUsage
import { PieChart } from "@/siteplane/components/pie-chart";
<PieChart
label="Storage use"
data={[
{ id: "documents", label: "Documents", value: 200 },
{ id: "images", label: "Images", value: 350 },
]}
/>;Pie
variant="pie" fills the whole disc with a wedge per share. The default, donut, draws the shares as a ring around a hole that can hold content of its own.
- Enterprise: $48,200
- Business: $31,500
- Team: $18,900
- Starter: $7,400
Content in the hole
Pass centerValue to show a figure in the hole of the donut, such as the total, and centerLabel for its caption. The chart fits the figure into the hole: in full at the largest of 30, 24 or 20 px that fits, and otherwise in compact notation, such as $2.5M, at the largest step from 30 px down. Screen readers read a compact figure in full. centerFormat takes Intl.NumberFormat options, such as a currency, and the chart adds the compact notation itself. The caption stays on one line and ends in an ellipsis where the hole is too narrow for it.
- Open: 128
- Pending: 54
- On hold: 23
- Enterprise: $1,486,000
- Team: $742,500
- Starter: $257,500
For content of your own, pass center instead. It is laid out in the square around the hole and cut off at the hole’s round edge, so it never covers the ring; keep it short. The content in the hole never takes the pointer, and it is not part of the chart’s accessible name, which is label alone. A pie has no hole and shows none of it.
Without a legend
The legend lists the shares beside the ring, each with its color, and moves below the ring when there is no room beside it. Set legend={false} when the text around the chart already says what it shows, as in a compact card. Screen readers still read every share and its value, as the description of the chart.
Storage
7.2 GB of 10 GB used
Categorical palette
With palette="categorical", each share takes its own chart color, which suits unrelated categories. Pass formatValue to format the value shown in the tooltip and read out with each legend item.
- Organic search: 38%
- Direct: 24%
- Referral: 18%
- Social: 12%
- Email: 8%
Pop-out
With popOut, the highlighted share steps 10 px out along its middle angle and glides back in when it is no longer highlighted. A mouse over a legend entry pops its share out too, without opening the tooltip. Without popOut no share moves, and the legend does not react to the mouse.
- North America: $412K
- Europe: $268K
- Asia Pacific: $174K
- Latin America: $61K
Changing data
When data changes, the chart glides to it. Each share moves to its new size and place; a new share grows from nothing, and a share that is gone shrinks away. Shares are told by their id, so give every share a stable one. The legend adds and removes its entries with the list motion of Motion, and the tooltip stays on the share it was on.
- Search: 5,265 visitors · 42%
- Direct: 3,120 visitors · 25%
- Social: 1,755 visitors · 14%
- Referral: 1,365 visitors · 11%
- Email: 975 visitors · 8%
Sizes
size sets the diameter of the chart in pixels. The chart shrinks to fit a narrow container, and the legend moves below the ring when there is no room beside it.
120 px
- Documents: 200
- Images: 350
- Video: 100
- Other: 120
- Free: 230
200 px
- Documents: 200
- Images: 350
- Video: 100
- Other: 120
- Free: 230
280 px
- Documents: 200
- Images: 350
- Video: 100
- Other: 120
- Free: 230
API reference
| Prop | Type | Default | Description |
|---|---|---|---|
Pie | readonly PieChartDatum[] | required | Shares of the total, drawn clockwise from the top in the order given. |
Pie | string | required | Accessible name of the chart. |
Pie | string | unset | Id of an element that describes the chart, read after the description that the chart gives itself. |
Pie | donut | pie | donut | donut draws the shares as a ring around a hole; pie fills the whole disc with a wedge per share. |
Pie | number | unset | A figure in the hole of the donut, such as the total. The chart fits it: in full at 30, 24 or 20 px, otherwise compact at the largest step that fits. Screen readers read it in full. |
Pie | string | unset | A caption under centerValue: one line of 12 px muted text that ends in an ellipsis where the hole is too narrow. |
Pie | Intl.NumberFormatOptions | unset | How centerValue is written in locale, such as a currency. The chart adds the compact notation when the figure needs it. |
Pie | ReactNode | unset | Content of your own in the hole, in place of centerValue and centerLabel, cut off at the hole’s edge so it never covers the ring. It never takes the pointer and is not part of the accessible name. A pie has no hole and shows none. |
Pie | boolean | true | Lists the shares beside the ring, each with its color, and reads each value to screen readers. Without it the shares and their values are the description of the chart. |
Pie | brand | categorical | brand | brand shades the brand color from strong to light; categorical gives each share its own chart color. A share’s own color wins either way. |
Pie | boolean | false | Steps the highlighted share 10 px out along its middle angle, at any size, and lets a mouse over a legend entry pop its share out too. A share that steps out reaches up to 10 px beyond the box of the chart. |
Pie | number | 200 | Diameter of the chart in pixels. |
Pie | (value: number) => string | locale number (1,234.5) | Formats the value in the tooltip and in the text that screen readers read for each share. |
Pie | string | en-US | Locale of the numbers. |
Pie | string | No data | Shown in the middle of the chart, in place of the content in the hole, when there is nothing to draw: no data, or every value 0. The ring is then drawn in the neutral empty color. |
Pie | Partial<ChartLabels> | English words | Replaces the words that the chart gives screen readers, each one on its own. Pass their translation when the application is in another language. |
Pie | string | unset | Additional classes on the figure. |
Pie | string | required | Stable key of the share. It tells the chart which share is which when the data changes. |
Pie | string | required | Name shown in the legend and the tooltip. |
Pie | number | required | Size of the share. A negative or non-finite value counts as 0. |
Pie | string | palette color | A CSS color that replaces the palette color of this share. |
Pie | boolean | false | Marks an unfilled share. It takes the neutral empty color and does not use up a palette color. |
Chart | string | chart | What screen readers call the chart. |
Chart | string | Use the arrow keys to move between data points. | Read after the description of the chart while it is a focus stop. An empty text leaves the hint out. |
PieChartProps and PieChartDatum export these contracts, and ChartLabels comes
from the chart core, @/siteplane/components/chart, which installs with the
chart. The chart renders a figure with the plot and the legend; it takes no
native props or ref beyond className and aria-describedby. A share that
names no color takes a shade of the brand color, from strong to light, spread
over the filled shares. palette="categorical" gives each share its own chart
color. Both palettes have eight colors and repeat them from the ninth filled
share, except that the last share never takes the color of the first, which it
meets where the ring closes; a color on a share always wins, and an empty
share takes no palette color.
Usage notes
Use a pie chart for a few shares of one total. With more than five or six shares, or when readers must compare values precisely, show a Table or a bar chart instead. Shares are drawn clockwise from the top in the order of data, so sort them in a way readers can follow.
The chart is one focus stop. Keyboard focus makes the first share active; the Left and Right arrow keys step through the shares and wrap around, Home and End jump to the first and the last share, and Escape closes the tooltip. A tap or pen press pins the share under it until the next press elsewhere or Escape. Screen readers meet the ring as a chart named by label and hear a hint that the arrow keys move between the data points. labels replaces the hint and the role description, for example with their translation. While the keyboard or a tap moves between the shares, a polite live region reads each share and its value. The legend names every share and reads its formatted value to screen readers, so the color never carries the information alone; without the legend, the same text describes the chart. A chart with nothing in it is not a focus stop, and emptyLabel describes it. Legend entries are not focus stops, and the legend does not toggle shares.
Nothing fades while a share is active: in the brand shades, a faded share would look like another one. With popOut, a share that steps out reaches up to 10 px beyond the box of the chart, so an ancestor that clips its overflow close to the chart cuts it off. A share that is the whole total has nowhere to step and stays in place.
The chart has no click or selection API. New data animates with the Motion tokens (--motion-duration-value and --motion-ease-standard). A share that pops out glides with the follow motion (--motion-duration-follow), and the tooltip card trails the share with --motion-duration-follow-trail. All of it is instant under reduced motion: the system setting, html with data-motion-reduce="true" or SiteplaneMotionProvider preset="reduced". The tooltip comes from Tooltip. The chart opens and closes it itself, so it needs no TooltipProvider, which only shares hover delays between tooltips.