Mario Charts
ChartsExamplesDocs
Mario Charts
 Star Mario Charts on GitHub
Star Mario Charts on GitHub
Introduction
Installation
AI Agents
Bar Chart
Line Chart
Pie Chart
Radar Chart
Scatter Plot
Stacked Bar Chart
Gauge Chart
Heatmap
Funnel Chart
Sankey Chart
TreeMap
Waterfall Chart
Sales & Revenue
Website Analytics
Loading chart documentation…

Sankey Chart

One journey, multiple paths. Follow branches from a shared entry to a common destination, with ribbons sized to the volume moving between steps.

Install
npx mario-charts@latest add sankey-chart

Playground

620 choose email. 380 choose single sign-on. Both reach the same destination.

Waiting for chart space

Select a node or connection to inspect its original observation.

Hover or focus to trace connected branches. Use arrow keys to inspect nodes, then connections; Enter selects. On narrow screens, scroll horizontally to follow the journey.

Usage

tsx
import { SankeyChart } from "@/components/charts/sankey-chart";

const nodes = [
  { id: "start", label: "Sign up" },
  { id: "email", label: "Email" },
  { id: "sso", label: "Single sign-on" },
  { id: "done", label: "Account created" },
];
const links = [
  { source: "start", target: "email", value: 620 },
  { source: "start", target: "sso", value: 380 },
  { source: "email", target: "done", value: 620 },
  { source: "sso", target: "done", value: 380 },
];

export function SignupPaths() {
  return <SankeyChart nodes={nodes} links={links}
    height={400} ariaLabel="Signup paths" />;
}

Reading a flow

Each ribbon represents one supplied transition. The email branch carries 620 of the 1,000 outgoing transitions, so its share is 62%. The destination receives 620 + 380 = 1,000. The chart does not deduplicate people or infer transitions from stage totals.

A node uses the larger of its incoming and outgoing totals for its height. An imbalance stays visible in inspection. To show abandonment, supply an explicit destination and its measured connections. A zero volume has no painted area, but remains inspectable.

Connections must form an acyclic graph. For a return visit, give the repeated event a new ID at a later step. Highlighting shows reachable connections; aggregated volumes cannot recover an individual user's complete route through a merge.

For conversion through one ordered sequence, use the Funnel Chart.

API Reference

PropTypeDefaultDescription
nodesRequired
readonly N[]—Each node has a unique string id, label and optional CSS color. Extra fields retain their inferred types in callbacks. Input order orders nodes within a column.
linksRequired
readonly L[]—Each connection has source/target node IDs and a finite nonnegative numeric value. Supply aggregated transition volumes in consistent units. Duplicate connections remain separate observations.
align
'justify' | 'start''justify'Place terminal nodes in the final column, or at their earliest depth. Connections spanning columns route below intermediate nodes.
linkColor
'gradient' | 'source' | 'target''gradient'A gradient follows source and destination colors. Solid options color each ribbon by one endpoint.
curvature
number0.50–1 curve tension; 0 produces straight connections between adjacent columns. Connections skipping columns keep a curved route around intervening nodes.
colors
readonly string[]—Palette for nodes without a color. CSS variables work; empty arrays fall back to the defaults.
nodeWidth / nodeGap
number18 / 24Node width (1–80px) and vertical gap (0–200px). Label space and internal scrolling prevent overlaps without inflating small values.
showValues
booleantrueShow each node's flow volume: max(incoming total, outgoing total). Incoming and outgoing totals stay available on inspection.
height / className
number / string400Stable frame height and root styling. Dense or narrow views scroll within the frame.
animation
booleantrueReveal connections from left to right. Reduced motion and keyboard focus complete the reveal immediately.
loading / error
boolean / string | null—Loading retains available geometry; initial loading uses a branched skeleton. Errors and empty states keep the same frame.
valueFormatter
(value: number) => string—Format labels, inspection values, the accessible table in your unit.
ariaLabel / description
string—Accessible chart name and optional explanation of the supplied data.
onNodeClick / onLinkClick
(item, index) => void—Original node or connection and input index, including zero-valued observations. Works with pointer, touch, Enter and Space.
tooltipRenderer
(inspection: SankeyInspection<N, L>) => ReactNode—A discriminated node/link payload with original data. Node inspection includes incoming/outgoing totals. Link inspection includes endpoints and its shares of source outgoing/target incoming; a zero denominator returns null.