I am coding my first amcharts4 stacked chart from this example https://www.amcharts.com/demos/100-stacked-column-chart/ but I have a problem with adding the total label above every column (total like simple sum of values, not percentages).
2 Answers
The way to do this is to create a LabelBullet
on the last, stacked series, position it outside of the chart, e.g. dy = -20
.
To get it to be visible outside the chart, set chart.maskBullets = false
, otherwise it'll get clipped.
To display totals, make sure to have the relevant axis calculate them in advance e.g. via valueAxis.calculateTotals = true;
(this only available for stacked series). Then on the label's text
, use the .total
placeholder, in the demo below it'd be labelBullet.label.text = {valueY.total};
.
Sample code:
// Enable .total and .totalPercent placeholders for stacked series
valueAxis.calculateTotals = true;
// Allow labels to show beyond chart area
chart.maskBullets = false;
// Create a LabelBullet for the top, stacked series
var labelBullet = series3.bullets.push(new am4charts.LabelBullet());
var label = labelBullet.label;
label.text = "{valueY.total}";
label.dy = -20;
Below is a fork of our 100% Stacked Column Chart with the above code:
https://codepen.io/team/amcharts/pen/c06396113836bb29024713d8bac5c883
In this fork I've disabled the scrollbar for convenience. If you enable it, remember to shift it upwards, too, e.g. chart.scrollbarX.dy = -25;
. Otherwise it'll overlay the LabelBullet
s.
There used to be totalText
you can use to achieve exactly what you want in amchart3
: https://stackoverflow.com/a/47722320/2410655, but I don't know if it would be available in amchart4
.
To workaround, my idea is to have 2 CategoryAxis
and they're opposite of each other, and have one of the CategoryAxis
to display the totals of each category.
Change of your data
You need to include a data field for the totals of each category. You can calculate that and add it to the data either manually, or with JavaScript loops:
let data = [
{
category: "One",
value1: 1,
value2: 5,
value3: 3,
total: 9
},
{
category: "Two",
value1: 2,
value2: 5,
value3: 3,
total: 10
},
{
category: "Three",
value1: 3,
value2: 5,
value3: 4,
total: 12
},
{
category: "Four",
value1: 4,
value2: 5,
value3: 6,
total: 15
},
{
category: "Five",
value1: 3,
value2: 5,
value3: 4,
total: 12
},
{
category: "Six",
value1: 2,
value2: 13,
value3: 1,
total: 16
}
];
Add another opposite Category xAxis
The trick here to display the total is to have another category axis on the opposite position, and use adapter
to change its label to display the total numbers:
let chart = am4core.createFromConfig({
data: data,
...,
xAxes: [{
type: "CategoryAxis",
dataFields: {
category: "category"
},
...
}, {
type: "CategoryAxis",
dataFields: {
category: "category"
},
renderer: {
...,
opposite: true,
labels: {
adapter: {
text: function(label, target, key) {
return "Total: {total}";
}
}
}
}
}],
...
}, "chart", am4charts.XYChart);
I had tried to have another category axis to display total
directly, like:
xAxes: [{
type: "CategoryAxis",
dataFields: {
category: "category"
},
...
}, {
type: "CategoryAxis",
dataFields: {
category: "total"
},
...
}]
That failed because category axis automatically merged duplicates (for example, total 12 from category "Three" and "Five") and resulted in missing numbers.