# Pie chart

> Parts of a whole drawn as slices from a data table, as a pie or a donut with its total.

## Anatomy

A `<figure class="pie-chart">` draws a `<table>` of parts as slices of a whole. The first column of the table names each part and the second holds its value.

It takes the same markup as a [column chart](column-chart.html). Slices run clockwise from the top in table order, so put the largest part first. A legend lists every row with its cell and its share of the total. A tooltip follows the pointer round the pie, and the arrow keys move it when the chart has focus. Keep a pie to about five parts. For more, or to compare parts that are close in size, use a [bar chart](bar-chart.html).

```
<figure class="pie-chart">
  <figcaption>Revenue by plan, 2026</figcaption>
  <table>
    <thead>
      <tr><th>Plan</th><th>Revenue</th></tr>
    </thead>
    <tbody>
      <tr><th>Basic plan</th><td>$25,864</td></tr>
      <tr><th>Premium plan</th><td>$14,258</td></tr>
      <tr><th>Enterprise plan</th><td>$5,258</td></tr>
    </tbody>
  </table>
</figure>
```

The legend and tooltip show each cell's text as written, so format values in the table. The chart works out the shares from the numbers.

## Donut

Add `donut` to cut a hole in the middle. A `<tfoot>` row holds the total. Its value and label show in the hole, and the chart does not draw it as a slice. Write the total yourself, formatted as you want it read.

```
<figure class="pie-chart donut">
  <figcaption>Lead sources, last six months</figcaption>
  <table>
    <thead>
      <tr><th>Source</th><th>Leads</th></tr>
    </thead>
    <tbody>
      <tr><th>Referrals</th><td>558</td></tr>
      <tr><th>Organic search</th><td>434</td></tr>
      <tr><th>Paid campaigns</th><td>248</td></tr>
    </tbody>
    <tfoot>
      <tr><th>Total leads</th><td>1,240</td></tr>
    </tfoot>
  </table>
</figure>
```

## Values

Add `values` to write each slice's share on it, in the slice color's on-color. Slices under 5% are too thin for a label. The legend still shows their share.

```
<figure class="pie-chart donut values">
  <figcaption>Top revenue sources</figcaption>
  <table>
    <thead>
      <tr><th>Source</th><th>Revenue</th></tr>
    </thead>
    <tbody>
      <tr><th>Enterprise clients</th><td data-value="38000000">$38M</td></tr>
      <tr><th>Referral partners</th><td data-value="10900000">$10.9M</td></tr>
      <!-- One row per source -->
    </tbody>
    <tfoot>
      <tr><th>Total client revenue</th><td>$63.1M</td></tr>
    </tfoot>
  </table>
</figure>
```

## Labels

Add `labels` to write each slice's name outside it, so a reader can match slices to parts without the legend. Names on the right half run rightwards and those on the left run leftwards. Neighbours that would touch move apart, away from the middle. A line from each name back to its slice shows which slice a moved name belongs to. The pie shrinks to leave `--md-comp-pie-chart-label-width` on each side, or a quarter of a narrow figure. Longer names get cut short with an ellipsis. Combine it with `values` to show the shares too.

```
<figure class="pie-chart donut values labels">
  <figcaption>Leads by source</figcaption>
  <table>
    <!-- The same table as above -->
  </table>
</figure>
```

## Small parts

Set `data-other` to a percentage to group every row under that share of the whole into one slice. The group comes last, so thin slices do not crowd the pie or push their names into the caption. It shows the rows' sum and share. The sum keeps the cells' currency and decimals, and is compact when they use `data-value`. Further columns do not add up, so the group shows no sum for them. Set `data-other-label` to name the group. It defaults to "Other". A single small row keeps its own slice, and the table keeps every row for screen readers.

```
<figure class="pie-chart labels" data-other="5">
  <figcaption>Visits by channel</figcaption>
  <table>
    <thead>
      <tr><th>Channel</th><th>Visits</th></tr>
    </thead>
    <tbody>
      <tr><th>Search</th><td>4,210</td></tr>
      <tr><th>Email</th><td>310</td></tr>
      <!-- One row per channel; those under 5% become "Other" -->
    </tbody>
  </table>
</figure>
```

## More columns

