Pie Chart | kamod chartsSkip to content

Charts

Pie Chart

Show parts of a whole with pie, donut, rose, and labeled slice layouts.

Charts / Pie Chart

Donut via innerRadiusLegend togglesRose / NightingaleOutside labels

Overview

Traffic sourcesShare of visits by acquisition channel with legend toggles and slice tooltips.
Visits
100k
import { PieChart } from "@kamod-ch/charts/pie";

PieChart renders proportional slices from a single value column. Use innerRadius for donuts, rose for equal-angle Nightingale layouts, and labels="outside" when category names need gutter space with leader lines.

API notes

Typed PieChart props — innerRadius for donuts, rose for equal-angle layouts, and pie-specific tooltip and legend options.

Value policy
Only finite values strictly greater than zero render as slices. Non-finite, zero, or negative entries resolve to 0 and are omitted from geometry, navigation, and tooltips. When every value is non-positive, pass emptyContent for a custom fallback.
Percentages
PieSliceContext.percentage is the slice value divided by the sum of visible slices. Legend toggles remove hidden keys from that total, so percentages in tooltips and announcements stay consistent with what is on screen.
innerRadius (donut)
Set innerRadius to any pixel value greater than zero to open a donut hole. Pair with centerContent for KPI summaries. There is no separate donut prop — radius controls the shape.
Pie vs rose
A standard pie maps value to angle. Rose (Nightingale) charts keep equal angles and map value to radius via rose. Default scaling is sqrt, which compresses outliers so small categories stay readable; use scale: "linear" only when proportional radius is intentional.
Outside labels
labels="outside" enables leader lines and defaults collision: "shift". Tune PieLabelLineOptions for radial and horizontal segments, or pass a full PieLabelOptions object for minAngle, custom render, and collision: "hide".
Legend & tooltip
showLegend renders slice toggles keyed by stable slice key. Set legend.interactive to false for a read-only legend. tooltip defaults to off; true shows value and percentage via PieTooltipOptions.
Color & categories
Do not rely on slice color alone — pair fills with labels, legend text, and tooltips. Pie charts work best for roughly three to six categories; beyond that prefer a BarChart or a sorted table for exact comparisons.
Locale formatting
Use Intl.NumberFormat in formatValue or formatPercentage on PieTooltipOptions (see the Basic example). Slice labels accept the same formatters through PieLabelOptions.render.

Six functional patterns covering legend tooltips, donuts, center KPIs, rose geometry, outside labels, and a carrier capacity snapshot. Each preview uses Kamod’s real PieChart API — no copied option objects.

Basic pie with legend and tooltip

Inside labels, an interactive legend, and tooltips that show raw value plus share of visible slices. Percentages update when legend items hide segments.

showLegendtooltipIntl
Regional parcel shareLegend toggles and tooltips use Intl.NumberFormat for values and percents.

Donut via innerRadius

Set innerRadius to open the hole — there is no separate donut prop. Outside labels leave gutter space automatically.

innerRadiuslabels
Acquisition mixDonut layout using innerRadius with outside category labels.

Donut with center KPI

centerContent renders Preact children in the hole — useful for totals, units, or status text without extra SVG markup.

centerContentinnerRadius
Visit mix with totalCenter KPI summarizes the whole while legend and tooltip carry per-channel detail.
Total visits
100k

Rose (Nightingale) chart

Equal slice angles with value mapped to radius. Default sqrt scaling keeps small regions visible; angle no longer encodes magnitude.

rosesqrt
Regional parcel volumesRose layout: equal angles, sqrt-scaled radii. Compare category size by radius, not arc width.

Outside labels with leader lines

Leader lines connect slices to gutter labels. collision: shift nudges overlapping labels vertically; narrow slices respect minAngle.

labelscollisionleader lines

Resize horizontally — gutter labels shift to avoid overlap.

Dense channel mixOutside labels with collision shift and configurable leader lines.

