Skip to content

Map heat legend with real start/end value labels

A Heat legend uses regular axis to display value range/scale. For narrower setups it might mean that there are not real start/end labels. This tutorial will show how to remedy that.

HeatLegend uses real ValueAxis to display value labels. Value axis come with its certain logic how labels are spaced, positioned, and rounded to “pretty” numbers.

In some cases that might result in oddly looking legend:

Let’s see how we can achieve that.

First of all, we need to get rid of the automatically-calculate labels.

For that we can set up an “adapter” to return empty text:

heatLegend.valueAxis.renderer.labels.template.adapter.add("text", function(labelText) {
return "";
});

We are now going to add two labels (in form of “axis ranges”): one for lowest value, the other for highest.

For now we are not going to set their values or text. We’ll get to that later. Empty labels for now.

let minRange = heatLegend.valueAxis.axisRanges.create();
minRange.label.horizontalCenter = "left";
let maxRange = heatLegend.valueAxis.axisRanges.create();
maxRange.label.horizontalCenter = "right";
var minRange = heatLegend.valueAxis.axisRanges.create();
minRange.label.horizontalCenter = "left";
var maxRange = heatLegend.valueAxis.axisRanges.create();
maxRange.label.horizontalCenter = "right";

All we have now left to do is to populate those labels with real values.

Since we need our data parsed and ready before we can know those min and max values, we’re going to be using "datavalidated" event on our polygon series.

polygonSeries.events.on("datavalidated", function(ev) {
let heatLegend = ev.target.map.getKey("heatLegend");
let min = heatLegend.series.dataItem.values.value.low;
let minRange = heatLegend.valueAxis.axisRanges.getIndex(0);
minRange.value = min;
minRange.label.text = "" + heatLegend.numberFormatter.format(min);
let max = heatLegend.series.dataItem.values.value.high;
let maxRange = heatLegend.valueAxis.axisRanges.getIndex(1);
maxRange.value = max;
maxRange.label.text = "" + heatLegend.numberFormatter.format(max);
});
// Set up heat legend
let heatLegend = chart.createChild(am4maps.HeatLegend);
heatLegend.id = "heatLegend";
heatLegend.series = polygonSeries;
heatLegend.align = "right";
heatLegend.valign = "bottom";
heatLegend.width = am4core.percent(35);
heatLegend.marginRight = am4core.percent(4);
heatLegend.background.fill = am4core.color("#000");
heatLegend.background.fillOpacity = 0.05;
heatLegend.padding(5, 5, 5, 5);
// Set up custom heat map legend labels using axis ranges
let minRange = heatLegend.valueAxis.axisRanges.create();
minRange.label.horizontalCenter = "left";
let maxRange = heatLegend.valueAxis.axisRanges.create();
maxRange.label.horizontalCenter = "right";
// Blank out internal heat legend value axis labels
heatLegend.valueAxis.renderer.labels.template.adapter.add("text", function(labelText) {
return "";
});
// Update heat legend value labels
polygonSeries.events.on("datavalidated", function(ev) {
let heatLegend = ev.target.map.getKey("heatLegend");
let min = heatLegend.series.dataItem.values.value.low;
let minRange = heatLegend.valueAxis.axisRanges.getIndex(0);
minRange.value = min;
minRange.label.text = "" + heatLegend.numberFormatter.format(min);
let max = heatLegend.series.dataItem.values.value.high;
let maxRange = heatLegend.valueAxis.axisRanges.getIndex(1);
maxRange.value = max;
maxRange.label.text = "" + heatLegend.numberFormatter.format(max);
});
Open in CodePen