Installation
Theme
Mode

Data viz

Sankey

A flow diagram: quantities move left-to-right through stages, and the width of every ribbon is the amount that flows along it. Use it to trace how work splits and recombines — type → team → outcome, source → channel → conversion. Hover any node to isolate its flows.

$npx shadcn@latest add @orbit/sankey-chart

Overview

Live — hover a node to fade everything except the ribbons that touch it, and follow one type or team across the board.

Where the work goes — type → team → outcome
Where the work goes
Tasks by type, routed to teams, by outcome — this sprint
360tasks

Reading it

Every node’s height and every ribbon’s thickness map to the same scale, so flow is conserved: what enters a node leaves it.

Conserved flow
A node’s height equals the sum of its inputs and of its outputs. If they don’t match, the data is wrong — the chart enforces it.
Thickness = amount
A fat ribbon is a big flow. You read magnitude directly from width without needing a single number.
Splits & merges
Watch one source fan out across teams, then those teams pour into a few outcomes — branching and pooling at a glance.
Hover to trace
Hovering a node fades every unrelated ribbon, so you can follow exactly where its work came from and went.

Stages & colors

Any number of stages, two and up. Nodes without an explicit color fall back to the fixed CHART_SERIES palette by row within their stage — color follows the entity across the whole diagram.

Two stages — default palette

Props

PropTypeDefaultDescription
stagesSankeyNode[][]Nodes per stage, left to right. { id, label, color? } — color defaults to CHART_SERIES by row within the stage.
links{ source: string; target: string; value: number }[]Flows between adjacent stages. Ribbon slices stack top-to-bottom in array order; ribbons take the source node’s color.
heightnumber384Total height in px. Width is responsive.
nodeWidthnumber13Width of the node bars.
nodeGapnumber17Vertical gap between stacked nodes in a stage.
showTooltipbooleantrueDark tooltip on hovered nodes (total) and ribbons (flow).
formatValue(v: number) => stringStringFormats node and tooltip values.
ariaLabelstringPlain-language summary for the chart’s role=“img”.
…restHTMLAttributes<HTMLDivElement>Forwarded to the root div, including ref and className.

Usage

A Sankey shines at 2–4 stages and a handful of nodes per stage. Past that it turns to spaghetti — aggregate small flows into an “Other” band.

Do

Keep stages few

Two to four columns reads cleanly. Each added stage multiplies crossings and erodes the “follow the flow” clarity.

Don’t

Show dozens of nodes

Beyond ~6 per column the ribbons tangle. Roll small categories into an “Other” node and let people drill in.

Do

Colour by origin

Tint ribbons by their source so a flow keeps its identity across the whole diagram, even after it merges.

Don’t

Use it for time series

Sankey is for flow between categories, not change over time. For trends, reach for line, area or cumulative-flow charts.

Keyboard & accessibility

The chart renders as a labelled image; every node carries its name and value directly, and the tooltip reads exact flows.

roleimg with an aria-label summary of the flow
TooltipHovered node totals and ribbon flows, with values
LabelsEvery node is named and valued directly on the chart
Halo3px surface halo keeps labels readable over ribbons