Clustered Bar Chart
Clustered Bar Chart (also known as Grouped bar chart, Multi-series bar chart) is great for displaying and comparing multiple sets of data over the same categories (like sales revenue of various departments of the company over several years).
Key implementation details
Clustered is the default behavior for the column/bar chart, so you don’t have to do anything extra to achieve the “clustering”.
To make a horizontal Bar chart (as opposed to a vertical Column chart) we set yAxis
to be a CategoryAxis
and xAxis
to a ValueAxis
. Accordingly, we set valueXField
and categoryYField
properties on the series, so they know that categories go along the Y axis and values along the X.
Normally, axes start at the 0 point (bottom-left) but in this case we wanted years to go from top to bottom. To achieve this, we’ve set inversed: true
on the category axis renderer.
Finally, to make bars appear in a sequenced animation (one-by-one and not all at once) we enable sequencedInterpolation
on the series.
Related tutorials
Demo source
<!-- Styles -->
<style>
#chartdiv {
width: 100%;
height: 500px;
}
</style>
<!-- Resources -->
<script src="https://cdn.amcharts.com/lib/5/index.js"></script>
<script src="https://cdn.amcharts.com/lib/5/xy.js"></script>
<script src="https://cdn.amcharts.com/lib/5/themes/Animated.js"></script>
<!-- Chart code -->
<script>
am5.ready(function() {
// 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)
]);
// Create chart
// https://www.amcharts.com/docs/v5/charts/xy-chart/
var chart = root.container.children.push(am5xy.XYChart.new(root, {
panX: false,
panY: false,
wheelX: "panX",
wheelY: "zoomX",
paddingLeft:0,
layout: root.verticalLayout
}));
// 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,
x: am5.p50
}))
// Data
var data = [{
year: "2017",
income: 23.5,
expenses: 18.1
}, {
year: "2018",
income: 26.2,
expenses: 22.8
}, {
year: "2019",
income: 30.1,
expenses: 23.9
}, {
year: "2020",
income: 29.5,
expenses: 25.1
}, {
year: "2021",
income: 24.6,
expenses: 25
}];
// Create axes
// https://www.amcharts.com/docs/v5/charts/xy-chart/axes/
var yAxis = chart.yAxes.push(am5xy.CategoryAxis.new(root, {
categoryField: "year",
renderer: am5xy.AxisRendererY.new(root, {
inversed: true,
cellStartLocation: 0.1,
cellEndLocation: 0.9,
minorGridEnabled: true
})
}));
yAxis.data.setAll(data);
var xAxis = chart.xAxes.push(am5xy.ValueAxis.new(root, {
renderer: am5xy.AxisRendererX.new(root, {
strokeOpacity: 0.1,
minGridDistance: 50
}),
min: 0
}));
// Add series
// https://www.amcharts.com/docs/v5/charts/xy-chart/series/
function createSeries(field, name) {
var series = chart.series.push(am5xy.ColumnSeries.new(root, {
name: name,
xAxis: xAxis,
yAxis: yAxis,
valueXField: field,
categoryYField: "year",
sequencedInterpolation: true,
tooltip: am5.Tooltip.new(root, {
pointerOrientation: "horizontal",
labelText: "[bold]{name}[/]\n{categoryY}: {valueX}"
})
}));
series.columns.template.setAll({
height: am5.p100,
strokeOpacity: 0
});
series.bullets.push(function () {
return am5.Bullet.new(root, {
locationX: 1,
locationY: 0.5,
sprite: am5.Label.new(root, {
centerY: am5.p50,
text: "{valueX}",
populateText: true
})
});
});
series.bullets.push(function () {
return am5.Bullet.new(root, {
locationX: 1,
locationY: 0.5,
sprite: am5.Label.new(root, {
centerX: am5.p100,
centerY: am5.p50,
text: "{name}",
fill: am5.color(0xffffff),
populateText: true
})
});
});
series.data.setAll(data);
series.appear();
return series;
}
createSeries("income", "Income");
createSeries("expenses", "Expenses");
// 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,
x: am5.p50
}));
legend.data.setAll(chart.series.values);
// Add cursor
// https://www.amcharts.com/docs/v5/charts/xy-chart/cursor/
var cursor = chart.set("cursor", am5xy.XYCursor.new(root, {
behavior: "zoomY"
}));
cursor.lineY.set("forceHidden", true);
cursor.lineX.set("forceHidden", true);
// Make stuff animate on load
// https://www.amcharts.com/docs/v5/concepts/animations/
chart.appear(1000, 100);
}); // end am5.ready()
</script>
<!-- HTML -->
<div id="chartdiv"></div>