Using label bullets on a horizontal bar chart

This tutorial will show how you can use LabelBullet to decorate your horizontal bar chart with data labels.

Preparing

Prerequisites

This tutorial will rely heavily on using Series' bullets. If you're not familiar on how bullets work in amCharts 4, please go through "Bullets" article first.

Also, since we're going to be binding our labels to data, you might want to brush up on "Text placeholders".

Base chart

We're going to be using this basic chart as a base of our operations throughout this tutorial:

See the Pen amCharts 4: Using label bullets on column series (base chart) by amCharts (@amcharts) on CodePen.24419

Data labels

Adding a label

As you might remember from Bullets tutorial (or not if you're just here for TL;DR) the quickest way to add a data label is to add a bullet of type LabelBullet to your series.

Such bullet will have a property label, which is an object of type Label so that you can configure it every way you want it to be, including appearance and content.

let valueLabel = series.bullets.push(new am4charts.LabelBullet());
valueLabel.label.text = "Hello";
valueLabel.label.fontSize = 20;
var valueLabel = series.bullets.push(new am4charts.LabelBullet());
valueLabel.label.text = "Hello";
valueLabel.label.fontSize = 20;
{
  // ...
  "series": [{
    // ...
    "bullets": [{
      "type": "LabelBullet",
      "label": {
        "text": "Hello",
        "fontSize": 20
      }
    }]
  }]
}

See the Pen amCharts 4: Using label bullets on column series (1) by amCharts (@amcharts) on CodePen.24419

Binding to data

As much as it is useful having word "Hello" strapped to each of the bars, it can be even more useful if we make it show some real, contextual data, such as the value of the adjacent bar.

For that, we can data placeholders in curly brackets:

valueLabel.label.text = "{value}";
valueLabel.label.text = "{value}";
{
  // ...
  "series": [{
    // ...
    "bullets": [{
      "type": "LabelBullet",
      "label": {
        "text": "{value}",
        "fontSize": 20
      }
    }]
  }]
}

See the Pen amCharts 4: Using label bullets on column series (2) by amCharts (@amcharts) on CodePen.24419

Controlling label truncation

Column series automatically sets a maxWidth property for all its labels. It is set to the actual width of the bar. It is done so that label knows the boundaries in case it needs to contain itself within the actual area of a bar/column.

Obviously, for situations where labels are drawn outside bars, it doesn't make much sense.

So, whenever a label does not fit into allotted space, two things might happen:

  1. Label is truncated with an ellipsis;
  2. Or, if there's no space for truncated label at all, it is hidden completely.

The label settings responsible for the above are truncate and hideOversized respectively.

So, if you are seeing label clipping or disappearing labels, simply reset both of the above to false:

valueLabel.label.truncate = false;
valueLabel.label.hideOversized = false;
valueLabel.label.truncate = false;
valueLabel.label.hideOversized = false;
{
  // ...
  "series": [{
    // ...
    "bullets": [{
      "type": "LabelBullet",
      "label": {
        // ...
        "truncate": false,
        "hideOversized": false
      }
    }]
  }]
}

Aligning labels

The thing about bullets (including label bullets) is that they are placed right at the tip of the column/bar. That works for image bullets just fine.

For labels - not so much.

We can remedy that by adjusting alignment of our bullet labels.

Let's see at various ways to do that.

Setting the virtual center of the label

When placing a bullet, the chart tries to align its center with the tip of the bar.

If we could tell the chart where the center of our label is, we'd be golden. Luckily, we can do that.

For that we can use horizontalCenter property of the label (yes, there's also verticalCenter but it's not relevant for the purpose of this tutorial, so we'll just leave it at that).

So, if we'd like our label to go to the left of the bar's end, we can set its center to "left":

valueLabel.label.horizontalCenter = "left";
valueLabel.label.horizontalCenter = "left";
{
  // ...
  "series": [{
    // ...
    "bullets": [{
      "type": "LabelBullet",
      "label": {
        "text": "{value}",
        "fontSize": 20,
        "horizontalCenter" : "left"
      }
    }]
  }]
}

See the Pen amCharts 4: Using label bullets on column series (3) by amCharts (@amcharts) on CodePen.24419

If we'd set it to "right", the label would go inside the bar itself:

See the Pen amCharts 4: Using label bullets on column series (4) by amCharts (@amcharts) on CodePen.24419

Fine-tuning label position

Right now, our labels do not are plopped awkwardly across the middle of the column tip. However, they're still "glued" to it.

Let's give us some breathing space by adjusting their position using dx property.

This property basically means "move the element by X pixels horizontally". Positive value would move it to right. Negative - to left.

valueLabel.label.dx = 10;
valueLabel.label.dx = 10;
{
  // ...
  "series": [{
    // ...
    "bullets": [{
      "type": "LabelBullet",
      "label": {
        "text": "{value}",
        "fontSize": 20,
        "horizontalCenter" : "left",
        "dx": 10
      }
    }]
  }]
}

See the Pen amCharts 4: Using label bullets on column series (5) by amCharts (@amcharts) on CodePen.24419

Positioning within column

Besides modifying where the center of the label is, we can also modify where within column the label will be positioned.

The property that's responsible for horizontal positioning is locationX. For vertical positioning we would be using locationY.

The scale of the available values is from 0 (zero) to 1 (one). With one meaning start of the column and zero meaning the end, which is default for horizontal placement.

So, if we'd like to place our label right in the middle of the column, we'd set locationX = 0.5. To move it to start of the column, we'd use 1.

valueLabel.locationX = 1;
valueLabel.locationX = 1;
{
  // ...
  "series": [{
    // ...
    "bullets": [{
      "type": "LabelBullet",
      "locationX": 1,
      // ...
    }]
  }]
}

See the Pen amCharts 4: Using label bullets on column series (6) by amCharts (@amcharts) on CodePen.24419

IMPORTANT There area some caveats and tricks when placing (label) bullets within column. Those are outlined in "Positioning within column" section of our "Bullets" article. We strongly advise you check them out.

Using multiple labels

Since amCharts 4 doe snot limit you to just a single bullet, you can add as many (distinctively formatted) labels as you like.

Let's add another label to show category:

let valueLabel = series.bullets.push(new am4charts.LabelBullet());
valueLabel.label.text = "{value}";
valueLabel.label.fontSize = 25;
valueLabel.label.horizontalCenter = "left";
valueLabel.label.dx = 10;

let categoryLabel = series.bullets.push(new am4charts.LabelBullet());
categoryLabel.label.text = "{category}";
categoryLabel.label.fontSize = 20;
categoryLabel.label.horizontalCenter = "right";
categoryLabel.label.dx = -10;
categoryLabel.label.fill = am4core.color("#fff");
var valueLabel = series.bullets.push(new am4charts.LabelBullet());
valueLabel.label.text = "{value}";
valueLabel.label.fontSize = 25;
valueLabel.label.horizontalCenter = "left";
valueLabel.label.dx = 10;

var categoryLabel = series.bullets.push(new am4charts.LabelBullet());
categoryLabel.label.text = "{category}";
categoryLabel.label.fontSize = 20;
categoryLabel.label.horizontalCenter = "right";
categoryLabel.label.dx = -10;
categoryLabel.label.fill = am4core.color("#fff");
{
  // ...
  "series": [{
    // ...
    "bullets": [{
      "type": "LabelBullet",
      "label": {
        "text": "{value}",
        "fontSize": 25,
        "horizontalCenter": "left",
        "dx": 10
      }
    }, {
      "type": "LabelBullet",
      "label": {
        "text": "{category}",
        "fontSize": 20,
        "horizontalCenter": "right",
        "dx": -10,
        "fill": "#fff"
      }
    }]
  }]
}

See the Pen amCharts 4: Using label bullets on column series (7) by amCharts (@amcharts) on CodePen.24419

NOTE The above demo has Category axis labels disabled via categoryAxis.renderer.labels.template.disabled = true.

Fixing clipped labels

Sometimes, if your label bullet does not fit into plot area, it will be clipped.

To fix that set maskBullets = false for your chart.

You might also want to add some padding for your chart to accommodate the labels, protruding from the chart, using paddingLeft.

chart.maskBullets = false
chart.paddingLeft = 30;
chart.maskBullets = false
chart.paddingLeft = 30;
{
  // ...
  "maskBullets": false,
  "paddingLeft": 30
}

Alternative to bullets

As an alternative to bullet-label approach, you can just use columns as containers to push labels into it:

let valueLabel = series.columns.template.createChild(am4core.Label);
valueLabel.text = "{value}";
valueLabel.fontSize = 20;
valueLabel.valign = "middle";
valueLabel.dx = 10;
valueLabel.strokeWidth = 0;
var valueLabel = series.columns.template.createChild(am4core.Label);
valueLabel.text = "{value}";
valueLabel.fontSize = 20;
valueLabel.valign = "middle";
valueLabel.dx = 10;
valueLabel.strokeWidth = 0;
{
  // ...
  "series": {
    // ...
    "columns": {
      // ...
      "children": [{
        "type": "Label",
        "text": "{value}",
        "fontSize": 20,
        "valign": "middle",
        "dx": 10,
        "strokeWidth": 0
      }]
    }
  }
}

See the Pen amCharts 4: Using label bullets on column series (6) by amCharts team (@amcharts) on CodePen.24419