Skip to content

sankey

A Sankey diagram is a specific type of flow diagram used to describe the flow from one set of values to another. Sankey diagrams have the following characteristics:

  • The starting flow and ending flow are the same, with the sum of all main branch widths equal to the sum of all split branch widths, maintaining energy balance;
  • Internally, different lines represent different flow distribution scenarios, with widths proportionally displaying the flow share of each branch;
  • Different node widths represent flow magnitudes under specific states. Sankey diagrams are commonly used for visualization analysis of energy, material composition, financial, and other data.

Getting Started

sankey
import { Chart } from '@antv/g2';

const chart = new Chart({
  container: 'container',
  padding: 10,
});

chart.options({
  type: 'sankey',
  data: {
    type: 'fetch',
    value: 'https://assets.antv.antgroup.com/g2/energy.json',
    transform: [
      {
        type: 'custom',
        callback: (data) => ({ links: data }),
      },
    ],
  },
  layout: {
    nodeAlign: 'center',
    nodePadding: 0.03,
  },
  scale: { color: { range: schemeTableau10 } },
  style: {
    labelSpacing: 3,
    labelFontWeight: 'bold',
    nodeStrokeWidth: 1.2,
    linkFillOpacity: 0.4,
  },
});

chart.render();

In G2, Layout is used to specify parameters for layout methods of marks with specific layout functions, such as Sankey, WordCloud, ForceGraph, etc.

({
  type: 'sankey',
  layout: {
    nodeAlign: 'center',
    nodePadding: 0.03,
  },
});
// API
chart.options({
  type: 'sankey',
  layout: { nodeAlign: 'center', nodePadding: 0.03 },
});

Data Update

Sankey diagrams support dynamic data updates using G2’s built-in API changeData():

const newData = {
  links: [
    { source: 'A', target: 'B', value: 10 },
    { source: 'A', target: 'C', value: 15 },
    { source: 'B', target: 'D', value: 8 },
    { source: 'C', target: 'D', value: 12 },
  ],
};
chart.changeData({ type: 'inline', value: newData });

Syntactic Sugar (Recommended)

G2 also provides convenient syntactic sugar, allowing you to pass array data directly like configuring other charts:

const newData = [
  { source: 'A', target: 'X', value: 10 },
  { source: 'A', target: 'Y', value: 15 },
  { source: 'B', target: 'X', value: 20 },
  { source: 'B', target: 'Y', value: 25 },
];

// Pass array directly
chart.changeData(newData);

Empty Data Handling

When passing an empty array or not providing links, the chart will display as blank:

// Clear chart - chart will display as blank
chart.changeData([]);
// or
chart.changeData({ links: [] });

Sankey Diagram Data Update Example

import { Chart } from '@antv/g2';

const chart = new Chart({ container: 'container' });

const initialData = [
  { source: 'A', target: 'X', value: 10 },
  { source: 'A', target: 'Y', value: 15 },
  { source: 'B', target: 'X', value: 20 },
];

chart.options({
  type: 'sankey',
  data: {
    type: 'inline',
    value: initialData,
  },
});

chart.render();

// Click event: randomly update data
chart.on('element:click', () => {
  const randomData = initialData.map((d) => ({
    ...d,
    value: Math.random() * 30 + 5,
  }));

  // Use simplified syntax to update data
  chart.changeData(randomData);
});

Options

Property Description Type Default
tooltip Configure Sankey diagram tooltip, see tooltip configuration object See tooltip configuration
layout Configure Sankey diagram layout, see layout configuration object See layout configuration
style Configure graphic and label styles, see style configuration object See style configuration
nodeLabels Custom node data label configuration, see nodeLabels configuration label[] []
linkLabels Custom link data label configuration, see linkLabels configuration label[] []

tooltip

As a composite graphic, Sankey diagrams need to distinguish between nodes and links when configuring tooltip.

title

Unlike single mark title configuration, Sankey diagrams need to configure nodeTitle and linkTitle separately.

({
  tooltip: {
    nodeTitle: (d) => d.key,
    linkTitle: (d) => 'link',
  },
});

items

Unlike single mark items configuration, Sankey diagrams need to configure both nodeItems and linkItems.

Like regular items, nodeItems and linkItems also support custom configuration:

