chartjs-chart-sankey

repository·main·Indexed 41 days ago

https://github.com/kurkle/chartjs-chart-sankey

A Chart.js plugin for creating Sankey diagrams to visualize directional flows between nodes with proportional band widths. Compatible with Chart.js v3.3+ and v4+, it provides the SankeyController and Flow components to render flow-style data such as energy transfers, budgets, and funnels.

Tokens
12.3K
Snippets
37
Records
41
Agent score
51%

What's inside chartjs-chart-sankey

  1. Overview of chartjs-chart-sankey

    main
    chartjs-chart-sankey is a module for Chart.js (v3.3+, v4+) that adds a Sankey chart type. It visualizes flows between named nodes as directional bands, where the width of the band is proportional to the flow value. It is ideal for visualizing energy transfers, budgets, funnels, and other flow-style data.
  2. Structure Sankey data using the flows array

    main

    To create a Sankey diagram, provide an array of objects to the data.datasets[].data property. Each object represents a flow between two nodes and must contain the following keys:

    • from: The identifier for the source node.
    • to: The identifier for the target node.
    • flow: The numerical value representing the volume of the connection.

    Example data structure:

    const flows = [
      { from: 'Origin · Syria', to: 'Host · Türkiye', flow: 2347756 },
      { from: 'Origin · Sudan', to: 'Host · Chad', flow: 1330950 }
    ];
    const flows = [
      { from: 'Origin · Syria', to: 'Host · Türkiye', flow: 2347756 },
      { from: 'Origin · Sudan', to: 'Host · Chad', flow: 1330950 },
      { from: 'Origin · Myanmar', to: 'Host · Bangladesh', flow: 1178003 },
      { from: 'Origin · Ukraine', to: 'Host · Germany', flow: 1173192 },
      { from: 'Origin · Afghanistan', to: 'Host · Pakistan', flow: 1158538 },
      { from: 'Origin · South Sudan', to: 'Host · Uganda', flow: 1033579 },
      { from: 'Origin · Ukraine', to: 'Host · Poland', flow: 972287 },
      { from: 'Origin · Afghanistan', to: 'Host · Iran', flow: 758339 },
      { from: 'Origin · Syria', to: 'Host · Germany', flow: 668647 },
      { from: 'Origin · DR Congo', to: 'Host · Uganda', flow: 644537 },
      { from: 'Origin · South Sudan', to: 'Host · Sudan', flow: 634954 },
      { from: 'Origin · Sudan', to: 'Host · South Sudan', flow: 571066 },
      { from: 'Origin · Sudan', to: 'Host · Libya', flow: 551727 },
      { from: 'Origin · Syria', to: 'Host · Lebanon', flow: 532357 },
      { from: 'Origin · South Sudan', to: 'Host · Ethiopia', flow: 422871 },
      { from: 'Origin · Syria', to: 'Host · Jordan', flow: 420835 },
      { from: 'Origin · Ukraine', to: 'Host · Czechia', flow: 392955 },
      { from: 'Origin · Somalia', to: 'Host · Kenya', flow: 319471 },
      { from: 'Origin · Somalia', to: 'Host · Ethiopia', flow: 317879 },
      { from: 'Origin · Syria', to: 'Host · Iraq', flow: 308226 },
    ]
  3. Understand nodePaddingMode: 'auto' vs 'even'

    main

    The nodePaddingMode determines how nodes are stacked in a column:

    • auto (default): Nodes are positioned to align with incoming flows from the left. This can result in varying gaps between nodes in the same column if the preceding columns are crowded.
    • even: Nodes are stacked back-to-back using the requested padding (max(prevNode.after, nextNode.before)). This creates regular gaps but causes flows to bend more to reach the nodes as they are no longer aligned with incoming flows.
  4. Understand the difference between nodePaddingMode 'auto' and 'even'

    main

    The nodePaddingMode option determines how gaps are distributed in a column, especially when nodes in one column must align with flows from a previous column.

    nodePaddingMode: 'auto' (Default)

    In auto mode, a node must clear every node stacked above it in the columns feeding into it. This ensures the node stays aligned with the flows arriving from the left.

    • Consequence: If a column narrows (e.g., four sources feeding two middle nodes), a node might end up with a gap significantly larger than the requested padding because it must clear the entire stack of preceding nodes.

    nodePaddingMode: 'even'

    In even mode, every gap in a column is given the same size.

    • Consequence: Nodes are no longer strictly aligned with the flows feeding them, which causes those flows to bend more to reach their targets. This mode is useful when you want uniform spacing regardless of the incoming flow structure.
    // Example of setting mode to 'even'
    const config = {
      type: 'sankey',
      options: {
        nodePadding: 20,
        nodePaddingMode: 'even',
      },
    }
  5. Quickstart: Create a Sankey chart

    main

    To use the Sankey chart type, you must register the SankeyController and Flow components from chartjs-chart-sankey along with the necessary Chart.js scales (like LinearScale).

    Data is provided as an array of objects within the dataset, where each object defines a connection using from, to, and flow keys.

    import { Chart, LinearScale } from 'chart.js';
    import { Flow, SankeyController } from 'chartjs-chart-sankey';
    
    Chart.register(LinearScale, SankeyController, Flow);
    
    new Chart(document.getElementById('chart'), {
      type: 'sankey',
      data: {
        datasets: [
          {
            label: 'My sankey',
            data: [
              {from: 'a', to: 'b', flow: 10},
              {from: 'a', to: 'c', flow: 5},
              {from: 'b', to: 'd', flow: 6},
              {from: 'c', to: 'd', flow: 4},
            ],
          },
        ],
      },
    });
  6. Integrate chartjs-chart-sankey using ESM

    main

    To use the Sankey plugin in an ECMAScript Module (ESM) environment, import SankeyController and Flow from chartjs-chart-sankey. You must explicitly register these components along with any required Chart.js scales (like LinearScale) using Chart.register().

    import { Chart, LinearScale } from 'chart.js'
    import { Flow, SankeyController } from 'chartjs-chart-sankey'
    
    Chart.register(LinearScale, SankeyController, Flow)
  7. Control Sankey node layout and geometry

    main

    You can customize the positioning and appearance of Sankey nodes using several configuration options within the options object.

    Node Positioning

    • column: An object used to override the automatic placement of nodes. You can map specific node names to a column index (e.g., { NodeName: 1 }).
    • priority: An object used to influence the ordering of nodes within a column. You can map node names to a priority value (e.g., { NodeName: 1 }).

    Node Geometry

    • nodeWidth: A number representing the width of the nodes.
    • nodePadding: A number representing the vertical spacing between nodes.
    • size: Controls how node sizes are calculated. Setting this to 'max' ensures nodes are sized relative to the maximum flow capacity.
    const config = {
      type: 'sankey',
      data: {
        datasets: [
          {
            label: 'Layout controls',
            data: [
              { from: 'Coal', to: 'Generation', flow: 25 },
              { from: 'Wind', to: 'Generation', flow: 18 },
            ],
          },
        ],
      },
      options: {
        column: {
          Homes: 3,
          Storage: 2,
        },
        priority: {
          Wind: 1,
          Solar: 2,
          Coal: 3,
          Homes: 1,
          Industry: 2,
          Storage: 3,
        },
        nodeWidth: 18,
        nodePadding: 20,
        size: 'max',
      },
    }
  8. Use the built ESM bundle in the browser

    main

    If you need to import the built ESM bundle directly in a browser environment, you must import Flow and SankeyController from the specific ESM file path and register them explicitly with Chart.register().

    import { Flow, SankeyController } from 'chartjs-chart-sankey/dist/chartjs-chart-sankey.esm.js'
    
    Chart.register(SankeyController, Flow)
  9. Integrate chartjs-chart-sankey using CommonJS

    main

    In a CommonJS environment, requiring chartjs-chart-sankey acts as a side effect that registers the SankeyController and Flow element automatically. You only need to manually register the Chart.js scales you are using.

    const { Chart, LinearScale } = require('chart.js')
    require('chartjs-chart-sankey')
    
    Chart.register(LinearScale)
  10. Register Sankey components for ESM usage

    main

    When using the ESM package entry, you must register the SankeyController and the Flow element with Chart.js before rendering a diagram. This ensures the Sankey plugin is correctly integrated into the Chart.js lifecycle.

    import { Chart } from 'chart.js'
    import { Flow, SankeyController } from 'chartjs-chart-sankey'
    
    Chart.register(SankeyController, Flow)