Sankey
sankeyVisualizes weighted flow between stages with proportional nodes and links.
Usage
Basic usage
nodes/links is controlled; when layer is not given, the topology is automatically layered according to links (source layer < target layer), and the flow width is based on value proportion. per-node tone eats the token variable.
<Sankey
nodes={[
{ id: "text", label: "Text generation", tone: "var(--color-chart-1)" },
{ id: "code", label: "Code Task", tone: "var(--color-chart-2)" },
{ id: "router", label: "Smart Router", tone: "var(--color-primary)" },
{ id: "haiku", label: "Haiku Pool", tone: "var(--color-chart-4)" },
{ id: "sonnet", label: "Sonnet Pool", tone: "var(--color-chart-5)" },
]}
links={[
{ source: "text", target: "router", value: 42 },
{ source: "code", target: "router", value: 28 },
{ source: "router", target: "haiku", value: 38 },
{ source: "router", target: "sonnet", value: 30 },
]}
height={300}
/>Item by item tooltip
renderTooltip distinguishes two types of hover targets: node / link. Follow the pointer to display details.
<Sankey
nodes={nodes}
links={links}
height={300}
renderTooltip={(item) =>
item.type === "node" ? (
<span>{item.node.label}</span>
) : (
<span>{item.link.source} → {item.link.target}: {item.link.value}</span>
)
}
/>Bold node strips + flow adjustment with transparency
nodeWidth enlarges the node rectangle width, linkOpacity adjusts the flow band stroke transparency.
<Sankey
nodes={nodes}
links={links}
height={300}
nodeWidth={24}
linkOpacity={0.5}
/>When to use
Use Sankey to show allocation or conversion across multiple directed layers, such as task routing, budget distribution, or traffic sources. Use Funnel for one linear attrition path, or [Table]/[ProTable] for flat records.
Import
import { Sankey, assignLayers, computeSankeyLayout } from "@hulianui/ui"Props
| Name | Type | Default | Description |
|---|---|---|---|
| nodes* | SankeyNode[] | — | {id, label?, layer?, tone?} nodes. Layers are inferred topologically when omitted. |
| links* | SankeyLink[] | — | {source, target, value, tone?} links whose ribbon width follows value. |
| height | number | 320 | Container height. |
| nodeWidth | number | 16 | Node rectangle width. |
| nodePadding | number | 12 | Vertical spacing between same-layer nodes. |
| linkOpacity | number | 0.35 | Ribbon opacity, raised to 0.6 on hover. |
| className | string | — | Root class name. |
Events
| Event | Type | Description |
|---|---|---|
| onNodeClick | (node: SankeyLaidNode) => void | Node drill-down. |
| onLinkClick | (link: SankeyLaidLink) => void | Link drill-down. |
Slots
| Slot | Type | Description |
|---|---|---|
| renderNodeLabel | (node: SankeyLaidNode) => ReactNode | Custom node label. |
| renderTooltip | (item: {type:"node";node} | {type:"link";link}) => ReactNode | Custom node or link hover tooltip. |
Example
const nodes: SankeyNode[] = [
{ id: "text", label: "Text generation", tone: "var(--color-chart-1)" },
{ id: "router", label: "Smart router", tone: "var(--color-primary)" },
{ id: "haiku", label: "Haiku pool", tone: "var(--color-chart-4)" },
];
const links: SankeyLink[] = [
{ source: "text", target: "router", value: 42 },
{ source: "router", target: "haiku", value: 38 },
];
<Sankey
nodes={nodes}
links={links}
height={300}
renderTooltip={(item) => item.type === "node"
? <span>{item.node.label}</span>
: <span>{item.link.source} → {item.link.target}: {item.link.value}</span>}
/>Usage notes
- SVG tones require full token names such as
var(--color-chart-3); see [[hulian-token-color-var-needs-color-prefix]]. computeSankeyLayoutproduces laid-out coordinates andassignLayersinfers topology. Do not pass cyclic links because layering assumes a DAG.- The root uses built-in Chinese
aria-label"\u6851\u57fa\u6d41\u5411\u56fe", meaning “Sankey flow diagram.”
Related
The chart accessibility label follows ConfigProvider.
Table · Book3D · ProTable · PricingTable · JsonViewer · EditableTable
Playground
<Sankey
nodes={[
{ id: "text", label: "Text generation", tone: "var(--color-chart-1)" },
{ id: "router", label: "Smart Router", tone: "var(--color-primary)" },
{ id: "haiku", label: "Haiku Pool", tone: "var(--color-chart-4)" },
]}
links={[
{ source: "text", target: "router", value: 42 },
{ source: "router", target: "haiku", value: 38 },
]}
height={300}
nodeWidth={16}
linkOpacity={0.35}
/>