The slices come from the first value column. Further columns add lines to the tooltip, such as a change from last year, and stay in the table for screen readers.

```
<figure class="pie-chart">
  <figcaption>Revenue by plan, with change</figcaption>
  <table>
    <thead>
      <tr><th>Plan</th><th>Revenue</th><th>Change</th></tr>
    </thead>
    <tbody>
      <tr><th>Basic plan</th><td>$25,864</td><td>+10%</td></tr>
      <!-- One row per plan -->
    </tbody>
  </table>
</figure>
```

## Chart cards

Put a chart in a card with the figures it explains. The card adds no chart styles. Size the pie with `--md-comp-pie-chart-height`, which sets its diameter.

```
<article class="outlined">
  <div class="p-4">
    <dl class="stats my-0">
      <div>
        <dt>Total revenue</dt>
        <dd>$45,380</dd>
        <dd class="stat-change up">+10% from last year</dd>
      </div>
    </dl>
    <figure class="pie-chart donut" style="--md-comp-pie-chart-height: 200px">
      <figcaption class="visually-hidden">Revenue by plan</figcaption>
      <table><!-- … --></table>
    </figure>
  </div>
</article>
```

Use `sparkline` for a small pie beside a figure that already explains it. It is a 48px pie with no legend or tooltip.

## Values and colors

Cells read the same way as in a column chart. A cell's number is its `data-value`, or its text without currency signs, percent signs or grouping commas. Text that is not a single number, such as "$38M" without a `data-value`, counts as nothing. So do zero and negative values. Their rows stay in the legend and the tooltip with no slice and no share. A chart whose cells are all gaps shows its table.

Slices take `primary`, `tertiary`, `secondary`, `on-surface-variant`, and then `primary-container` and `tertiary-container` mixed with `on-surface`, in turn. The mix keeps every slice at 3:1 or more against the surface in light and dark themes. A seventh row would take the first row's color beside it, so it takes the second. Past that, the colors repeat. Group small parts into one "Other" row instead.

## Accessibility

The table is the chart's text alternative. Give it a header row and a header cell per row, and name the chart with a `<figcaption>`. The chart hides the drawn pie, values, total and legend from assistive technology.

The plot is one Tab stop, named by the caption. The arrow keys move round the pie. Right and down go to the next row, and left and up go to the one before. Past the last row they go on to the first. Home and End jump to the first and last rows, and Escape hides the tooltip. On a touch screen, tap a slice to show it. In a right-to-left page the slices still run clockwise, and so do the arrows. The tooltip is a polite live region, so a screen reader hears each row's values and share as it moves. A sparkline is not focusable. In forced colors the slices keep their colors so the legend still keys them.

## JavaScript

`AutoInit()` starts every `.pie-chart`. To start one yourself, call `PieChart.init`. After changing its table, call `update()` to redraw it in place, or add `data-watch` to the figure so it redraws itself. It has the line chart's methods. The `min` and `max` options do not apply.

```
const chart = Expressive.PieChart.init(document.querySelector('.pie-chart'));
chart.show(2);   // highlight the third row; -1 hides the tooltip
chart.update();  // redraw from the table; focus and the highlighted row stay
chart.destroy(); // remove the drawing and show the table again
```

## Tokens

Override these on the `.pie-chart`.

| Token | Default |
| --- | --- |
| `--md-comp-pie-chart-height` | 240px, the pie's diameter; 48px for a sparkline |
| `--md-comp-pie-chart-hole` | 0.6, the donut hole's share of the diameter |
| `--md-comp-pie-chart-label-width` | 96px, the room on each side of the pie for `labels`, at most a quarter of the figure's width |
| `--md-comp-pie-chart-gap` | 1.5, the gap between slices in hundredths of the plot's width |
| `--md-comp-pie-chart-color-1` … `-4` | `primary`, `tertiary`, `secondary`, `on-surface-variant` |
| `--md-comp-pie-chart-color-5`, `-6` | `primary-container`, `tertiary-container`, each mixed 45% with `on-surface` |
| `--md-comp-pie-chart-on-color-1` … `-6` | `on-primary`, `on-tertiary`, `on-secondary`, `surface`, `surface`, `surface`; text from `values` |

For a selective Sass build, include `"pie-chart"` in `$components`.
