Is it possible to position Highcharts dataLabels depending on the value?

35,550

Solution 1

Looks like it's not possible to do that from within the formatter.

But you could set them after the chart is rendered (loaded). Try something like this

$.each(chartObj.series[0].data, function(i, point) {
    if(point.y > 100) {
        point.dataLabel.attr({x:20});
    }
});

in the load callback (or if you need it in the redraw callback).

See example here.

Solution 2

Here's what I ended up with. The setTimeout is necessary or the dataLabel property doesn't exist on the point:

formatter: function () {
    var point = this.point;
    window.setTimeout(function () {
        if (point.s < 0) {
            point.dataLabel.attr({
                y: point.plotY + 20
            });
        }
    });
    //this.series.options.dataLabels.y = -6;
    var sty = this.point.s < 0 ? 'color:#d00' : 'color:#090;' //other style has no effect:(
    return '<span style="' + sty + '">' + Math.abs(this.point.s) + '</span>';
}

Solution 3

Although Bhesh's answer solves the problem for x/y positioning, Highcharts ignores any changes to the style property of dataLabels (see the problem here). However, you can override the styles of an individual point by passing it through the data object:

series: [{ data: [29.9, 106, { y: 135, dataLabels: { style: { fontSize: 20 } } }]

example from Highcharts docs

I was able to get dynamic styles by iterating over my data before passing the whole object to Highcharts to render.

Share:
35,550
3rgo
Author by

3rgo

Computer Science Engineer, specialized in Web development. Work : 2011-2016: Intranet tools development for Airbus France (Single page JS apps, with a PHP5+Symfony 2 REST API ; custom made Ruby CI/CD pipeline). 2016-2018: Project Manager/CTO for Decasoft 2019+: Freelance web developer (Symfony, Laravel, ReactJS) and Trainer (PHP, OOP, Algorithmics, JS) Tech Stack: PHP 5 to 8 Symfony, Laravel Laravel Livewire PHPUnit Javascript ReactJS AlpineJS MeteorJS (in progress) jQuery, Underscore/Lodash, MomentJS, D3.js, Leaflet MySQL, PostgreSQL, mongoDB (in progress) Bootstrap, MaterialUI, TailwindCSS Jenkins, Git Apache, NGINX Windows, Ubuntu, macOS Python, Bash

Updated on May 03, 2022

Comments

  • 3rgo
    3rgo 9 days

    I'm using Highcharts to display a bar chart, with 2 bars overlaying each other, and a dataLabels at the right of them, displaying the exact value.

    The problem here is that when the value is above 80%, the label is overflowing from the chart into the frame, going over some other text, and making them both unreadable.

    Here are my plotOptions :

    plotOptions: {
                bar: {
                    groupPadding: 0.5,
                    pointWidth : 30,
                    borderWidth: 0,
                    dataLabels: {
                        enabled: true,
                        y:-5,
                        color:"black",
                        style: {
                            fontSize: "12px"
                        },
                        formatter: function(){
                            if(this.y > 80)
                            {
                                this.series.chart.options.plotOptions.bar.dataLabels.x -= 20;
                            }
                            if(this.series.name == "Tests OK")
                                return "Tests OK : <strong>"+Math.round(this.y*10)/10+"%</strong>";
                            else
                                return "<br/>Tests Executed : <strong>"+Math.round(this.y*10)/10+"%</strong>";
                        }
                    }
                }
            }
    

    I thought i could edit the chart options on the go, using this.series.chart.options.plotOptions.bar.dataLabels.x -= 20;, but this doesn't work.

    Surely I'm not the first one who has encountered a problem like that. Any idea ?

    Thanks

  • 3rgo
    3rgo over 10 years
    Thanks for the answer, but this doesn't work either. By logging this.series into the formatter, i can see that the line is taken into account, because the dataLabels.x is in fact equal to -20, but no change in the display...
  • Geoffrey Litt almost 9 years
    I used this technique and it worked great. Thanks for the tip!
  • lamarant
    lamarant over 7 years
    This works great. Worth noting that the formatter function should exist within {plotOptions:dataLabels}