# Pie and donut charts

> Pies, donuts and gauges with pieChart(), from the data shape to label placement, slice colors and half-circle gauges.

A pie shows parts of a whole. `pieChart()` draws one slice per value, sized by its share of the total, and turns into a donut or a gauge with a few options. Pies work best with a handful of slices. If you're comparing more than five or six values, a [bar chart](https://chartist.dev/docs/bar-charts/) is easier to read.

## Your first pie

A pie takes a flat series: one array of numbers, not an array of arrays. The labels are optional and go on the slices in the same order:

**A one-hour meeting** (runs in the browser):

`src/main.ts`:

```ts
import 'chartist/styles.css';
import './style.css';
import { pieChart } from 'chartist';

// Where the minutes of a one-hour meeting go.
pieChart('#chart', {
  labels: ['Agenda', 'Small talk', 'Decisions', 'Coffee'],
  series: [10, 25, 5, 20]
});
```

`src/style.css`:

```css
/* Labels on colored slices read best in white. */
#chart {
  --ct-label-color: #fff;
}
```

`index.html`:

```html
<!doctype html>
<html>
  <head>
    <meta charset="UTF-8" />
    <script type="module" src="/src/main.ts"></script>
  </head>
  <body>
    <div id="chart" class="ct-golden-section"></div>
  </body>
</html>
```

Every value becomes its own series group, `ct-series-a`, `ct-series-b` and so on, so every slice gets its own color from the stylesheet. Leave out the labels and the slices show their values instead.

The white labels are one line of CSS, `--ct-label-color: #fff` in `src/style.css`: the default label color is a translucent black, made for axes on a light background. Labels [outside the pie](#labels) keep it.

## Donuts

Set `donut: true` and the slices become arcs of a ring. The stylesheet sets how thick it is, 60 px by default: change it with `--ct-donut-width` in CSS, for the page, a container or one chart. The chart lays the ring out for that width, so it still fits the chart's edge.

**Donut** (runs in the browser):

`src/main.ts`:

```ts
import 'chartist/styles.css';
import './style.css';
import { pieChart } from 'chartist';

pieChart(
  '#chart',
  {
    labels: ['Agenda', 'Small talk', 'Decisions', 'Coffee'],
    series: [10, 25, 5, 20]
  },
  { donut: true }
);
```

`src/style.css`:

```css
/* Labels on colored slices read best in white, and the ring is 40 px. */
#chart {
  --ct-label-color: #fff;
  --ct-donut-width: 40px;
}
```

`index.html`:

```html
<!doctype html>
<html>
  <head>
    <meta charset="UTF-8" />
    <script type="module" src="/src/main.ts"></script>
  </head>
  <body>
    <div id="chart" class="ct-golden-section"></div>
  </body>
</html>
```

A donut's SVG gets `ct-chart-donut` instead of `ct-chart-pie`, and its slices are `ct-slice-donut` paths drawn with a stroke, not a fill. Labels sit in the middle of the ring; `labelPosition` and `labelOffset` move them as on a pie.

> **The width comes from CSS, or from `donutWidth`.** The chart reads the width
> the stylesheet gives a slice on every render, so `--ct-donut-width: 30px` on a
> container and a 1.x rule like `.ct-slice-donut { stroke-width: 30px }` both
> work. Only px widths count: a percentage in CSS is laid out as 60 px. After a
> CSS change that doesn't resize the chart, such as a theme switch, call
> `update()`. Set `donutWidth` where there's no stylesheet to read: with
> `renderToString()` the ring is laid out for 60 px, and without the Chartist
> stylesheet it gets the browser's 1px stroke. `donutWidth` takes px or a
> percentage of the radius, like `'30%'`, and is written as an inline
> `stroke-width` that wins over the stylesheet. 1.x code that sets it keeps
> working.

## Gauges

Two options turn a donut into a gauge. `startAngle` is where the first slice starts, in degrees: `0` points up and the slices run clockwise. `total` fixes the value of a full circle; without it, the slices always add up to one. When your values sum to less than `total`, part of the circle stays empty.

Start at `270` (the left side) and make the total twice the sum, and the slices fill the upper half:

**Sprint gauge** (runs in the browser):

`src/main.ts`:

```ts
import 'chartist/styles.css';
import './style.css';
import { pieChart } from 'chartist';

// Story points of a sprint: done, in progress, to do. The total is
// twice their sum, so together they fill half the circle.
pieChart(
  '#chart',
  { series: [12, 5, 3] },
  {
    donut: true,
    startAngle: 270,
    total: 40,
    showLabel: false
  }
);
```

`src/style.css`:

```css
/* A 40 px ring. */
#chart {
  --ct-donut-width: 40px;
}
```

`index.html`:

```html
<!doctype html>
<html>
  <head>
    <meta charset="UTF-8" />
    <script type="module" src="/src/main.ts"></script>
  </head>
  <body>
    <div id="chart" class="ct-golden-section"></div>
  </body>
</html>
```

Gauges usually go without slice labels, so this one sets `showLabel: false`. A single-value gauge works the same way: `{ series: [72] }` with `total: 200` fills a little more than a third of the circle.

## Labels

By default, labels sit halfway between the center and the edge of the slice, or in the middle of a donut's ring. Four options move them:

| Option           | Default     | What it does                                                                                                                                  |
| ---------------- | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| `showLabel`      | `true`      | Draws the labels at all                                                                                                                       |
| `labelPosition`  | `'inside'`  | `'inside'` (half the radius, or the middle of the ring), `'outside'` (on the outer edge) or `'center'` (the center point, plus `labelOffset`) |
| `labelOffset`    | `0`         | Px added to that distance from the center; negative values move labels inward                                                                 |
| `labelDirection` | `'neutral'` | `'explode'` anchors labels so the text grows away from the center, `'implode'` toward it; `'neutral'` centers it                              |

Labels outside the pie need room, so give the chart some `chartPadding` (the pie's default is `5`):

**Labels outside** (runs in the browser):

`src/main.ts`:

```ts
import 'chartist/styles.css';
import { pieChart } from 'chartist';

pieChart(
  '#chart',
  {
    labels: ['Agenda', 'Small talk', 'Decisions', 'Coffee'],
    series: [10, 25, 5, 20]
  },
  {
    labelPosition: 'outside',
    labelOffset: 16,
    labelDirection: 'explode',
    chartPadding: 30
  }
);
```

`index.html`:

```html
<!doctype html>
<html>
  <head>
    <meta charset="UTF-8" />
    <script type="module" src="/src/main.ts"></script>
  </head>
  <body>
    <div id="chart" class="ct-golden-section"></div>
  </body>
</html>
```

### Label text

`labelInterpolationFnc` gets each slice's label (or its value, when there are no labels) and its index, and returns the text to show. Return `null` to leave a slice without a label:

```ts
import 'chartist/styles.css';
import { pieChart } from 'chartist';

const series = [10, 25, 5, 20];
const total = series.reduce((sum, value) => sum + value, 0);

pieChart(
  '#chart',
  { series },
  {
    // 17%, 42% and 33%; the 8% slice stays unlabeled.
    labelInterpolationFnc: value => {
      const percent = Math.round((Number(value) / total) * 100);
      return percent < 10 ? null : `${percent}%`;
    }
  }
);
```

Small slices crowd their labels. `preventOverlappingLabelOffset` is a px step: when a label would overlap one drawn before it, it moves up and to the left by that step until it doesn't.

## Slices with names and colors

A value can also be an object. `className` replaces the slice's letter class, so you pick its color in CSS. `name` and `meta` end up in the SVG as `ct:series-name` and `ct:meta` attributes, for plugins and your own scripts:

```ts
import 'chartist/styles.css';
import { pieChart } from 'chartist';

pieChart('#chart', {
  labels: ['Yes', 'No'],
  series: [
    { value: 62, className: 'vote-yes' },
    { value: 38, className: 'vote-no' }
  ]
});
```

```css
.vote-yes {
  --ct-color: #59922b;
}
.vote-no {
  --ct-color: #d70206;
}
```

More on series colors in [Styling with CSS](https://chartist.dev/docs/styling-with-css/#one-color-per-series).

A `0` still gets a label and a sliver of a slice. Set `ignoreEmptyValues: true` to skip both.

In the API reference: [`pieChart`](https://chartist.dev/api/charts/#pieChart) and [its options](https://chartist.dev/api/charts/#PieChartPresetOptions).

Next: [put bars and a line on one chart](https://chartist.dev/docs/composed-charts/), or [make the pie respond to its container](https://chartist.dev/docs/responsive/).
