Components / Decomposition Bar

Decomposition Bar

One quantity split into named parts that sum to it — a residual pool broken into reasons, a spend total broken by channel. Reach for it when the reading is "these are all of the same whole", never for progress toward a target.

import { DecompositionBar, type DecompositionSegment } from '@layers/ui/decomposition-bar'

Rendered stock

House rules

  • The parts must PARTITION the whole. A bar whose segments do not sum to the total states something the shape cannot support; use MeterList for independent measures.
  • Colour is magnitude, not identity: every part is one hue (--chart-series-1), stepped down in strength by rank, largest strongest, and a sixth part folds into a --muted-foreground tint. No part gets a hue of its own, so repainting on a data change is correct here. A hairline in --card cuts adjacent parts apart.
  • Segments keep the caller’s order along the track while the ramp follows size, so sequence and magnitude stay independent encodings.
  • It carries no labels, legend or total. Pair it with the table that names the parts; a 12px ribbon cannot hold text anyone can read.
  • hint is the evidence behind one part — the num/den, never a restatement of the label.
  • Zero-value parts are dropped, and a bar with nothing in it renders nothing rather than an empty track that would read as "all unaccounted for".

See also