Carrier capacity donut

Operational snapshot: allocated lanes versus remaining headroom. Pair color with labels and a center KPI so utilization is readable without hue alone.

centerContenttooltipdomain
Hub capacity this weekAllocated, available, and maintenance hold parcels across the network hub.
Utilized
79.8%
of 9.8K

Keyboard and screen reader behavior

  • Focus the chart SVG and use Arrow keys to move between visible slices; Home and End jump to the first and last slice.
  • Enter or Space activates the focused slice; Escape clears the active slice without moving focus.
  • Tooltips follow pointer hover; keyboard selection announces value and percentage through a live region.
  • Legend buttons toggle visibility without adding extra tab stops inside the SVG.
  • Prefer title and description text that states the metric and unit — do not rely on slice color alone.

Props

PieChart props
PropTypeDefaultDescription
valueKeyDataAccessor<TDatum, number | null | undefined>—Numeric value for each slice. Only finite values strictly greater than zero render as slices.
labelKeyDataAccessor<TDatum, string | number | null | undefined>—Label accessor for slices, legend items, and tooltips.
innerRadiusnumber0Inner radius in pixels. Values above zero create a donut hole; pair with centerContent for KPI summaries.
outerRadiusnumber—Outer radius in pixels. Defaults to the available plot size; outside labels auto-shrink the radius to leave gutter space.
padAnglenumber—Gap between adjacent slices in radians.
cornerRadiusnumber—Rounded outer corners for slice arcs.
sortboolean | PieSortComparator<TDatum>falseWhen true, sorts slices by descending value. Pass a comparator for custom ordering.
labelsPieLabelPosition | PieLabelOptions<TDatum>"inside"Shorthand: "none", "inside", or "outside". Outside enables leader lines and defaults collision to shift.
roseboolean | PieRoseOptions—Nightingale layout: equal slice angles with value mapped to radius. Default scale is sqrt when rose is true.
colorsreadonly string[]—Explicit palette for slices. Colors stay stable by original data index.
centerContentComponentChildren—Content rendered in the donut hole when innerRadius is set.
emptyContentComponentChildren—Fallback when data exists but no slice has a finite value greater than zero, or when every slice is hidden via legend.
activeOffsetnumber6Pixel expansion applied to the active slice outer radius on pointer or keyboard focus.
tooltipboolean | PieTooltipOptions<TDatum>falsePointer and keyboard tooltips for the active slice. true uses default value and percentage formatting.
showLegendbooleanfalseRender an HTML legend with per-slice visibility toggles keyed by stable slice keys.
legendPieLegendOptions—Legend behavior. interactive defaults to true for segment toggling.
onSegmentClick(datum, index, value) => void—Called when a slice is activated with pointer click or keyboard Enter/Space.
animateboolean | ChartAnimateOptions—Optional data animation. No-op on the static donut entry unless MotionConfig is present.

PieSliceContext

Passed to tooltip.render, tooltip.formatValue, tooltip.formatPercentage, and PieLabelOptions.render.

PieSliceContext fields
PropTypeDefaultDescription
datumTDatum—Original data row for the slice.
indexnumber—Row index in the source data array.
keystring—Stable identifier used for legend toggles and React/Preact keys.
labelstring—Resolved display label for the slice.
valuenumber—Normalized slice value (finite and greater than zero).
totalnumber—Sum of visible slice values; used for percentage calculation.
percentagenumber—Slice value as a percentage of total visible slices (0–100).
colorstring—Resolved fill color for the slice.
startAngle / endAnglenumber—Slice arc bounds in radians.
innerRadius / outerRadiusnumber—Resolved radii for the slice, including activeOffset when active.
activeboolean—True when the slice is keyboard- or pointer-selected.

PieTooltipOptions

Chart-level via tooltip. Defaults show numeric value and percentage of visible slices.

