Search code examples
javascriptamcharts

Hide legend label on AmChart4


I am using amchart line graph.

I want to hide amchart legend label on the graph.

I struggled to find out that there are items related to labels

console.log(chart.legend.labels.values);
console.log(chart.legend.labels.values.length)// somehow 0....

  for (key in this.chart.legend.labels.values){ // it doesn't loop...
    this.chart.legend.labels.values[key].hide();
  }

How can I hide the legend labels??

enter image description here


Solution

  • The short answer:

    chart.legend.labels.template.disabled = true;
    

    Demo:

    https://codepen.io/team/amcharts/pen/17e8f139f06008c69ee45130718d5324

    Getting to know amCharts v4's ListTemplate concept will help to understand why this answer works and how to use such an object like chart.legend.labels in the case you wanted to iterate over it.

    A ListTemplate basically uses an actual instance of an object/Class as the template for all future such objects that it will generate, it stores this in its template property. chart.legend.labels is a ListTemplate for/of Labels.

    By default, a chart's legend will refer to the charts' series to automatically generate legend items, it will clone chart.legend.markers.template and chart.legend.labels.template and then populate the clones with series' colors/data. So if the original label is disabled, it will be:

    "hidden, ... removed from any processing, layout calculations, and generally treated as if it does not exist."

    This is what we want, as .hide() could just visually hide the text, yet still occupy the same space (thinking in CSS terms, it's a lot like display: none vs visibility: hidden).

    The above process is asynchronous. It's why your code, chart.legend.labels.values.length, returns 0 if run straight away in the source, but the expected number if run directly in the console later on. If you wanted to iterate over the legend items or labels, you'd have to wait for them to be rendered, then use its each() method (instead of looping through values), e.g.:

    chart.legend.events.on("inited", function() {
        chart.legend.labels.each(function(label) {
            // Do something related to this specific label
        });
    });
    

    In the above code, we wait for the legend itself to grab its data, parse, and render, then we check the populated labels for whatever it is we want to do.

    By using the template in advance, we ignore the asynchronous nature altogether. If you want to apply settings on all legend labels after the fact, in the case of chart.legend.labels.template, it already has applyOnClones set to true, so you could toggle chart.legend.labels.template.disabled between true and false at any time during your app and it would hide/show the legend's labels instantly each time, updating its layout accordingly.