Sankey flowPro

Flows between stages as ribbons with drifting particles; hover any node or ribbon to pour its share through the whole journey.

Live · keyboard ready

Signup journey

11,200 signups, Jul to Sep 2026

  • Showing how a total splits and recombines across three to five stages.
  • Explaining where a funnel leaks, with the share at each step one hover away.
  • Comparing two periods of the same flow by switching data.
  • Use bar-chart for a simple linear funnel with no branches.
  • Use sunburst for a strict hierarchy where each part has one parent.
  • Avoid more than about 12 nodes per column; small flows become unreadable slivers.

Installation

Pro source and install commands unlock with a Pro plan.

example.tsx
import { SankeyFlow } from "@/registry/components/sankey-flow/sankey-flow"; const nodes = [  { id: "organic", label: "Organic" }, { id: "paid", label: "Paid" },  { id: "activated", label: "Activated" }, { id: "inactive", label: "Not activated" },  { id: "free", label: "Free" }, { id: "pro", label: "Pro" },];const links = [  { source: "organic", target: "activated", value: 3380 }, { source: "organic", target: "inactive", value: 1820 },  { source: "paid", target: "activated", value: 1990 }, { source: "paid", target: "inactive", value: 1910 },  { source: "activated", target: "free", value: 3860 }, { source: "activated", target: "pro", value: 1510 },]; export function SignupJourney() {  return <SankeyFlow nodes={nodes} links={links} label="Signup journey" columns={["Source", "Activation", "Plan"]} unit="people" totalLabel="signups" />;}

SankeyFlow

A Sankey diagram with smooth ribbons, values on every node, and fine particles drifting along each flow. Hovering a node or ribbon pours the share of every flow that passes through it, end to end. Sources wear the series palette derived from the accent, and a trace pours in its source's hue.

PropTypeDefaultDescription
nodesRequired{ id: string; label: string; column?: number }[]–Nodes in the order they stack within each column. Columns default to each node's distance from a source.
linksRequired{ source: string; target: string; value: number }[]–Flows between node ids. A node's value is the larger of what flows in and out.
labelRequiredstring–Names the chart for assistive technology.
columnsstring[]–Stage names printed above each column. Hidden when a name would not fit, and in the upright layout.
unitstring""Unit after values in the tooltip and table, such as "people".
totalLabelstring"the total"What the first column adds up to, used in shares such as "21% of signups".
formatValue(value: number) => string–Formats node values, the tooltip, and the table.
heightnumber340Plot height in pixels. The upright layout below 420px wide uses at least 480.
particlesboolean–Controlled particles along the ribbons.
defaultParticlesbooleantrueInitial particles state when uncontrolled.
onParticlesChange(on: boolean) => void–Called when the built in toggle is pressed.
particleTogglebooleantrueShows the Flow toggle under the plot.
emptyLabelstring"No flows yet"Shown when there are no positive links.
classNamestring–Extra class on the figure.
Tab
Focuses the diagram and highlights the first node.
ArrowUporArrowDown
Moves between nodes in a column (left and right in the upright layout).
ArrowLeftorArrowRight
Steps to the nearest node in the previous or next column (up and down in the upright layout).
HomeorEnd
Jumps to the first or last column.
Escape
Clears the highlight.
  • The plot is one focusable group; the node in focus is announced with its value, share of the total, and where it flows next.
  • A visually hidden table lists every flow with its value and share of the source.
  • Labels, particles, and ribbons are aria-hidden; the table and announcements carry the data.
  • Highlighting uses the accent plus dimming of everything else, never color alone; values are printed on nodes.
  • Nodes and ribbons grow in from their centres on first view, and morph from the layout on screen to the new one when data changes.
  • Focus pours the traced share into each ribbon on a short spring and drains it back out when focus leaves.
  • Particles move at one constant speed on a canvas and pause when the chart is off screen.
  • Reduced motion jumps to the final layout and removes particles and the toggle.
  • Below 420px wide the diagram turns upright: stages run top to bottom and labels sit under each node at full width.
  • On wide layouts the last column labels to its right in a gutter sized to its labels, so no two labels share a gap.
  • Touch taps a node or ribbon to trace it and taps again to clear; the tooltip stays inside the plot.
  • Layout is computed once per data and size change; morphs interpolate numbers and write path attributes directly.
  • Particles draw on one canvas, capped at 34 per ribbon, and stop when the chart leaves the viewport.
  • Tracing walks each column once, so it stays instant for a few hundred links.

Notes for AI

Give your coding assistant the Markdown reference instead of screenshots.

  • Choose it for funnels that split and merge: acquisition to activation to plan, budget sources to spend, traffic between pages.
  • Keep node ids stable across datasets so switching periods morphs instead of redrawing.
  • Order nodes within a column the way people read them, such as good outcomes on top; the layout keeps that order.
  • Tracing assumes each node mixes what reaches it, which fits aggregates. Say so if exact per person paths matter.

The full library index for assistants is at /llms.txt.