A Sankey diagram shows how a quantity flows from one stage to the next, each band as wide as its share. Here, an example energy budget: of every 100 units that go in, 40 end up doing useful work.
A Sankey diagram follows one quantity, such as energy, money or people, through the steps it passes. Every band keeps its width from start to end, so the big flows and the losses stand out at once. It reads best with three to five stages and a couple of dozen flows.
Built with amCharts 5, a JavaScript library. The JavaScript includes your theme and renderer (canvas or SVG); the JSON also follows the changes you make with the controls.
npm install @amcharts/amcharts5. See Getting started.
The same chart as a JSON config. Chart Maker reads and writes this format, the library's JSON parser turns it into a chart, and the <am5-chart> element puts it on a page with no code."type" is the class to create and "settings" what you would pass to its new() in code; "properties" fill in its parts, lists such as series and axes or templates such as columns.template; "refs" holds objects used in more than one place ("#series-0" stands for the one named series-0); a string starting with "@" takes a value from another object, such as "@series.get('fill')".
A complete page. Save it as an .html file and open it in a browser.
Paste this into an AI coding assistant to build the chart from scratch. More in amCharts & AI.
// Create root element
// https://www.amcharts.com/docs/v5/getting-started/#Root_element
var root = am5.Root.new("chartdiv");
// Set themes
// https://www.amcharts.com/docs/v5/concepts/themes/
root.setThemes([
am5themes_Animated.new(root),
am5themes_Responsive.new(root)
]);
// Create series
// https://www.amcharts.com/docs/v5/charts/flow-charts/
var chart = root.container.children.push(am5.SerialChartContainer.new(root, {})); // holds the flow series
// each link is as wide as its value, and each node as tall as the flow through it
var series = chart.series.push(am5flow.Sankey.new(root, {
sourceIdField: "from",
targetIdField: "to",
valueField: "value",
// room for the labels of the last column
paddingRight: 110
}));
// take every second color of the set, so neighboring nodes differ more
series.nodes.get("colors").set("step", 2);
// Every number is a share of all the energy that goes in, so the values add up to 100
series.links.template.set("tooltipText", "{sourceId} to {targetId}: {value}%");
// Set data
// https://www.amcharts.com/docs/v5/charts/flow-charts/#Setting_data
series.data.setAll([
// sources
{ from: "Wind & solar", to: "Electricity", value: 16 },
{ from: "Natural gas", to: "Electricity", value: 22 },
{ from: "Natural gas", to: "Fuels", value: 16 },
{ from: "Oil", to: "Fuels", value: 46 },
// where electricity and fuels are used
{ from: "Electricity", to: "Homes", value: 13 },
{ from: "Electricity", to: "Industry", value: 13 },
{ from: "Fuels", to: "Homes", value: 9 },
{ from: "Fuels", to: "Industry", value: 18 },
{ from: "Fuels", to: "Transport", value: 35 },
// what does useful work and what is wasted
{ from: "Homes", to: "Useful energy", value: 15 },
{ from: "Homes", to: "Lost as heat", value: 7 },
{ from: "Industry", to: "Useful energy", value: 16 },
{ from: "Industry", to: "Lost as heat", value: 15 },
{ from: "Transport", to: "Useful energy", value: 9 },
{ from: "Transport", to: "Lost as heat", value: 26 },
// power plants lose a third of their energy as heat
{ from: "Electricity", to: "Lost as heat", value: 12 }
]);
// Make stuff animate on load
series.appear(1000, 100);
{
"type": "SerialChartContainer",
"properties": {
"series": [
"#series-0"
]
},
"refs": [
{
"data-0": [
{
"from": "Wind & solar",
"to": "Electricity",
"value": 16
},
{
"from": "Natural gas",
"to": "Electricity",
"value": 22
},
{
"from": "Natural gas",
"to": "Fuels",
"value": 16
},
{
"from": "Oil",
"to": "Fuels",
"value": 46
},
{
"from": "Electricity",
"to": "Homes",
"value": 13
},
{
"from": "Electricity",
"to": "Industry",
"value": 13
},
{
"from": "Fuels",
"to": "Homes",
"value": 9
},
{
"from": "Fuels",
"to": "Industry",
"value": 18
},
{
"from": "Fuels",
"to": "Transport",
"value": 35
},
{
"from": "Homes",
"to": "Useful energy",
"value": 15
},
{
"from": "Homes",
"to": "Lost as heat",
"value": 7
},
{
"from": "Industry",
"to": "Useful energy",
"value": 16
},
{
"from": "Industry",
"to": "Lost as heat",
"value": 15
},
{
"from": "Transport",
"to": "Useful energy",
"value": 9
},
{
"from": "Transport",
"to": "Lost as heat",
"value": 26
},
{
"from": "Electricity",
"to": "Lost as heat",
"value": 12
}
]
},
{
"series-0": {
"type": "Sankey",
"settings": {
"sourceIdField": "from",
"targetIdField": "to",
"valueField": "value",
"paddingRight": 110
},
"properties": {
"data": "#data-0",
"links": {
"properties": {
"template": {
"settings": {
"tooltipText": "{sourceId} to {targetId}: {value}%"
}
}
}
},
"nodes": {
"settings": {
"colors": {
"type": "ColorSet",
"settings": {
"step": 2,
"passOptions": {
"hue": 0.05,
"saturation": 0,
"lightness": 0
},
"colors": [
{
"type": "Color",
"value": "#67b7dc"
},
{
"type": "Color",
"value": "#6794dc"
},
{
"type": "Color",
"value": "#6771dc"
},
{
"type": "Color",
"value": "#8067dc"
},
{
"type": "Color",
"value": "#a367dc"
},
{
"type": "Color",
"value": "#c767dc"
},
{
"type": "Color",
"value": "#dc67ce"
},
{
"type": "Color",
"value": "#dc67ab"
},
{
"type": "Color",
"value": "#dc6788"
},
{
"type": "Color",
"value": "#dc6967"
},
{
"type": "Color",
"value": "#dc8c67"
},
{
"type": "Color",
"value": "#dcaf67"
},
{
"type": "Color",
"value": "#dcd267"
},
{
"type": "Color",
"value": "#c3dc67"
},
{
"type": "Color",
"value": "#a0dc67"
},
{
"type": "Color",
"value": "#7ddc67"
},
{
"type": "Color",
"value": "#67dc75"
},
{
"type": "Color",
"value": "#67dc98"
},
{
"type": "Color",
"value": "#67dcbb"
}
],
"reuse": false,
"startIndex": 0,
"stateAnimationDuration": 600
}
}
}
}
}
}
}
]
}