Data viz
Cumulative flow
A stacked area of how many items sit in each status over time — the CFD. The width of each colored band is the work-in-progress at that stage, so a widening band reveals a bottleneck and a steepening Done edge shows throughput. Hover any day for the breakdown. Built on the shared Orbit chart scaffolding.
npx shadcn@latest add @orbit/cumulative-flow-chartOverview
Switch the range, hover a day for the per-status counts, or hover a legend entry to isolate its band.
Reading it
The vertical thickness of a band at any day is the count in that status. Read the shapes, not just the lines.
Controlled
Hide the built-in range toggle with showRangeToggle={false} and drive the window from outside via range + onRangeChange.
range=14Custom bands
Bands are entities: pass your own workflow (bottom band first) and each status keeps its color everywhere it appears. Fold long tails before charting — five or six bands stay legible.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| data | Record<string, number>[] | — | Daily counts keyed by band key, oldest first. The active range shows the last N days. |
| bands | { key: string; label: string; color: string }[] | CUMULATIVE_FLOW_BANDS | Stacking order, bottom band first. Defaults to Done / In review / In progress / Todo / Backlog with tokenized status colors. |
| ranges | number[] | [14, 30, 60] | Day counts offered by the range toggle. |
| range | number | — | Controlled range (days shown). Pair with onRangeChange. |
| defaultRange | number | 30 | Uncontrolled initial range. |
| onRangeChange | (range) => void | — | Fires when the range toggle (or a controlled parent) changes the window. |
| title | string | "Cumulative flow" | Card heading. |
| subtitle | string | — | Overrides the “Items in each status over the last N days” subtitle. |
| height | number | 300 | Plot height in px. Width is responsive. |
| showRangeToggle | boolean | true | Range toggle in the header. |
| showLegend | boolean | true | Bordered legend row with the latest counts; hover / focus isolates a band. |
| formatDay | (index: number) => string | — | Axis and tooltip day label. Defaults to “D5” on the axis, “Day 5” in the tooltip. |
| ariaLabel | string | — | Plain-language summary for the chart's role=“img”. |
| …rest | HTMLAttributes<HTMLDivElement> | — | Forwarded to the root card, including ref and className. |
Usage
Use a CFD to watch flow and WIP across statuses over time. For a single sprint's completion use Burndown; for the current snapshot use the Kanban board itself.
Order bands by workflow
Stack statuses in pipeline order — Done at the bottom, Backlog at the top — so the chart reads like the board flows.
Use too many statuses
Five or six bands stay legible. A dozen thin slivers turn the CFD into stripes nobody can read.
Keep colors consistent
Use the same status colors as the board and list, so Done is always green here and everywhere else.
Reset the cumulative total
A CFD is cumulative — bands only grow as scope is added. Don’t subtract finished work or the shapes lie.
Keyboard & accessibility
The chart renders as a labelled image; the crosshair tooltip reads every band at the hovered day, and legend entries are keyboard-focusable.