({
  tooltip: {
    nodeItems: [
      (d, index, data, column) => {
        return {
          color: 'red', // Specify item color
          name: 'Node', // Specify item name
          value: d.key, // Use y channel value
          content: 'Custom node property',
        };
      },
    ],
    linkItems: [
      (d, index, data, column) => {
        return {
          color: 'red', // Specify item color
          name: 'Link', // Specify item name
          value: `${d.source.key}-${d.target.key}`, // Use y channel value
          content: 'Custom link property',
        };
      },
    ],
  },
});

💡 How to use supplementary properties in data to customize tooltip display in Sankey diagrams?

Similar to general Mark custom tooltip interaction methods, first pass custom properties in the graphic’s tooltip, then use them in interaction.

Example:

import { Chart } from '@antv/g2';

const chart = new Chart({
  container: 'container',
});

const data = {
  nodes: [
    { id: 'a', key: 'Homepage', des: 'Custom node property' },
    { id: 'b', key: 'Page 1', des: 'Custom node property' },
    { id: 'b_1', key: 'Page 1', des: 'Custom node property' },
    { id: 'c', key: 'Page 2', des: 'Custom node property' },
    { id: 'c_1', key: 'Page 2', des: 'Custom node property' },
    { id: 'd', key: 'Page 3', des: 'Custom node property' },
    { id: 'd_1', key: 'Page 3', des: 'Custom node property' },
  ],
  links: [
    { source: 'a', target: 'b', value: 100 },
    { source: 'b', target: 'c', value: 80 },
    { source: 'b', target: 'd', value: 20 },
    { source: 'c', target: 'b_1', value: 80 },
    { source: 'b_1', target: 'c_1', value: 40 },
    { source: 'b_1', target: 'd_1', value: 40 },
  ],
};

chart.options({
  type: 'sankey',
  width: 900,
  height: 600,
  data: {
    value: data,
    transform: [
      {
        type: 'custom',
        callback: (data) => ({
          nodes: data.nodes,
          links: data.links,
        }),
      },
    ],
  },
  tooltip: {
    nodeItems: [
      (d, index, data, column) => {
        return {
          content: d.des,
        };
      },
    ],
    linkItems: [
      (d, index, data, column) => {
        return {
          color: 'red', // Specify item color
          name: 'Link', // Specify item name
          value: `${d.source.key}-${d.target.key}`, // Use y channel value
          content: 'Custom link property',
        };
      },
    ],
  },
  layout: {
    nodeId: (d) => d.id,
    nodeAlign: 'center',
    nodePadding: 0.03,
    iterations: 25,
  },
  style: {
    labelSpacing: 3,
    labelFontWeight: 'bold',
    // linkFillOpacity: 0.2,
    // linkFill: '#3F96FF',
  },
  interaction: {
    tooltip: {
      render: (e, { items, title }) => {
        return `<div>${items[0].content}</div>`;
      },
    },
  },
});

chart.render();

layout

Sankey diagram layout configuration. Specific configuration options are as follows:

nodeId

<description>optional function </description>

Callback format: (node: any) => string. If nodeId is not specified, defaults to (node) => node.key.

Node binding field, used as unique identifier in layout.

💡 Sankey diagrams don’t support cycles, so how should we configure for scenarios like page flow diagrams where duplicate nodes appear?

For nodes that appear multiple times, set an id as unique identifier and configure the nodeId callback method as (node) => node.id.

Example:

import { Chart } from '@antv/g2';

const chart = new Chart({
  container: 'container',
});

const data = {
  nodes: [
    { id: 'a', key: 'Homepage' },
    { id: 'b', key: 'Page 1' },
    { id: 'b_1', key: 'Page 1' },
    { id: 'c', key: 'Page 2' },
    { id: 'c_1', key: 'Page 2' },
    { id: 'd', key: 'Page 3' },
    { id: 'd_1', key: 'Page 3' },
  ],
  links: [
    { source: 'a', target: 'b', value: 100 },
    { source: 'b', target: 'c', value: 80 },
    { source: 'b', target: 'd', value: 20 },
    { source: 'c', target: 'b_1', value: 80 },
    { source: 'b_1', target: 'c_1', value: 40 },
    { source: 'b_1', target: 'd_1', value: 40 },
  ],
};

