Skip to content

Wrapping, truncating, and auto-rotating axis labels

This tutorial will explain how you can deal with very long axis labels, by wrapping and/or truncating them.

If you haven’t done that already, we suggest you take a look at the “Positioning Axis Elements” article, which explains the principles about configuring Axis elements, including the concept of “axis renderer”. Moving forward we will assume you are familiar with the idea, that almost every appearance setting for an axis is added via its renderer property.

Furthermore, this tutorial also uses “list templates”. Make sure you take a brief look at the “List templates” article for an introduction to this powerful concept.

Let’s start off with a basic chart, that has very long labels on its Category axis:

Open in CodePen

Looks cool? Not really.

Let’s see how we can fix that.

The first solution that comes into mind is: “let’s make labels wrap so they are not overlapping”.

To make that happen, we will need to modify axis label template object. For an axis, this template is stored in its Renderer: axis.renderer.labels.template.

An axis label is an object of type Label. Click the link on it to explore it’s all options.

For now, to make our labels wrap we will need its two options: wrap and maxWidth.

The first one is obvious - it’s a boolean setting indicating whether labels should wrap. The second gives a width threshold for the label, so that it knows how much width it has available.

Let’s try it:

let label = categoryAxis.renderer.labels.template;
label.wrap = true;
label.maxWidth = 120;
var label = categoryAxis.renderer.labels.template;
label.wrap = true;
label.maxWidth = 120;
{
// ...
"xAxes": [{
// ...
"renderer": {
"labels": {
"wrap": true,
"maxWidth": 120
}
}
}]
}
Open in CodePen

Wrapping labels made them readable, but they also made them tall, resulting in chart itself being flattened next to nothing. Not particularly good.

Let’s try to make labels auto-truncate.

We’ll still need to set the maximum width of the label using maxWidth. However, instead of telling it to wrap, we’ll tell it to truncate the text by setting its truncate property.

let label = categoryAxis.renderer.labels.template;
label.truncate = true;
label.maxWidth = 120;
var label = categoryAxis.renderer.labels.template;
label.truncate = true;
label.maxWidth = 120;
{
// ...
"xAxes": [{
// ...
"renderer": {
"labels": {
"truncate": true,
"maxWidth": 120
}
}
}]
}
Open in CodePen

Now, as we say here “the wolf is fed, yet the sheep is alive”. We don’t sacrifice the height of the chart itself, yet we retain part of the labels, giving users an idea of what this category is about.

By default, labels are truncated with a triple-dot for an ellipsis. You can use label’s ellipsis property to set it to any other string.

Now that we have truncated the labels, we are concealing part of the information from our users.

Let’s set the labels up to display a tooltip when user rolls over the label with a mouse cursor or taps it on a touch screen.

Any element in amCharts 4 has a property tooltipText. If it’s set, a tooltip will appear when hovering the element.

We can set it to some static text, or we can use dynamic placeholders, that can draw data from related data item and even elements own properties and data. Since we know Category axis’ labels have data item with a category property, we can use the placeholder "{category}" in label template’s tooltipText:

let label = categoryAxis.renderer.labels.template;
label.truncate = true;
label.maxWidth = 120;
label.tooltipText = "{category}";
var label = categoryAxis.renderer.labels.template;
label.truncate = true;
label.maxWidth = 120;
label.tooltipText = "{category}";
{
// ...
"xAxes": [{
// ...
"renderer": {
"labels": {
"truncate": true,
"maxWidth": 120,
"tooltipText": "{category}"
}
}
}]
}

That’s it. Now hovering over the label will display full text of the truncated label. Go ahead, try it out on a below chart:

Open in CodePen

Labels are too big even for a tooltip? Let’s fix that by constraining tooltip width and making it auto-wrap:

categoryAxis.tooltip.label.maxWidth = 200;
categoryAxis.tooltip.label.wrap = true;

All of the above solutions involved hard-coded maxWidth value.

Let’s take it one step further and make it fully automatic: so that maxWidth is always set to actual available space.

For that we are going to be utilizing axis’ sizechanged event, which kicks in whenever axis size changes.

When that happens we will calculate actual width in pixels, take into account how many categories are there on the screen right now, and div it all up to find out a perfect maxWidth.

categoryAxis.events.on("sizechanged", function(ev) { let axis = ev.target; let cellWidth = axis.pixelWidth / (axis.endIndex - axis.startIndex); axis.renderer.labels.template.maxWidth = cellWidth;});

Now, whatever data you throw at the chart, it will adapt and crop the labels accordingly:

Open in CodePen

(Try to open the above chart in a new window and play around with its size)

Building on the previous example, let’s make the sizechanged event work to automatically rotate labels if they do not fit into specific cell width.

categoryAxis.events.on("sizechanged", function(ev) {
let axis = ev.target;
var cellWidth = axis.pixelWidth / (axis.endIndex - axis.startIndex);
if (cellWidth < axis.renderer.labels.template.maxWidth) {
axis.renderer.labels.template.rotation = -45;
axis.renderer.labels.template.horizontalCenter = "right";
axis.renderer.labels.template.verticalCenter = "middle";
}
else {
axis.renderer.labels.template.rotation = 0;
axis.renderer.labels.template.horizontalCenter = "middle";
axis.renderer.labels.template.verticalCenter = "top";
}
});
Open in CodePen

So far we have been using sizechanged event to resize labels when actual width of the chart container changed.

However, zooming the axis would also change number and thus available width for the labels, too.

So, to handle both events, we should execute our label sizing code on axis’ startendchanged event, as well.