Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

like image 453
3rgo Avatar asked Sep 26 '11 14:09

3rgo


2 Answers

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>';
}
like image 87
jvenema Avatar answered Nov 19 '22 04:11

jvenema


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.

like image 15
Bhesh Gurung Avatar answered Nov 19 '22 03:11

Bhesh Gurung