A stacked chart on its side: each bar is a year’s total, split into six regions and labeled segment by segment. Bars leave room for long names and long lists.
Stacked bars do what stacked columns do, with the categories down the side: easier for long names and long lists, and natural for rankings read from top to bottom. As in any stack, the totals and the first segments compare easily, the segments further along less so.
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");
var myTheme = am5.Theme.new(root);
// the grid line at zero, normally darker, as faint as the others
myTheme.rule("Grid", ["base"]).setAll({
strokeOpacity: 0.1
});
// Set themes
// https://www.amcharts.com/docs/v5/concepts/themes/
root.setThemes([
am5themes_Animated.new(root),
myTheme,
am5themes_Responsive.new(root)
]);
// Create chart
// https://www.amcharts.com/docs/v5/charts/xy-chart/
var chart = root.container.children.push(am5xy.XYChart.new(root, {
panX: false, // no panning
panY: false,
paddingLeft: 0, // no gap at the chart's left edge
layout: root.verticalLayout // the legend goes below the plot
}));
var data = [{
"year": "2023",
"europe": 2.5,
"namerica": 2.5,
"asia": 2.1,
"lamerica": 1,
"meast": 0.8,
"africa": 0.4
}, {
"year": "2024",
"europe": 2.6,
"namerica": 2.7,
"asia": 2.2,
"lamerica": 0.5,
"meast": 0.4,
"africa": 0.3
}, {
"year": "2025",
"europe": 2.8,
"namerica": 2.9,
"asia": 2.4,
"lamerica": 0.3,
"meast": 0.9,
"africa": 0.5
}]
// Create axes
// https://www.amcharts.com/docs/v5/charts/xy-chart/axes/
var yRenderer = am5xy.AxisRendererY.new(root, {});
var yAxis = chart.yAxes.push(am5xy.CategoryAxis.new(root, {
categoryField: "year",
renderer: yRenderer,
tooltip: am5.Tooltip.new(root, {})
}));
yRenderer.grid.template.setAll({
location: 1 // grid lines between the years, not through the middle of each
})
yAxis.data.setAll(data);
var xAxis = chart.xAxes.push(am5xy.ValueAxis.new(root, {
min: 0, // the bars start at zero
// whole numbers only in the axis labels
maxPrecision: 0,
renderer: am5xy.AxisRendererX.new(root, {
minGridDistance: 40, // at least 40px between the labels
strokeOpacity: 0.1 // a faint axis line
})
}));
// Add legend
// https://www.amcharts.com/docs/v5/charts/xy-chart/legend-xy-series/
var legend = chart.children.push(am5.Legend.new(root, {
centerX: am5.p50, // centered...
x: am5.p50 // ...under the chart
}));
// no cursor, so no values for the legend: without the empty value labels its items stay compact
legend.valueLabels.template.set("forceHidden", true);
// Add series
// https://www.amcharts.com/docs/v5/charts/xy-chart/series/
// adds the bars of one region, stacked on the regions added before
function makeSeries(name, fieldName) {
var series = chart.series.push(am5xy.ColumnSeries.new(root, {
name: name,
stacked: true, // the main trick: each bar starts where the one before it ends
xAxis: xAxis,
yAxis: yAxis,
// the bars grow sideways from the year axis, and stack along X
baseAxis: yAxis,
valueXField: fieldName,
categoryYField: "year"
}));
series.columns.template.setAll({
tooltipText: "{name}, {categoryY}: {valueX}", // hover a bar for its region, year and value
tooltipY: am5.percent(90) // the tooltip points near the bar's bottom edge, not its middle
});
series.data.setAll(data);
// Make stuff animate on load
// https://www.amcharts.com/docs/v5/concepts/animations/
series.appear();
// the value in the middle of each bar
series.bullets.push(function () {
return am5.Bullet.new(root, {
sprite: am5.Label.new(root, {
text: "{valueX}",
fill: root.interfaceColors.get("alternativeText"), // the theme's text color for use on colored fills
centerY: am5.p50, // centered on the bar...
centerX: am5.p50, // ...both ways
populateText: true // fill in {valueX} from the data
})
});
});
legend.data.push(series);
}
makeSeries("Europe", "europe");
makeSeries("North America", "namerica");
makeSeries("Asia", "asia");
makeSeries("Latin America", "lamerica");
makeSeries("Middle East", "meast");
makeSeries("Africa", "africa");
// Make stuff animate on load
// https://www.amcharts.com/docs/v5/concepts/animations/
chart.appear(1000, 100);
{
"type": "XYChart",
"settings": {
"panX": false,
"panY": false,
"paddingLeft": 0,
"layout": {
"type": "VerticalLayout"
}
},
"properties": {
"series": [
"#series-0",
"#series-1",
"#series-2",
"#series-3",
"#series-4",
"#series-5"
],
"xAxes": [
"#axis-0"
],
"yAxes": [
"#axis-1"
]
},
"children": [
{
"type": "Legend",
"settings": {
"centerX": {
"type": "Percent",
"value": 50
},
"x": {
"type": "Percent",
"value": 50
}
},
"properties": {
"data": [
"#series-0",
"#series-1",
"#series-2",
"#series-3",
"#series-4",
"#series-5"
],
"valueLabels": {
"properties": {
"template": {
"settings": {
"forceHidden": true
}
}
}
}
}
}
],
"refs": [
{
"data-0": [
{
"year": "2023",
"europe": 2.5,
"namerica": 2.5,
"asia": 2.1,
"lamerica": 1,
"meast": 0.8,
"africa": 0.4
},
{
"year": "2024",
"europe": 2.6,
"namerica": 2.7,
"asia": 2.2,
"lamerica": 0.5,
"meast": 0.4,
"africa": 0.3
},
{
"year": "2025",
"europe": 2.8,
"namerica": 2.9,
"asia": 2.4,
"lamerica": 0.3,
"meast": 0.9,
"africa": 0.5
}
]
},
{
"axis-0": {
"type": "ValueAxis",
"settings": {
"min": 0,
"maxPrecision": 0,
"renderer": {
"type": "AxisRendererX",
"settings": {
"minGridDistance": 40,
"strokeOpacity": 0.1
}
}
}
}
},
{
"axis-1": {
"type": "CategoryAxis",
"settings": {
"categoryField": "year",
"renderer": {
"type": "AxisRendererY",
"properties": {
"grid": {
"properties": {
"template": {
"settings": {
"location": 1
}
}
}
}
}
},
"tooltip": {
"type": "Tooltip"
}
},
"properties": {
"data": "#data-0"
}
}
},
{
"series-0": {
"type": "ColumnSeries",
"settings": {
"name": "Europe",
"stacked": true,
"xAxis": "#axis-0",
"yAxis": "#axis-1",
"baseAxis": "#axis-1",
"valueXField": "europe",
"categoryYField": "year"
},
"properties": {
"data": "#data-0",
"columns": {
"properties": {
"template": {
"settings": {
"tooltipText": "{name}, {categoryY}: {valueX}",
"tooltipY": {
"type": "Percent",
"value": 90
}
}
}
}
},
"bullets": [
{
"type": "Bullet",
"settings": {
"sprite": {
"type": "Label",
"settings": {
"text": "{valueX}",
"fill": "@root.interfaceColors.get('alternativeText')",
"centerY": {
"type": "Percent",
"value": 50
},
"centerX": {
"type": "Percent",
"value": 50
},
"populateText": true
}
}
}
}
]
}
}
},
{
"series-1": {
"type": "ColumnSeries",
"settings": {
"name": "North America",
"stacked": true,
"xAxis": "#axis-0",
"yAxis": "#axis-1",
"baseAxis": "#axis-1",
"valueXField": "namerica",
"categoryYField": "year"
},
"properties": {
"data": "#data-0",
"columns": {
"properties": {
"template": {
"settings": {
"tooltipText": "{name}, {categoryY}: {valueX}",
"tooltipY": {
"type": "Percent",
"value": 90
}
}
}
}
},
"bullets": [
{
"type": "Bullet",
"settings": {
"sprite": {
"type": "Label",
"settings": {
"text": "{valueX}",
"fill": "@root.interfaceColors.get('alternativeText')",
"centerY": {
"type": "Percent",
"value": 50
},
"centerX": {
"type": "Percent",
"value": 50
},
"populateText": true
}
}
}
}
]
}
}
},
{
"series-2": {
"type": "ColumnSeries",
"settings": {
"name": "Asia",
"stacked": true,
"xAxis": "#axis-0",
"yAxis": "#axis-1",
"baseAxis": "#axis-1",
"valueXField": "asia",
"categoryYField": "year"
},
"properties": {
"data": "#data-0",
"columns": {
"properties": {
"template": {
"settings": {
"tooltipText": "{name}, {categoryY}: {valueX}",
"tooltipY": {
"type": "Percent",
"value": 90
}
}
}
}
},
"bullets": [
{
"type": "Bullet",
"settings": {
"sprite": {
"type": "Label",
"settings": {
"text": "{valueX}",
"fill": "@root.interfaceColors.get('alternativeText')",
"centerY": {
"type": "Percent",
"value": 50
},
"centerX": {
"type": "Percent",
"value": 50
},
"populateText": true
}
}
}
}
]
}
}
},
{
"series-3": {
"type": "ColumnSeries",
"settings": {
"name": "Latin America",
"stacked": true,
"xAxis": "#axis-0",
"yAxis": "#axis-1",
"baseAxis": "#axis-1",
"valueXField": "lamerica",
"categoryYField": "year"
},
"properties": {
"data": "#data-0",
"columns": {
"properties": {
"template": {
"settings": {
"tooltipText": "{name}, {categoryY}: {valueX}",
"tooltipY": {
"type": "Percent",
"value": 90
}
}
}
}
},
"bullets": [
{
"type": "Bullet",
"settings": {
"sprite": {
"type": "Label",
"settings": {
"text": "{valueX}",
"fill": "@root.interfaceColors.get('alternativeText')",
"centerY": {
"type": "Percent",
"value": 50
},
"centerX": {
"type": "Percent",
"value": 50
},
"populateText": true
}
}
}
}
]
}
}
},
{
"series-4": {
"type": "ColumnSeries",
"settings": {
"name": "Middle East",
"stacked": true,
"xAxis": "#axis-0",
"yAxis": "#axis-1",
"baseAxis": "#axis-1",
"valueXField": "meast",
"categoryYField": "year"
},
"properties": {
"data": "#data-0",
"columns": {
"properties": {
"template": {
"settings": {
"tooltipText": "{name}, {categoryY}: {valueX}",
"tooltipY": {
"type": "Percent",
"value": 90
}
}
}
}
},
"bullets": [
{
"type": "Bullet",
"settings": {
"sprite": {
"type": "Label",
"settings": {
"text": "{valueX}",
"fill": "@root.interfaceColors.get('alternativeText')",
"centerY": {
"type": "Percent",
"value": 50
},
"centerX": {
"type": "Percent",
"value": 50
},
"populateText": true
}
}
}
}
]
}
}
},
{
"series-5": {
"type": "ColumnSeries",
"settings": {
"name": "Africa",
"stacked": true,
"xAxis": "#axis-0",
"yAxis": "#axis-1",
"baseAxis": "#axis-1",
"valueXField": "africa",
"categoryYField": "year"
},
"properties": {
"data": "#data-0",
"columns": {
"properties": {
"template": {
"settings": {
"tooltipText": "{name}, {categoryY}: {valueX}",
"tooltipY": {
"type": "Percent",
"value": 90
}
}
}
}
},
"bullets": [
{
"type": "Bullet",
"settings": {
"sprite": {
"type": "Label",
"settings": {
"text": "{valueX}",
"fill": "@root.interfaceColors.get('alternativeText')",
"centerY": {
"type": "Percent",
"value": 50
},
"centerX": {
"type": "Percent",
"value": 50
},
"populateText": true
}
}
}
}
]
}
}
}
]
}