PieTooltipOptions fields
PropTypeDefaultDescription
placementTooltipPlacement—Tooltip placement relative to the slice anchor.
offsetnumber—Pixel gap between the anchor and tooltip content.
render(context: PieSliceContext<TDatum>) => ComponentChildren—Fully custom tooltip body. Receives the active slice context.
formatValue(value, context) => ComponentChildren | null | undefined—Format the numeric value. Return null to fall back to the default string.
formatPercentage(percentage, context) => ComponentChildren | null | undefined—Format the percentage (0–100). Return null to fall back to one decimal place with a percent sign.

PieLabelOptions

Chart-level via labels when not using the "inside" | "outside" | "none" shorthand.

PieLabelOptions fields
PropTypeDefaultDescription
position"none" | "inside" | "outside""inside"Label placement. outside draws leader lines to gutter labels.
render(context: PieSliceContext<TDatum>) => ComponentChildren | null | undefined—Custom label content per slice.
minAnglenumber—Minimum slice span in degrees required to show a label and leader line.
collision"none" | "shift" | "hide"—Outside-label overlap strategy. Defaults to shift for outside placement.
linePieLabelLineOptions—Leader line geometry and styling for outside labels.
offsetnumber—Pixel gap between the leader line elbow and label text.
color / classstring—SVG fill color or class for label text.

PieLabelLineOptions

Nested under PieLabelOptions.line for outside placement.

PieLabelLineOptions fields
PropTypeDefaultDescription
lengthnumber—Radial segment length from the slice outer edge to the elbow.
horizontalLengthnumber—Horizontal segment length from the elbow to the label anchor.
colorstring—Stroke color for leader lines.
strokeWidthnumber—Stroke width for leader lines.
classstring—Optional class applied to leader line paths.

PieRoseOptions

Nested under rose when not passing rose={true}.

PieRoseOptions fields
PropTypeDefaultDescription
scale"sqrt" | "linear""sqrt"How slice values map to radius. sqrt compresses large outliers; linear is proportional.
minRadiusnumber—Minimum outer radius for the smallest visible slice. Defaults to innerRadius plus 8% of the radius span.

PieLegendOptions

Nested under legend. Legend items key off stable slice key values from the data row index.

PieLegendOptions fields
PropTypeDefaultDescription
interactivebooleantrueWhen true, legend items toggle slice visibility. Hidden slices are excluded from totals and navigation.

Value policy and percentages

  • Only finite values strictly greater than zero become slices. Zero, negative, and non-finite entries are treated as non-visible.
  • When every value is non-positive, render emptyContent instead of an blank chart.
  • PieSliceContext.percentage divides each visible slice by the sum of currently visible slices. Legend toggles remove hidden keys from that total, so tooltips and announcements stay aligned with what is on screen.
  • activeOffset expands the active slice radius on pointer hover or keyboard focus (default 6 px).

Pie vs rose and when to pick another chart

| Layout | Angle | Radius | Best for | | ------------- | --------------------- | ----------------------------- | ------------------------------------------------------------ | | Standard pie | proportional to value | fixed (minus donut hole) | three to six categories, familiar part-to-whole | | Rose (rose) | equal per category | proportional (sqrt default) | many categories where small values would vanish as thin arcs | | Bar / table | — | — | more than ~six categories or when exact rank order matters |

Rose charts default to sqrt scaling so one large category does not swallow the plot; use scale: "linear" only when radius should track value linearly.

Do not use color as the only signal — pair fills with labels, legend text, tooltips, or explicit description copy. For dense comparisons, prefer Bar Chart or a sorted table.

Donut and empty states

Set innerRadius to any pixel value above zero to open a donut hole. centerContent accepts Preact children for KPIs or status text. There is no separate donut boolean. For ratio-based rings, semicircles, and automatic center totals, see Donut Chart.

When all slices are hidden through the legend, the chart shows emptyContent while the legend remains so users can restore segments.