A Sankey diagram that runs from top to bottom instead of left to right. Here, an example of how $1.77 trillion of company cash splits by industry, and how much of it is held overseas.
A vertical Sankey reads like a page: the total at the top, splitting step by step into smaller parts below. It suits reports and infographics, and the wide bands have room for labels inside them, so the chart needs no legend.
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 a container for the series
var chart = root.container.children.push(am5.SerialChartContainer.new(root, {}));
// Create series
// https://www.amcharts.com/docs/v5/charts/flow-charts/
var series = chart.series.push(
am5flow.Sankey.new(root, {
orientation: "vertical", // the money flows from top to bottom
sourceIdField: "from",
targetIdField: "to",
valueField: "value",
// narrow gaps keep the bands of the five companies straight enough for their labels
nodePadding: 5,
// room for the labels above the first node and below the last ones
paddingTop: 30,
paddingBottom: 45
})
);
// Nodes are hidden: the bands themselves make the picture
series.nodes.nodes.template.setAll({
// clicking a node doesn't hide its bands
toggleKey: "none",
cursorOverStyle: "default" // a plain arrow cursor, as the nodes do nothing
});
series.nodes.rectangles.template.setAll({
fillOpacity: 0,
strokeOpacity: 0
});
series.links.template.setAll({
tooltipText: "{sourceId} > {targetId}: [bold]${value}B",
fillOpacity: 1, // solid bands
strokeOpacity: 1,
interactive: true // the bands react to the mouse
});
// a band under the mouse turns slightly see-through
series.links.template.states.create("hover", { fillOpacity: 0.8 });
// Only the first and the last nodes get a label: their own text from the node data
series.nodes.labels.template.setAll({
forceHidden: true, // hidden unless the node's labelSettings show it
textAlign: "center", // each line centered
templateField: "labelSettings"
});
// Colors from the theme: one for the companies, two more for where the cash is held
var colors = am5.ColorSet.new(root, {});
var companyColor = colors.getIndex(0);
series.nodes.data.setAll([
{
id: "Non-financial companies",
fill: companyColor,
labelSettings: {
text: "NON-FINANCIAL COMPANIES: [bold]$1.77 TRILLION[/] IN CASH",
forceHidden: false,
centerY: am5.p100, // above the top node...
paddingBottom: 6 // ...6px clear of it
}
},
{ id: "Non-tech companies", fill: companyColor },
{ id: "Tech companies", fill: companyColor },
{
id: "Cash in the U.S.",
fill: colors.getIndex(4), // the bands into it fade to the theme's fifth color
labelSettings: {
text: "CASH IN THE U.S.\n[bold]$459 BILLION",
forceHidden: false,
centerY: 0, // below the node...
paddingTop: 6 // ...6px clear of it
}
},
{
id: "Cash overseas",
fill: colors.getIndex(8), // and these to its ninth
labelSettings: {
text: "CASH OVERSEAS\n[bold]$1.31 TRILLION",
forceHidden: false,
centerY: 0,
paddingTop: 6
}
},
{ id: "Rest of tech", fill: companyColor },
{ id: "Top 5 tech companies", fill: companyColor },
{ id: "Joytechs", fill: companyColor },
{ id: "Fireex", fill: companyColor },
{ id: "Globalworld", fill: companyColor },
{ id: "Betagate", fill: companyColor },
{ id: "Apexi", fill: companyColor }
]);
// the labels on the bands: black or white, whichever stands out on the companies' color
var bandTextColor = am5.Color.alternative(companyColor, am5.color(0xffffff), am5.color(0x000000));
// Labels on the bands, from each link's labelSettings
series.bullets.push(function () {
return am5.Bullet.new(root, {
locationY: 0.5, // halfway along the band
sprite: am5.Label.new(root, {
templateField: "labelSettings",
fill: bandTextColor,
fontSize: "0.85em", // 85% of the chart's text size
textAlign: "center", // each line centered...
centerX: am5.p50, // ...on the middle of the band
centerY: am5.p50,
paddingTop: 0, // no padding above or below, so the label fits a thin band
paddingBottom: 0
})
});
});
// The five companies' bands are narrow, so their labels are turned to run up the band from each company's node,
// where the band is straight, with the amount on a second line
series.bullets.push(function () {
return am5.Bullet.new(root, {
locationY: 1, // at the end of the band, the company's node
sprite: am5.Label.new(root, {
templateField: "companyLabel",
fill: bandTextColor,
fontSize: "0.75em", // 75% of the chart's text size
rotation: -90, // turned to read upward
centerX: 0, // starting at the node, running up the band
centerY: am5.p50,
paddingLeft: 5, // 5px from the node
paddingTop: 0,
paddingBottom: 0
})
});
});
// Set data
// https://www.amcharts.com/docs/v5/charts/flow-charts/#Setting_data
series.data.setAll([
{
from: "Non-financial companies",
to: "Non-tech companies",
value: 907,
labelSettings: { text: "NON-TECH COMPANIES\n[bold]$907 BILLION" }
},
{
from: "Non-financial companies",
to: "Tech companies",
value: 861,
labelSettings: { text: "TECH COMPANIES\n[bold]$861 BILLION" }
},
{ from: "Non-tech companies", to: "Cash in the U.S.", value: 324 },
{ from: "Non-tech companies", to: "Cash overseas", value: 583 },
{
from: "Tech companies",
to: "Rest of tech",
value: 274,
labelSettings: { text: "REST OF TECH\n[bold]$274 BILLION" }
},
{
from: "Tech companies",
to: "Top 5 tech companies",
value: 587,
labelSettings: { text: "TOP 5 TECH COMPANIES\n[bold]$587 BILLION" }
},
{ from: "Rest of tech", to: "Cash in the U.S.", value: 74 },
{ from: "Rest of tech", to: "Cash overseas", value: 200 },
{
from: "Top 5 tech companies",
to: "Joytechs",
value: 67,
companyLabel: { text: "JOYTECHS\n[bold]$67B" }
},
{ from: "Joytechs", to: "Cash in the U.S.", value: 10 },
{ from: "Joytechs", to: "Cash overseas", value: 57 },
{
from: "Top 5 tech companies",
to: "Fireex",
value: 68,
companyLabel: { text: "FIREEX\n[bold]$68B" }
},
{ from: "Fireex", to: "Cash in the U.S.", value: 8 },
{ from: "Fireex", to: "Cash overseas", value: 60 },
{
from: "Top 5 tech companies",
to: "Globalworld",
value: 85,
companyLabel: { text: "GLOBALWORLD\n[bold]$85B" }
},
{ from: "Globalworld", to: "Cash in the U.S.", value: 10 },
{ from: "Globalworld", to: "Cash overseas", value: 75 },
{
from: "Top 5 tech companies",
to: "Betagate",
value: 115,
companyLabel: { text: "BETAGATE\n[bold]$115B" }
},
{ from: "Betagate", to: "Cash in the U.S.", value: 10 },
{ from: "Betagate", to: "Cash overseas", value: 105 },
{
from: "Top 5 tech companies",
to: "Apexi",
value: 252,
companyLabel: { text: "APEXI\n[bold]$252B" }
},
{ from: "Apexi", to: "Cash in the U.S.", value: 23 },
{ from: "Apexi", to: "Cash overseas", value: 229 }
]);
// Make stuff animate on load
series.appear(1000, 100);
{
"type": "SerialChartContainer",
"properties": {
"series": [
"#series-0"
]
},
"refs": [
{
"data-0": [
{
"from": "Non-financial companies",
"to": "Non-tech companies",
"value": 907,
"labelSettings": {
"text": "NON-TECH COMPANIES\n[bold]$907 BILLION"
},
"__parse": true
},
{
"from": "Non-financial companies",
"to": "Tech companies",
"value": 861,
"labelSettings": {
"text": "TECH COMPANIES\n[bold]$861 BILLION"
},
"__parse": true
},
{
"from": "Non-tech companies",
"to": "Cash in the U.S.",
"value": 324
},
{
"from": "Non-tech companies",
"to": "Cash overseas",
"value": 583
},
{
"from": "Tech companies",
"to": "Rest of tech",
"value": 274,
"labelSettings": {
"text": "REST OF TECH\n[bold]$274 BILLION"
},
"__parse": true
},
{
"from": "Tech companies",
"to": "Top 5 tech companies",
"value": 587,
"labelSettings": {
"text": "TOP 5 TECH COMPANIES\n[bold]$587 BILLION"
},
"__parse": true
},
{
"from": "Rest of tech",
"to": "Cash in the U.S.",
"value": 74
},
{
"from": "Rest of tech",
"to": "Cash overseas",
"value": 200
},
{
"from": "Top 5 tech companies",
"to": "Joytechs",
"value": 67,
"companyLabel": {
"text": "JOYTECHS\n[bold]$67B"
},
"__parse": true
},
{
"from": "Joytechs",
"to": "Cash in the U.S.",
"value": 10
},
{
"from": "Joytechs",
"to": "Cash overseas",
"value": 57
},
{
"from": "Top 5 tech companies",
"to": "Fireex",
"value": 68,
"companyLabel": {
"text": "FIREEX\n[bold]$68B"
},
"__parse": true
},
{
"from": "Fireex",
"to": "Cash in the U.S.",
"value": 8
},
{
"from": "Fireex",
"to": "Cash overseas",
"value": 60
},
{
"from": "Top 5 tech companies",
"to": "Globalworld",
"value": 85,
"companyLabel": {
"text": "GLOBALWORLD\n[bold]$85B"
},
"__parse": true
},
{
"from": "Globalworld",
"to": "Cash in the U.S.",
"value": 10
},
{
"from": "Globalworld",
"to": "Cash overseas",
"value": 75
},
{
"from": "Top 5 tech companies",
"to": "Betagate",
"value": 115,
"companyLabel": {
"text": "BETAGATE\n[bold]$115B"
},
"__parse": true
},
{
"from": "Betagate",
"to": "Cash in the U.S.",
"value": 10
},
{
"from": "Betagate",
"to": "Cash overseas",
"value": 105
},
{
"from": "Top 5 tech companies",
"to": "Apexi",
"value": 252,
"companyLabel": {
"text": "APEXI\n[bold]$252B"
},
"__parse": true
},
{
"from": "Apexi",
"to": "Cash in the U.S.",
"value": 23
},
{
"from": "Apexi",
"to": "Cash overseas",
"value": 229
}
]
},
{
"series-0": {
"type": "Sankey",
"settings": {
"orientation": "vertical",
"sourceIdField": "from",
"targetIdField": "to",
"valueField": "value",
"nodePadding": 5,
"paddingTop": 30,
"paddingBottom": 45
},
"properties": {
"data": "#data-0",
"links": {
"properties": {
"template": {
"settings": {
"tooltipText": "{sourceId} > {targetId}: [bold]${value}B",
"fillOpacity": 1,
"strokeOpacity": 1,
"interactive": true
},
"states": [
{
"key": "hover",
"settings": {
"fillOpacity": 0.8
}
}
]
}
}
},
"nodes": {
"properties": {
"data": [
{
"id": "Non-financial companies",
"fill": {
"type": "Color",
"value": "#67b7dc"
},
"labelSettings": {
"text": "NON-FINANCIAL COMPANIES: [bold]$1.77 TRILLION[/] IN CASH",
"forceHidden": false,
"centerY": {
"type": "Percent",
"value": 100
},
"paddingBottom": 6,
"__parse": true
},
"__parse": true
},
{
"id": "Non-tech companies",
"fill": {
"type": "Color",
"value": "#67b7dc"
},
"__parse": true
},
{
"id": "Tech companies",
"fill": {
"type": "Color",
"value": "#67b7dc"
},
"__parse": true
},
{
"id": "Cash in the U.S.",
"fill": {
"type": "Color",
"value": "#a367dc"
},
"labelSettings": {
"text": "CASH IN THE U.S.\n[bold]$459 BILLION",
"forceHidden": false,
"centerY": 0,
"paddingTop": 6
},
"__parse": true
},
{
"id": "Cash overseas",
"fill": {
"type": "Color",
"value": "#dc6788"
},
"labelSettings": {
"text": "CASH OVERSEAS\n[bold]$1.31 TRILLION",
"forceHidden": false,
"centerY": 0,
"paddingTop": 6
},
"__parse": true
},
{
"id": "Rest of tech",
"fill": {
"type": "Color",
"value": "#67b7dc"
},
"__parse": true
},
{
"id": "Top 5 tech companies",
"fill": {
"type": "Color",
"value": "#67b7dc"
},
"__parse": true
},
{
"id": "Joytechs",
"fill": {
"type": "Color",
"value": "#67b7dc"
},
"__parse": true
},
{
"id": "Fireex",
"fill": {
"type": "Color",
"value": "#67b7dc"
},
"__parse": true
},
{
"id": "Globalworld",
"fill": {
"type": "Color",
"value": "#67b7dc"
},
"__parse": true
},
{
"id": "Betagate",
"fill": {
"type": "Color",
"value": "#67b7dc"
},
"__parse": true
},
{
"id": "Apexi",
"fill": {
"type": "Color",
"value": "#67b7dc"
},
"__parse": true
}
],
"rectangles": {
"properties": {
"template": {
"settings": {
"fillOpacity": 0,
"strokeOpacity": 0
}
}
}
},
"labels": {
"properties": {
"template": {
"settings": {
"forceHidden": true,
"textAlign": "center",
"templateField": "labelSettings"
}
}
}
}
}
},
"bullets": [
{
"type": "Bullet",
"settings": {
"locationY": 0.5,
"sprite": {
"type": "Label",
"settings": {
"templateField": "labelSettings",
"fill": {
"type": "Color",
"value": "#000000"
},
"fontSize": "0.85em",
"textAlign": "center",
"centerX": {
"type": "Percent",
"value": 50
},
"centerY": {
"type": "Percent",
"value": 50
},
"paddingTop": 0,
"paddingBottom": 0
}
}
}
},
{
"type": "Bullet",
"settings": {
"locationY": 1,
"sprite": {
"type": "Label",
"settings": {
"templateField": "companyLabel",
"fill": {
"type": "Color",
"value": "#000000"
},
"fontSize": "0.75em",
"rotation": -90,
"centerX": 0,
"centerY": {
"type": "Percent",
"value": 50
},
"paddingLeft": 5,
"paddingTop": 0,
"paddingBottom": 0
}
}
}
}
]
}
}
}
]
}