Skip to content
Protocore Design Systemv1.6.9

/// Charts

PercentageBarChart

A single 100%-stacked horizontal distribution bar with sharp, tokened segments and a swatch/label/percent legend.

import { PercentageBarChart } from "@protocore/pds";
View as Markdown

Import path

PercentageBarChart ships from the `@protocore/pds/charts` subpath. Unlike the recharts wrappers it is hand-rolled SVG-free markup — no recharts dependency — so it is safe to render anywhere, but it is grouped with the charts family for its ramp and legend conventions.

import { PercentageBarChart } from "@protocore/pds/charts";
import { ChartContainer } from "@protocore/pds";

Basics

Pass data as an array of { label, value } segments. Values are normalised to their share of the total, so they need not sum to 100. Each segment is sharp (radius 0), hairline-separated, and coloured from the --pds-chart-N ramp; the legend beneath carries the label and a tabular percentage.

CI suite · last run

Signal colour + custom format

Override a segment's color to spend a signal hue on the part that matters — a red 5xx slice against grey 2xx/4xx. formatValue controls the printed percentage (here to one decimal).

Edge responses · 1h

When to use it

Use a PercentageBarChart to show a *single* whole split into parts along one row — status-class mix, pass/fail/skip, storage used vs free. It reads more precisely than a PieChart for near-equal shares and packs into a table cell or a stat row.

For a *value* progressing to a target (not a part-to-whole split) use a ProgressBar or RadialProgress; to compare a value across many categories use a BarChart.

Usage

Do

  • Use it for one whole split into a few labelled parts.
  • Let segments stay grey and spend a signal hue on the meaningful part.
  • Rely on the normalisation — pass raw counts, not pre-computed percentages.
  • Give each segment a readable `label` so the legend and aria summary are meaningful.

Don't

  • Don't use it to track a single value to a target — that's a ProgressBar.
  • Don't round the segments or add shadows; sharp geometry is the house style.
  • Don't pack in so many segments that the thin slivers become unreadable.
  • Don't rely on colour alone — the legend labels every segment.

Accessibility

  • The bar exposes `role="img"` with an aria-label composed from each segment's label and percentage (override via `label`).
  • Segment length encodes share independently of colour, so the distribution stays readable in grayscale and for colour-vision deficiencies.
  • The legend labels every segment with a tabular percentage for exact values.

PercentageBarChart props

PropTypeDefaultDescription
data *PercentageSegment[]Segments in draw + legend order (left to right). `PercentageSegment` = `{ key?: string; label?: ReactNode; value: number; color?: string }` — each segment's share of the summed total sets its width.
thicknessnumber12Bar thickness in px.
legendbooleantrueRender the swatch/label/percent legend beneath the bar.
formatValue(pct: number, segment: PercentageSegment) => stringtrimmed 0–1 decimal %Format a segment's percentage for display.
labelstringauto-composedAccessible summary of the distribution (role=img aria-label). Composed from segments when omitted.

Related

  • PieChartA monochrome-plus-signal pie chart with sharp sectors and a custom legend; DonutChart is the same wrapper with a ring cutout.
  • BarChartA monochrome-plus-signal bar chart with sharp (radius 0) bars capped at 24px, recharts-backed.
  • ProgressBarA thin track that fills to value/max, or sweeps indeterminately when value is omitted.
  • ChartLegendA compact swatch-and-label legend row: 8px squares with mono-UPPERCASE muted labels.