<script lang="ts">
import { SankeyChart, ChartPalette } from "kumo-svelte/components/chart";
import { echarts } from "../chart-echarts";
const sankeyLinks = [
{ source: 0, target: 2, value: 80000 },
{ source: 0, target: 3, value: 23600 },
{ source: 1, target: 2, value: 42600 },
{ source: 1, target: 3, value: 8200 },
];
const sankeyNodes = [
{ name: "Users", value: 103600, color: ChartPalette.categorical(0) },
{ name: "Devices", value: 50800, color: ChartPalette.categorical(1) },
{ name: "Apps", value: 122600, color: ChartPalette.categorical(2) },
{ name: "Tunnels", value: 31800, color: ChartPalette.categorical(3) },
];
</script>
<SankeyChart {echarts} nodes={sankeyNodes} links={sankeyLinks} height={300} />
Import
SankeyChart requires echarts as a peer dependency.
pnpm add echarts import { ChartPalette, SankeyChart } from "kumo-svelte/components/chart"; Usage
<script lang="ts">
import { SankeyChart, ChartPalette } from "kumo-svelte/components/chart";
import { echarts } from "./chart-echarts";
const nodes = [
{ name: "Users", value: 103600, color: ChartPalette.categorical(0) },
{ name: "Apps", value: 122600, color: ChartPalette.categorical(2) },
];
const links = [{ source: 0, target: 1, value: 80000 }];
</script>
<SankeyChart {echarts} {nodes} {links} height={300} /> Examples
Basic Sankey
A simple Sankey diagram showing flow between source and target nodes.
<script lang="ts">
import { SankeyChart, ChartPalette } from "kumo-svelte/components/chart";
import { echarts } from "../chart-echarts";
const sankeyLinks = [
{ source: 0, target: 2, value: 80000 },
{ source: 0, target: 3, value: 23600 },
{ source: 1, target: 2, value: 42600 },
{ source: 1, target: 3, value: 8200 },
];
const sankeyNodes = [
{ name: "Users", value: 103600, color: ChartPalette.categorical(0) },
{ name: "Devices", value: 50800, color: ChartPalette.categorical(1) },
{ name: "Apps", value: 122600, color: ChartPalette.categorical(2) },
{ name: "Tunnels", value: 31800, color: ChartPalette.categorical(3) },
];
</script>
<SankeyChart {echarts} nodes={sankeyNodes} links={sankeyLinks} height={300} />
Full-Width Layout
Use left and right to control horizontal padding of the Sankey layout within its container.
<script lang="ts">
import { SankeyChart, ChartPalette } from "kumo-svelte/components/chart";
import { echarts } from "../chart-echarts";
const sankeyLinks = [
{ source: 0, target: 2, value: 80000 },
{ source: 0, target: 3, value: 23600 },
{ source: 1, target: 2, value: 42600 },
{ source: 1, target: 3, value: 8200 },
];
const sankeyNodes = [
{ name: "Users", value: 103600, color: ChartPalette.categorical(0) },
{ name: "Devices", value: 50800, color: ChartPalette.categorical(1) },
{ name: "Apps", value: 122600, color: ChartPalette.categorical(2) },
{ name: "Tunnels", value: 31800, color: ChartPalette.categorical(3) },
];
</script>
<SankeyChart {echarts} nodes={sankeyNodes} links={sankeyLinks} height={300} left={0} right={0} />
Rich Tooltips
Use tooltipFormatter for full control over tooltip content.
<script lang="ts">
import { SankeyChart, type SankeyTooltipParams, ChartPalette } from "kumo-svelte/components/chart";
import { echarts } from "../chart-echarts";
const sankeyLinks = [
{ source: 0, target: 2, value: 80000 },
{ source: 0, target: 3, value: 23600 },
{ source: 1, target: 2, value: 42600 },
{ source: 1, target: 3, value: 8200 },
];
const sankeyNodes = [
{ name: "Users", value: 103600, color: ChartPalette.categorical(0) },
{ name: "Devices", value: 50800, color: ChartPalette.categorical(1) },
{ name: "Apps", value: 122600, color: ChartPalette.categorical(2) },
{ name: "Tunnels", value: 31800, color: ChartPalette.categorical(3) },
];
function tooltipFormatter(params: SankeyTooltipParams) {
if (params.type === "node" && params.node) {
return `<strong>${params.name}</strong><br>${params.node.value?.toLocaleString() ?? ""}`;
}
if (params.type === "link" && params.link) {
return `${params.link.source} → ${params.link.target}<br><strong>${params.link.value.toLocaleString()}</strong>`;
}
return "";
}
</script>
<SankeyChart {echarts} nodes={sankeyNodes} links={sankeyLinks} height={300} {tooltipFormatter} />
Interactive
Use onNodeClick and onLinkClick to handle interactions.
Click a node or link
<script lang="ts">
import { SankeyChart, ChartPalette } from "kumo-svelte/components/chart";
import { echarts } from "../chart-echarts";
const sankeyLinks = [
{ source: 0, target: 2, value: 80000 },
{ source: 0, target: 3, value: 23600 },
{ source: 1, target: 2, value: 42600 },
{ source: 1, target: 3, value: 8200 },
];
const sankeyNodes = [
{ name: "Users", value: 103600, color: ChartPalette.categorical(0) },
{ name: "Devices", value: 50800, color: ChartPalette.categorical(1) },
{ name: "Apps", value: 122600, color: ChartPalette.categorical(2) },
{ name: "Tunnels", value: 31800, color: ChartPalette.categorical(3) },
];
let clicked = $state("Click a node or link");
</script>
<div class="space-y-3">
<SankeyChart
{echarts}
nodes={sankeyNodes}
links={sankeyLinks}
height={300}
onNodeClick={(node) => (clicked = `Node: ${node.name}`)}
onLinkClick={(link) => (clicked = `Link: ${link.source} → ${link.target}`)}
/>
<p class="text-sm text-kumo-subtle">{clicked}</p>
</div>
Drill-Down Filtering
Click a source node to filter the chart and show only its connections. Click again or use the reset button to restore the full view.
Click Users or Devices
<script lang="ts">
import { Button } from "kumo-svelte/components/button";
import { SankeyChart, ChartPalette } from "kumo-svelte/components/chart";
import { echarts } from "../chart-echarts";
const sankeyLinks = [
{ source: 0, target: 2, value: 80000 },
{ source: 0, target: 3, value: 23600 },
{ source: 1, target: 2, value: 42600 },
{ source: 1, target: 3, value: 8200 },
];
const sankeyNodes = [
{ name: "Users", value: 103600, color: ChartPalette.categorical(0) },
{ name: "Devices", value: 50800, color: ChartPalette.categorical(1) },
{ name: "Apps", value: 122600, color: ChartPalette.categorical(2) },
{ name: "Tunnels", value: 31800, color: ChartPalette.categorical(3) },
];
const sourceNames = new Set(["Users", "Devices"]);
let selected = $state<string | null>(null);
let filteredLinks = $derived(
selected ? sankeyLinks.filter((link) => sankeyNodes[link.source]?.name === selected) : sankeyLinks,
);
let connectedNodeIndexes = $derived(new Set(filteredLinks.flatMap((link) => [link.source, link.target])));
let filteredNodes = $derived(selected ? sankeyNodes.filter((_, index) => connectedNodeIndexes.has(index)) : sankeyNodes);
let remappedLinks = $derived(
selected
? filteredLinks.map((link) => ({
...link,
source: filteredNodes.findIndex((node) => node.name === sankeyNodes[link.source]?.name),
target: filteredNodes.findIndex((node) => node.name === sankeyNodes[link.target]?.name),
}))
: filteredLinks,
);
</script>
<div class="space-y-3">
<div class="flex items-center gap-2">
<Button size="sm" variant="secondary" onclick={() => (selected = null)}>Reset</Button>
<span class="text-sm text-kumo-subtle">{selected ? `Filtered to ${selected}` : "Click Users or Devices"}</span>
</div>
<SankeyChart
{echarts}
nodes={filteredNodes}
links={remappedLinks}
height={300}
onNodeClick={(node) => {
selected = sourceNames.has(node.name) ? (selected === node.name ? null : node.name) : selected;
}}
/>
</div>
API Reference
| Prop | Type | Description |
|---|---|---|
echarts | typeof echarts | Registered ECharts module instance. |
nodes | SankeyNodeData[] | Node data. |
links | SankeyLinkData[] | Link data using node indexes. |
height | number | Chart height in pixels. |
left / right | number \| string | Horizontal layout padding. |
nodeWidth | number | Node width. |
nodePadding | number | Gap between nodes. |
linkColor | "gradient" \| "gray" | Link color mode. |
tooltipFormatter | (params: SankeyTooltipParams) => string | Custom tooltip HTML. |
onNodeClick | (node: SankeyNodeData) => void | Node click handler. |
onLinkClick | (link: SankeyLinkData) => void | Link click handler. |