Totals on column stacks

This tutorial will explain how we can place an automatically-calculated total on a stack of columns.

Preparing value axis

Normally, the chart would not calculate totals, saving CPU for us. We need to enable it by setting calculateTotals: true on our value axis:

let yAxis = chart.yAxes.push(am5xy.ValueAxis.new(root, {
  calculateTotals: true,
  renderer: am5xy.AxisRendererY.new(root, {})
}));
var yAxis = chart.yAxes.push(am5xy.ValueAxis.new(root, {
  calculateTotals: true,
  renderer: am5xy.AxisRendererY.new(root, {})
}));

Adding a label bullet

To place labels on or in a column, we will need to add a bullet with a Label element in it.

Since we only want to single sum, we'll add it to the last series in stack.

We will also use bullet's locationY: 1 setting to ensure the bullet is placed at the end of the last column in stack.

series.bullets.push(function () {
  return am5.Bullet.new(root, {
    locationY: 1,
    sprite: am5.Label.new(root, {
      text: "{valueYTotal}",
      fill: am5.color(0x000000),
      centerY: am5.p100,
      centerX: am5.p50,
      populateText: true
    })
  });
});
series.bullets.push(function () {
  return am5.Bullet.new(root, {
    locationY: 1,
    sprite: am5.Label.new(root, {
      text: "{valueYTotal}",
      fill: am5.color(0x000000),
      centerY: am5.p100,
      centerX: am5.p50,
      populateText: true
    })
  });
});

Please note that value for text setting: "{valueYTotal}".

It refers directly to column's data item values. That's where calculateTotals: true on a value axis comes in handy: if we don't set it, this particular value is not calculated.

The calculateTotals: true is needed for any other calculated data placeholders, like "{valueYTotalPercent}", if we want to use them.

NOTEWe are adding additional series with all-zero values in its data to hold the bullets. We also do not add it to legend. We do this, so that when series are toggled off in legend, the totals bullet stays on.

Bullet clipping

Since we're placing the bullet on top of the column, there might be a situation where bullet would get clipped if it goes outside of the plot area.

There are two things we can do to fight that.

Disable bullet masking

To disable bullet masking that, we need to set maskBullets: false in settings of the series:

let series = chart.series.push(am5xy.ColumnSeries.new(root, {
  name: name,
  xAxis: xAxis,
  yAxis: yAxis,
  valueYField: fieldName,
  categoryXField: "year",
  stacked: true,
  maskBullets: false
}));
var series = chart.series.push(am5xy.ColumnSeries.new(root, {
  name: name,
  xAxis: xAxis,
  yAxis: yAxis,
  valueYField: fieldName,
  categoryXField: "year",
  stacked: true,
  maskBullets: false
}));

Extend axis scale

We can relatively extend value axis scale using its extraMax setting:

var yAxis = chart.yAxes.push(am5xy.ValueAxis.new(root, {
  calculateTotals: true,
  extraMax: 0.1,
  renderer: am5xy.AxisRendererY.new(root, {})
}));
var series = chart.series.push(am5xy.ColumnSeries.new(root, {
var yAxis = chart.yAxes.push(am5xy.ValueAxis.new(root, {
  calculateTotals: true,
  extraMax: 0.1,
  renderer: am5xy.AxisRendererY.new(root, {})
}));

This will expand value axis scale by 10% - just enough to fit our labels for totals.

Example

See the Pen
Totals on top of stacks
by amCharts team (@amcharts)
on CodePen.0

Totals on clustered stacks

Refer to "Totals on clustered column stacks" demo.

Posted in Uncategorized