Kumo Svelte
  • Home
  • Installation
  • Colors
  • Accessibility
  • Changelog
  • Autocomplete
  • Badge
  • Banner
  • Breadcrumbs
  • Button
  • Checkbox
  • Clipboard Text
  • Cloudflare Logo
  • CodeHighlighted
  • Collapsible
  • Combobox
  • Command Palette
  • Date Picker
  • Dialog
  • Dropdown
  • Empty
  • Flow
  • Grid
  • Input
  • InputArea
  • InputGroup
  • Label
  • Layer Card
  • Link
  • Loader
  • MenuBar
  • Meter
  • Pagination
  • Popover
  • Radio
  • Select
  • Sensitive Input
  • Sidebar
  • Skeleton Line
  • Switch
  • Table
  • Table of Contents
  • Tabs
  • Text
  • Toast
  • Toolbar
  • Tooltip
  • Charts
  • Colors
  • Timeseries
  • Maps
  • Sankey
  • Custom Chart
  • Page Header
  • Resource List
  • Delete Resource
Sankey Chart
kumo-svelte

Sankey Chart

A Sankey diagram component for visualizing flow data between nodes using ECharts.

<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

PropTypeDescription
echartstypeof echartsRegistered ECharts module instance.
nodesSankeyNodeData[]Node data.
linksSankeyLinkData[]Link data using node indexes.
heightnumberChart height in pixels.
left / rightnumber \| stringHorizontal layout padding.
nodeWidthnumberNode width.
nodePaddingnumberGap between nodes.
linkColor"gradient" \| "gray"Link color mode.
tooltipFormatter(params: SankeyTooltipParams) => stringCustom tooltip HTML.
onNodeClick(node: SankeyNodeData) => voidNode click handler.
onLinkClick(link: SankeyLinkData) => voidLink click handler.

On this page

  • Import
  • Usage
  • Examples
    • Basic Sankey
    • Full-Width Layout
    • Rich Tooltips
    • Interactive
    • Drill-Down Filtering
  • API Reference