chart.options({
  type: 'sankey',
  width: 900,
  height: 600,
  data: {
    value: data,
    transform: [
      {
        type: 'custom',
        callback: (data) => ({
          nodes: data.nodes,
          links: data.links,
        }),
      },
    ],
  },
  layout: {
    nodeId: (d) => d.id,
    nodeAlign: 'center',
    nodePadding: 0.03,
    iterations: 25,
  },
  style: {
    labelSpacing: 3,
    labelFontWeight: 'bold',
    linkFillOpacity: 0.2,
    linkFill: '#3F96FF',
  },
});

chart.render();

nodeSort

<description>optional function </description>

Callback format: ((a: any, b: any) => number)

Node sorting method. If nodeSort is not specified, returns the current node sorting method, defaulting to undefined, meaning the vertical order of nodes within each column will be automatically determined by the layout. If nodeSort is null, the order is fixed by input. Otherwise, the order is determined by the specified sorting function; this function is passed two nodes and must return a value less than 0 if the first node should be above the second node, greater than 0 if the second node should be above the first node, or 0 if no order is specified.

linkSort

<description> optional function </description>

Callback format: ((a: any, b: any) => number)

Link sorting method. If linkSort is not specified, returns the current link sorting method, defaulting to undefined, meaning the vertical order of links within each node will be automatically determined by the layout. If linkSort is null, the order is fixed by input. Otherwise, the order is determined by the specified sorting function; this function is passed two links and must return a value less than 0 if the first link should be above the second link, greater than 0 if the second link should be above the first link, or 0 if no order is specified.

nodeAlign

<description>optional string | function </description>

Built-in supported types: 'left' | 'right' | 'center' | 'justify'

