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 centre cut out. Both work best for a small number of parts of a whole.
Pie
Map the slice category tocolor, the value to y, and leave x empty so all slices share one band:
Donut
A donut is the same recipe with aninnerRadius on the polar coord. The hole leaves room for a headline number, and the thinner ring can read more cleanly than a full pie:
innerRadius is a fraction of the outer radius — 0.55 cuts the hole just past the halfway point. Larger values give a thinner ring. The hole is the natural home for a headline number:
position: 'center' needs a non-zero innerRadius — on a full pie there is no hole to sit in.
Where the first slice starts
coord.polar takes a startAngle in degrees, defaulting to 0. It rotates the whole ring, which is how you put a dominant slice at a particular 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:Rounded wedges
Wedges carry the bar geom’sborderRadius, a named token the polar renderer resolves against each wedge’s radial span. The built-in default is 'sm', so wedge corners are already slightly softened:
Related
- Styling — the stylesheet, its cascade and every target
- Headline numbers — a metric in the donut’s hole
- Radar & radial — the
theta: 'x'polar charts - Coordinate systems — the polar plane,
theta,startAngleandinnerRadius

