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 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:
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]
});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 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.
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 }
);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.
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:
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
}
);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):
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
}
);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:
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:
import 'chartist/styles.css';
import { pieChart } from 'chartist';
pieChart('#chart', {
labels: ['Yes', 'No'],
series: [
{ value: 62, className: 'vote-yes' },
{ value: 38, className: 'vote-no' }
]
});
.vote-yes {
--ct-color: #59922b;
}
.vote-no {
--ct-color: #d70206;
}
More on series colors in Styling with CSS.
A 0 still gets a label and a sliver of a slice. Set ignoreEmptyValues: true to skip both.
In the API reference: pieChart and its options.
Next: put bars and a line on one chart, or make the pie respond to its container.