Callback format: ((node: any, n: number) => number

Current node alignment method. Besides the built-in types, you can also pass the current node and the graph’s total depth n (maximum node depth + 1), and must return an integer between 0 and n - 1, indicating the desired horizontal position of the node in the generated graph.

nodeWidth

<description>optional number </description>

Node width. Defaults to 0.02.

nodePadding

<description>optional number </description>

Node spacing. Defaults to 0.02.

nodeDepth

<description>optional function </description>

Callback format: (datum: any, maxDepth: number) => number

Node depth.

iterations

<description>optional number </description>

Layout calculation iteration count, defaults to 6. More iterations result in more reasonable layout.

For more layout configuration, see d3-sankey

style

Default style configuration:

({
  // label
  labelText: (d) => d.key,
  labelSpacing: 5,
  labelFontSize: 10,
  // node
  nodeStroke: '#000',
  // link
  linkFillOpacity: 0.5,
  linkStroke: undefined,
});

Composite graphic marks need to use different prefixes to distinguish graphic configurations.

  • <label>: Prefix for configuring data labels.
Property Type Description
labelText (d: any) => string Configure default data label value for Sankey diagram, defaults to (d) => d.key
labelSpacing number Configure data label spacing for Sankey diagram, defaults to 5
labelFontSize number Sankey diagram data label font size
labelFontFamily string Sankey diagram data label font family
labelFontWeight number Sankey diagram data label font weight
labelLineHeight number Sankey diagram data label text line height
labelTextAlign string Set current alignment for Sankey diagram data label text content, supported values: center | end | left | right | start, defaults to start
labelTextBaseline string Set current text baseline used when drawing Sankey diagram data label text, supported values: top | middle | bottom | alphabetic | hanging. Defaults to bottom
labelFill string Sankey diagram data label text fill color
labelFillOpacity number Sankey diagram data label text fill opacity
labelStroke string Sankey diagram data label text stroke
labelLineWidth number Sankey diagram data label text stroke width
labelLineDash [number,number] Sankey diagram data label stroke dash configuration, first value is dash segment length, second value is gap distance. Setting lineDash to [0,0] results in no stroke.
labelStrokeOpacity number Sankey diagram data label stroke opacity
labelOpacity number Sankey diagram data label text overall opacity
labelShadowColor string Sankey diagram data label text shadow color
labelShadowBlur number Sankey diagram data label text shadow Gaussian blur coefficient
labelShadowOffsetX number Set horizontal distance of Sankey diagram data label shadow from text
labelShadowOffsetY number Set vertical distance of Sankey diagram data label shadow from text
labelCursor string Sankey diagram data label mouse cursor style. Same as CSS cursor style, defaults to ‘default’.
  • <node>: Prefix for configuring nodes.
Property Type Description
nodeFill string Sankey diagram node fill color
nodeFillOpacity number Sankey diagram node fill opacity
nodeStroke string Sankey diagram node stroke
nodeStrokeOpacity number Sankey diagram node stroke opacity
nodeLineWidth number Sankey diagram node stroke width
nodeLineDash [number,number] Sankey diagram node stroke dash configuration, first value is dash segment length, second value is gap distance. Setting lineDash to [0,0] results in no stroke.
nodeOpacity number Sankey diagram node overall opacity
nodeShadowColor string Sankey diagram node shadow color
nodeShadowBlur number Sankey diagram node shadow Gaussian blur coefficient
nodeShadowOffsetX number Set horizontal distance of shadow from Sankey diagram node
nodeShadowOffsetY number Set vertical distance of shadow from Sankey diagram node
nodeCursor string Sankey diagram node mouse cursor style. Same as CSS cursor style, defaults to ‘default’.
  • <link>: Prefix for configuring links.
Property Type Description
linkFill string Sankey diagram link fill color
linkFillOpacity number Sankey diagram link fill opacity
linkStroke string Sankey diagram link stroke
linkStrokeOpacity number Sankey diagram link stroke opacity
linkLineWidth number Sankey diagram link stroke width
linkLineDash [number,number] Sankey diagram link stroke dash configuration, first value is dash segment length, second value is gap distance. Setting lineDash to [0,0] results in no stroke.
linkOpacity number Sankey diagram link overall opacity
linkShadowColor string Sankey diagram link shadow color
linkShadowBlur number Sankey diagram link shadow Gaussian blur coefficient
linkShadowOffsetX number Set horizontal distance of shadow from Sankey diagram link
linkShadowOffsetY number Set vertical distance of shadow from Sankey diagram link
linkCursor string Sankey diagram link mouse cursor style. Same as CSS cursor style, defaults to ‘default’.

nodeLabels

<description>optional Label[] </description>

Built-in data label configuration is as follows.

({
  labels: [
    {
      text,
      dx: (d) => (d.x[0] < 0.5 ? spacing : -spacing),
      ...labelStyle, // User-provided custom data label styles
    },
    ...nodeLabels, // User-provided custom data labels
  ],
});

Besides the built-in node data labels, you can also customize node data label configuration.

({
  nodeLabels: [
    {
      text: (d) => d.key,
      fontSize: 10, // Note!!! Drawing properties here no longer need the label prefix
      fill: 'red',
    },
  ],
});

linkLabels

<description>optional Label[] </description>

Links don’t have built-in data labels, but you can customize link data label configuration.

({
  linkLabels: [
    {
      text: (d) => d.key,
      fontSize: 10, // Note!!! Drawing properties here no longer need the label prefix
      fill: 'yellow',
    },
  ],
});

state

State configuration is similar to style, using different prefixes to distinguish different graphic configurations. Configurations without prefixes will apply to both graphics.

Example:

import * as G2 from '@antv/g2';

(() => {
  const chart = new G2.Chart({ container: 'container' });

  const data = {
    links: [
      { source: 'a', target: 'b', value: 100 },
      { source: 'b', target: 'c', value: 80 },
      { source: 'b', target: 'd', value: 20 },
      { source: 'c', target: 'b_1', value: 80 },
      { source: 'b_1', target: 'c_1', value: 40 },
      { source: 'b_1', target: 'd_1', value: 40 },
    ],
  };

  chart.options({
    type: 'sankey',
    width: 900,
    height: 600,
    data: {
      value: data,
    },
    style: {
      labelSpacing: 3,
      labelFontWeight: 'bold',
      linkFillOpacity: 0.5,
      nodeFillOpacity: 0.5, // Default opacity is 0.5
    },
    state: {
      active: {
        fillOpacity: 0.8, // Opacity is 0.8 on hover
        linkFill: 'red', // Links turn red
        nodeFill: 'blue', // Nodes turn blue
      },
      inactive: {
        linkFillOpacity: 0.4,
        nodeFillOpacity: 0.2, // Nodes are lighter than links
      },
    },
    interaction: {
      elementHighlight: true,
    },
  });

  chart.render();

  return chart.getContainer();
})();
© Copyright 2026 Ant Group Co., Ltd..备案号:京ICP备15032932号-38
Site search
Documentation and examplesType to start searching

Search documentation, APIs, and examples

↑↓Select↵OpenEscClose