Skip to content

Components · Charts

StackedProportionBar

One horizontal bar split into proportions, with a legend of values and shares as a real list.

@rookcom/monarch-react/chartsComponent

Pipeline stages

  • New 1,240 · 60%
  • In a campaign 610 · 29%
  • Replied 182 · 9%
  • Converted 41 · 2%
  • Unsubscribed 6 · <1%

Usage examples

Storage capacity with a remainder

Status mode: monitors by state

Compact, legend for screen readers only

Purpose

Shows how one whole divides (pipeline stages, storage by type, monitors by state) in a single compact bar, with the numbers in a legend that also serves as the accessible version.

Use when

  • A breakdown inside a card or row where a donut would be too large.
  • Usage of a capacity (total larger than the parts, with a "Free" remainder).

Avoid when

  • One value against a target: use Progress (meter).
  • Ranking or comparing many parts: use BarList.
  • Breakdowns over time: use a stacked BarChart.

Design principles

  • The bar is decorative; the legend is a real list ("Replied 18 · 9%"), so nothing depends on colour.
  • Series colours come only from the data palette, in order or pinned. The one exception is status mode: when every segment is a state (operational, degraded, down), each takes a status tone from the intent tokens instead.
  • Palette and status colours never mix in one bar: the types reject it, and a mixed array from untyped code logs a development warning and falls back to the palette.
  • Small parts stay visible: segments have a minimum width and shares under 1% read "<1%".
  • Gaps separate neighbours, so adjacent segments never merge.

API reference

import { StackedProportionBar, formatShare } from '@rookcom/monarch-react/charts';
ExportKindRenderingRoot class
StackedProportionBarcomponentserver-safe.mn-color-success-solid
formatShareutilityserver-safe–

The ref and native attributes go to the root <div>.

formatShare(part, total, { locale, maximumFractionDigits }) is exported for the same "<1%" / ">99%" wording elsewhere.

Exported from @rookcom/monarch-react/charts; the legend is the shared chart legend (.mn-chart__legend).

Generated from the TypeScript declarations of packages/react/src/components/charts/stacked-proportion-bar.

Properties

Negative and non-finite values count as 0.

StackedProportionBar

One horizontal bar split into proportions (pipeline stages, storage by type, monitors by state) with a legend of values and shares. The bar is decorative; the legend is a real list, so the data never depends on colour.

PropTypeDescription
label requiredstringNames the legend list (the accessible version of the bar), e.g. "Lead pipeline" or "Storage".
segments requiredreadonly ProportionSegment[] | readonly ProportionStatusSegment[]The parts, in display order. Negative values are treated as 0. Either every segment uses the data palette (`color`, or none), or every segment has a status `tone` (status mode); the two never mix.
classNamestring
emptyLabelstringShown instead of the legend when every value is 0. Default "No data yet".
formatValueValueFormatterFormats values. Wins over `valueFormat`.
hideZerobooleanLeave segments with a value of 0 out of the bar and legend. Default `true`.
idstring
legendboolean`true` (default) shows the legend; `false` keeps it for assistive technology only, visually hidden.
legendContentProportionLegendContentWhat the legend shows after each label. Default `both` ("1,204 · 34%").
localestringBCP 47 locale for values and percentages.
minSegmentWidthstringNarrowest a non-zero segment is drawn, so tiny shares stay visible. Default `4px`.
percentDigitsnumberDecimal places in percentages. Default 0 (shares under 1% read "<1%").
remainderLabelstringLegend name for the empty remainder when `total` exceeds the sum, e.g. "Free". Omit to leave it out of the legend.
size"sm" | "md" | "lg"Bar thickness: `sm` 4px, `md` (default) 8px, `lg` 12px.
totalnumberThe size of the whole. Default: the sum of the segments. Set it larger for a capacity (storage, quota); the rest is drawn as empty track.
valueFormatIntl.NumberFormatOptions`Intl.NumberFormat` options for values.

Variants

PropValuesDescription
size'sm''md''lg'Bar thickness 4, 8 (default) or 12px (data-size).
legendContent'both''value''percent''none'What each legend entry shows after its label.
segment.tone (status mode)'success''warning''danger''info''neutral'Every segment gets an intent colour (--mn-color-<tone>-solid, neutral is --mn-color-text-subtle); the root has data-mode="status". All segments or none.
legend'true''false'false hides the legend visually but keeps it for assistive technology.

States

StateExposed asBehaviour
Remainderdata-remaindertotal above the sum leaves empty track; with remainderLabel it is listed in the legend.
Status modedata-mode="status"Every segment has a tone; segments carry data-tone and the legend swatches use the same intent colours.
Zero segments–Left out of the bar and legend unless hideZero={false}.
Emptydata-emptyEvery value 0: an empty track and emptyLabel ("No data yet").

Interaction behaviour

  • Hovering a segment shows its label, value and share as a native tooltip.

Keyboard support

Not interactive, so there is no keyboard behaviour.

Accessibility

Role
list (the legend)
Accessible name
label names the list, e.g. "Lead pipeline".
  • The bar is aria-hidden; every part is a list item with its label, value and share.
  • With legend={false} the list is visually hidden, not removed.
  • The empty state is announced with the label ("Lead pipeline: No data yet").
  • In forced-colours mode the track is outlined and segments are drawn in CanvasText, separated by gaps.

Responsive behaviour

  • The bar fills its container at any width; the legend wraps onto more lines.
  • Minimum segment widths can exceed the bar only with many tiny parts; the overflow is clipped.

Theme support

  • Segments use --mn-color-data-*, contrast-checked per theme; in status mode the -solid intent tokens. The track is --mn-color-bg-muted.
  • The remainder swatch matches the track, outlined with --mn-color-border-strong.

Do and don't

Do

  • Name the whole with label, and keep segment labels short.
  • Use total and remainderLabel for capacities so the empty part is explained.
  • Pin color when the same stages appear elsewhere on the page.
  • Use status mode only when every segment is a state, and keep a text label on each one (the legend or the hidden list always shows it).

Don't

  • Do not use status tones for categories that are not states (stages, file types): use the palette.
  • Do not mix tones and palette colours in one bar, or rely on the tone colour alone to say which state a part is.
  • Do not hide the legend unless the same numbers are visible nearby.
  • Do not use it for more than about six parts.
  • Progress: One value against a target, or a quota meter.
  • DonutChart: The same breakdown as a larger chart with a table.
  • BarList: Ranking parts against each other.

Dependencies

KindDepends on
npm packagesreact
Monarch componentsNone

Testing coverage

  • Legend list of non-zero parts with value and share; decorative bar; proportional flex sizes.
  • Palette colours by position and pinned slots; hideZero false.
  • Status mode: intent colours on segments and swatches, text legend; mixed arrays rejected by the types and warned about at runtime.
  • Capacity remainder with a named legend entry.
  • Legend content modes and the visually hidden legend.
  • "<1%" and ">99%" shares; formatShare edges.
  • Minimum width and size; empty state; negative and NaN values; ref; SSR.
CheckCovered
Axe in jsdomYes
Server renderingYes
Browser suitesVisual baselines: /__gallery/stacked-proportion-bar; Cross-browser axe: /components/stacked-proportion-bar

Tests: packages/react/src/components/charts/stacked-proportion-bar