Skip to content

Sankey

The Sankey component (ui:sankey) renders a flow diagram where directed ribbons between nodes have widths proportional to a flow value. Use it for user funnels with branching, budget allocation, energy flow, traffic attribution, or any scenario where both topology and magnitude matter.

Unlike a flowchart, every edge is sized; unlike a stacked bar chart, the branching topology is visible.

Basic example — signup funnel

Budget allocation across multiple tiers

Sankey diagrams shine when you have more than two layers of flow — budgets, org charts by headcount, or multi-stage supply chains.

Top-down orientation

Swap to vertical flow for layouts where the stages read top-to-bottom — useful when the diagram sits inside a narrow column or a dashboard cell.

Properties

PropertyTypeDefaultDescription
titlestringOptional heading displayed above the diagram.
nodesSankeyNode[](required, min 2)Array of nodes — each must have a unique id.
flowsSankeyFlow[](required, min 1)Directed flows between nodes; width is proportional to value.
orientation'left-right' | 'top-down''left-right'Axis along which the flow runs.
unitstringOptional unit label shown next to node values (e.g. users, k USD).

SankeyNode

PropertyTypeDefaultDescription
idstring(required)Stable identifier referenced by flows.
labelstring(required)Display label for the node.
colorstringOptional explicit CSS color. Overrides the default palette cycle (see “Colors” below).

SankeyFlow

PropertyTypeDefaultDescription
fromstring(required)Source node ID — must refer to a declared node.
tostring(required)Target node ID — must refer to a declared node.
valuenumber(required, > 0)Magnitude of the flow; controls ribbon thickness.
labelstringOptional description surfaced in the accessible flows table.

Constraints

  • DAG only. Cycles (including self-loops) are rejected at schema-validation time. Sankey is not meant for feedback loops — reach for a graph component for those.
  • Unique node IDs. Every flow.from / flow.to must match a declared node; references to unknown IDs fail validation.
  • Flow conservation is not enforced. You can have unbalanced totals, for example to show drop-off without explicitly routing it. This is intentional — authors often know the aggregate drop but not the itemized reasons.

Colors

Each node gets a color from the shared palette (--glyph-palette-color-1 through --glyph-palette-color-10), cycled by declaration order. Ribbons inherit the color of their source node at 55% opacity, so overlaps blend visually. Provide node.color to override.

Accessibility

  • The SVG has role="img" and an aria-label summarising the title and node/flow counts.
  • A hidden data table (role="table" with aria-label="Sankey flows") lists every flow with its source, target, value, and label — screen readers get the full data without the visual.
  • Node labels and values render as SVG <text>, so they remain selectable and discoverable through the accessibility tree.
  • Ribbons expose per-flow <title> tooltips with the flow summary.