chartjs-chart-sankey
repository·main·Indexed 41 days ago
https://github.com/kurkle/chartjs-chart-sankeyA 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.
What's inside chartjs-chart-sankey
- 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.
Structure Sankey data using the flows array
mainTo create a Sankey diagram, provide an array of objects to the
data.datasets[].dataproperty. 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 }, ]Understand nodePaddingMode: 'auto' vs 'even'
mainThe
nodePaddingModedetermines 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.
Define Sankey data points
mainSankey data points represent directed flows between named nodes. Each data point is an object specifying the source node (
from), the target node (to), and the magnitude of the flow (flow).{ from: 'Coal', to: 'Electricity', flow: 42 }Understand the difference between nodePaddingMode 'auto' and 'even'
mainThe
nodePaddingModeoption 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
automode, 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
evenmode, 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', }, }Quickstart: Create a Sankey chart
mainTo use the Sankey chart type, you must register the
SankeyControllerandFlowcomponents fromchartjs-chart-sankeyalong with the necessary Chart.js scales (likeLinearScale).Data is provided as an array of objects within the dataset, where each object defines a connection using
from,to, andflowkeys.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}, ], }, ], }, });Integrate chartjs-chart-sankey using ESM
mainTo use the Sankey plugin in an ECMAScript Module (ESM) environment, import
SankeyControllerandFlowfromchartjs-chart-sankey. You must explicitly register these components along with any required Chart.js scales (likeLinearScale) usingChart.register().import { Chart, LinearScale } from 'chart.js' import { Flow, SankeyController } from 'chartjs-chart-sankey' Chart.register(LinearScale, SankeyController, Flow)Control Sankey node layout and geometry
mainYou can customize the positioning and appearance of Sankey nodes using several configuration options within the
optionsobject.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', }, }Use the built ESM bundle in the browser
mainIf you need to import the built ESM bundle directly in a browser environment, you must import
FlowandSankeyControllerfrom the specific ESM file path and register them explicitly withChart.register().import { Flow, SankeyController } from 'chartjs-chart-sankey/dist/chartjs-chart-sankey.esm.js' Chart.register(SankeyController, Flow)Install chartjs-chart-sankey via npm
mainTo use sankey diagrams with Chart.js, install both
chart.jsandchartjs-chart-sankeyusing npm.npm install chart.js chartjs-chart-sankeyIntegrate chartjs-chart-sankey using CommonJS
mainIn a CommonJS environment, requiring
chartjs-chart-sankeyacts as a side effect that registers theSankeyControllerandFlowelement 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)Register Sankey components for ESM usage
mainWhen using the ESM package entry, you must register the
SankeyControllerand theFlowelement 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)