ApexSankey

July 5, 2026 · View on GitHub

A JavaScript library to create Sankey diagrams built on SVG

apex-sankey-chart

Dependency

Include svg.js

<script src="https://cdn.jsdelivr.net/npm/@svgdotjs/svg.js"></script>

Installation

To add the ApexSankey to your project and its dependencies, install the package from npm.

npm install apexsankey

Usage

import ApexSankey from 'apexsankey';

To create a basic sankey with minimal configuration, write as follows:

<div id="sankey-container"></div>
 const data = {
   ...(data with format provided below)
 }
 const options = {
    width: 800,
    height: 800,
    canvasStyle: 'border: 1px solid #caced0; background: #f6f6f6;',
    spacing: 100,
    nodeWidth: 20,
 };
 const sankey = new ApexSankey(document.getElementById('sankey-container'), options);
 const graph = sankey.render(data);

Setting the License

To use ApexSankey with a commercial license, set your license key before creating any chart instances:

import ApexSankey from 'apexsankey';

// set license key before creating any charts
ApexSankey.setLicense('your-license-key');

const sankey = new ApexSankey(document.getElementById('sankey-container'), options);
const graph = sankey.render(data);

ApexSankey Options

The layout can be configured by passing a second argument to ApexSankey with the properties listed below.

OptionTypeDefaultDescription
widthnumber | string'100%'Width of the canvas. Accepts a pixel number or CSS percentage string.
heightnumber | string'auto'Height of the canvas. 'auto' derives height from width at a 1.6:1 ratio.
canvasStylestringbuilt-in borderArbitrary CSS injected onto the SVG root container element.
spacingnumber20Horizontal spacing between node columns in pixels.
nodeWidthnumber20Width of each node rectangle in pixels.
nodeBorderWidthnumber1Border width of each node in pixels.
nodeBorderColorstring | nullnullCSS color for the node border. null disables the border.
onNodeClick(node: SankeyNode) => voidundefinedCallback fired when the user clicks a node.
edgeOpacitynumber0.4Opacity of edges (0–1).
edgeGradientFillbooleantrueFill edges with a gradient between source and target node colors.
edgeGapnumber0Gap in pixels between adjacent edges at node connection points.
whitespacenumber0.18Fraction of vertical space used as margins between nodes (0–1). Lower = taller nodes.
viewPortWidthnumber800Internal SVG viewport width in pixels.
viewPortHeightnumber500Internal SVG viewport height in pixels.
highlightConnectedPathbooleantrueHighlight the connected flow path when hovering a node or edge.
dimOpacitynumber0.2Opacity for dimmed (unrelated) elements when path highlighting is active.
animation{ enabled: boolean, duration: number }{ enabled: true, duration: 800 }Entrance animation. Automatically disabled when prefers-reduced-motion is set.
enableTooltipbooleantrueShow edge tooltips on hover.
enableToolbarbooleantrueShow the zoom/pan toolbar.
tooltipIdstring'apexsankey-tooltip-container'HTML id for the tooltip container element.
tooltipTemplate(content: TooltipContent) => stringbuilt-inCustom function returning an HTML string for the edge (source→target) tooltip.
nodeTooltipTemplate(content: NodeTooltipContent) => stringbuilt-inCustom function returning an HTML string for the per-node tooltip.
tooltipTheme'light' | 'dark'undefinedOverrides tooltipBGColor/tooltipBorderColor/tooltipFontColor with a preset.
tooltipBorderColorstring'#E2E8F0'Border color of the tooltip.
tooltipBGColorstring'#FFFFFF'Background color of the tooltip.
tooltipFontColorstring'#1a1a1a'Font color inside the tooltip.
fontColorstring'#212121'CSS color for node labels.
fontFamilystring''CSS font-family for node labels. Falls back to the page default when empty.
fontSizestring'14px'CSS font-size for node labels.
fontWeightstring'400'CSS font-weight for node labels.
a11y{ enabled?: boolean, diagramLabel?: string, description?: string }{ enabled: true }WCAG 2.1 AA accessibility options.
locale{ direction?: 'ltr' | 'rtl' | 'auto', messages?: Partial<SankeyMessages> }{ direction: 'ltr' }Localization and text-direction. direction: 'rtl' mirrors the diagram horizontally (flows read right-to-left) and sets dir="rtl" on the container ('auto' defers to the document). messages overrides the screen-reader strings the diagram generates.

Localization & RTL

The diagram's screen-reader strings live in SankeyMessages; pass a Partial<SankeyMessages> via locale.messages to translate any subset (unset keys keep their English defaults, exported as DEFAULT_SANKEY_MESSAGES). Visible tooltips are localized separately via tooltipTemplate / nodeTooltipTemplate.

SankeyMessages keyTypeDescription
diagramLabel(ctx: SankeyDiagramLabelContext) => stringSVG root aria-label summary (node/flow counts + largest flow).
nodeAriaLabel(ctx: SankeyNodeLabelContext) => stringPer-node aria-label (incoming/outgoing flow summary).
edgeAriaLabel(ctx: SankeyEdgeLabelContext) => stringPer-edge aria-label. Default: Flow from {source} to {target}: {value} units.
nodesGroupLabelstringaria-label for the <g> wrapping all nodes. Default: 'Sankey nodes'.
const sankey = new ApexSankey(el, {
  locale: {
    direction: 'rtl',
    messages: {nodesGroupLabel: 'العقد'},
  },
});

Default tooltip template

const tooltipTemplate = ({source, target, value}) => {
    return `
      <div style='display:flex;align-items:center;gap:5px;'>
        <div style='width:12px;height:12px;background-color:${source.color}'></div>
        <div>${source.title}</div>
        <div>=></div>
        <div style='width:12px;height:12px;background-color:${target.color}'></div>
        <div>${target.title}</div>
        <div>: ${value}</div>
      </div>
    `;
  },

Expected data format

Passed data should be an object containing nodes, edges and options. Nodes, edges and options should be in below format.

  • nodes : Passed node object should contain id and title. Id is for uniquely identifying nodes and title is for node titles. It will be also used for showing tooltips for node-to-node connections.
{
  "id": "1", // required
  "title": "A" // required
}
  • edges : Passed edge object should contain source, target, value and type. source is id value of source node for edge, target is id value of target node for edge, value indicates edge size and type is for grouping nodes.
{
    "source": "a",    // required
    "target": "b",    // required
    "value": 1,       // required
    "type": "x",      // optional
},
  • options : ApexSankey supports two options order and alightLinkTypes.

    • order: optional list of layers

      If order is not specified, the nodes are automatically assigned to layers. If order is specified, it is used directly and no rank assignment or ordering algorithm takes place.

      The order structure has three nested lists: order is a list of layers, each of which is a list of bands, each of which is a list of node ids. For example,

      {
          "order": [
              [["a", "b"]],
              [["c"]],
          ],
      },
      

Example

const data = {
  nodes: [
    {
      id: 'a',
      title: 'AAA',
    },
    {
      id: 'b',
      title: 'BBB',
    },
    {
      id: 'c',
      title: 'CCC',
    },
  ],
  edges: [
    {
      source: 'a',
      target: 'c',
      value: 1,
      type: 'A',
    },
    {
      source: 'b',
      target: 'c',
      value: 2,
      type: 'A',
    },
  ],
  options: {
    order: [[['a', 'b']], [['c']]],
  },
};