Skip to content
GitSiteEmail

A Chart.Pie with the middle cut out. Use the empty center to show a total, the selected value, or custom content.

All pie features — data model, palette, animation, interactivity, legend, and tooltips — work the same way. This page only covers the donut-specific behavior.

import Chart from '@components/Feedback/Chart/Chart';
import { createSignal } from 'solid-js';
const App = () => {
const [stats, setStats] = createSignal([
{
label: 'Loadout',
points: [
{ type: 'strength', value: 13 },
{ type: 'agility', value: 9 },
{ type: 'stamina', value: 16 },
{ type: 'intellect', value: 6 },
],
},
]);
return (
<Chart.Donut data={stats()} interactive>
<Chart.Labels placement="hole" />
<Chart.Legend position="bottom" />
</Chart.Donut>
);
};

innerRadius accepts either a ratio of the outer radius or a pixel value. The default is '60%'.

<Chart.Donut data={stats()} innerRadius="40%" /> {/* thicker ring */}
<Chart.Donut data={stats()} innerRadius={48} /> {/* 48px */}

The value is clamped to [0, outerRadius], so an oversized value flattens the ring instead of creating an inverted shape. An innerRadius of 0 behaves like a pie chart.

There are two ways to populate the center, and they can be combined.

Chart.Labels placement="hole" renders a derived value: the total of the visible slices, or the hovered slice’s value and label while the pointer is on the ring.

<Chart.Donut data={stats()} interactive>
<Chart.Labels placement="hole" format={(point) => `${point.value} pts`} />
</Chart.Donut>

Chart.Donut.Hole takes over the center completely. Its children replace the derived label content.

<Chart.Donut data={stats()}>
<Chart.Donut.Hole>
<Image src={crest} />
</Chart.Donut.Hole>
</Chart.Donut>

If you leave Chart.Donut.Hole empty, you can style the container while Chart.Labels supplies the content. The slot is the frame; the labels are what go inside it.

<Chart.Donut data={stats()} interactive>
<Chart.Donut.Hole class="my-hole-frame" />
<Chart.Labels placement="hole" />
</Chart.Donut>

The hole container matches the inner circle and has pointer-events: none, so anything inside it does not block hover interactions on the ring beneath it.

Identical to Chart.Pie, plus:

Prop NameTypeDefaultDescription
innerRadiusChartLength'60%'Hole size as either a length ('3rem') or a share of the outer radius ('60%'). Clamped to the outer radius.
  • The hole shows the total of the visible slices. Hiding a slice from the legend removes it from the total.
  • During animation, the total is mid-tween, so it is displayed with one decimal place until it settles.
  • Everything else behaves the same as a pie: negatives are treated as zero, missing categories count as zero, and extra series are ignored.
Prop NameTypeDefaultDescription
classstring""CSS classes applied to every slice.
styleJSX.CSSProperties{}Inline styles applied to every slice.
padAnglenumber0Degrees of gap between slices.
cornerRadiusChartLength0Rounds the slice corners.
hoverOffsetChartLength0How far the hovered slice pops outward. Requires interactive.
Prop NameTypeDefaultDescription
classstring""CSS classes applied to the hole container.
styleJSX.CSSProperties{}Inline styles applied to the hole container.
childrenJSX.ElementundefinedContent for the hole. Replaces anything Chart.Labels placement="hole" would render.

Shared with every chart type. See Shared slots for their props.

Chart.Labels supports the same placements as a pie, plus one more:

placementEffect
'hole'Renders the total, or the hovered slice’s value and label, in the middle of the ring. The slot’s class and style apply to the hole container.