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
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>';
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With