Skip to main content
A pie chart is one 100% stacked bar bent around a circle: geom.bar({ position: 'fill' }) under coord.polar({ theta: 'y' }). Each slice’s angle is proportional to its value. Add an innerRadius and it becomes a donut, a pie with the center cut out. Both work best for a few parts of a whole.

Pie

Map the slice category to color, the value to y, and leave x empty so all slices share one band:

Donut

A donut is the same recipe with an innerRadius on the polar coord. The hole leaves room for a headline number, and a thin band can read more cleanly than a full pie:
innerRadius is a fraction of the outer radius; 0.55 cuts the hole just past halfway. Larger values give a thinner band. The hole is the natural home for a headline number:
position: 'center' needs a non-zero innerRadius; a full pie has no hole to sit in.

Where the first slice starts

coord.polar takes a startAngle in degrees, 0 by default. It rotates the whole pie, which is how you put the largest slice at a chosen clock position:

Slice labels

Turn on data labels to print each slice’s value or share. On polar bars, showCategoryLabels prefixes the category:

Separated wedges

A border in the chart’s background color leaves a crisp gap between wedges. Borders are paint, so they come from the stylesheet:
The border is the only way to do this. Every slice is a segment of one stacked bar, so the segments meet edge to edge and there is no band gap to widen.

Rounded wedges

Wedges take the bar geom’s cornerRadius, a named token the polar renderer sizes against each wedge’s radial span. The default is 'sm', so wedge corners are already slightly rounded: