I've been trying to implement dynamic 'callout' shape datalabels for donut chart using Highcharts javascript library, where notch of datalabels point to respective arc. something like this: https://imgur.com/yKhWKOu
I've created the 'callout' shape using highcharts renderer method, but unable to make it dynamic. This is what I'm getting right now: https://imgur.com/VMuVwdk My code is :
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="container" style="min-width: 310px; height: 400px; max-width: 600px; margin: 0 auto"></div>
<script type="text/javascript" src="https://code.highcharts.com/highcharts.js"></script>
<script type="text/javascript">
(function(Highcharts) {
Highcharts.Renderer.prototype.symbols.callout = function(x, y, w, h) {
var arrowLength = 6,
halfDistance = 6,
r = Math.min(0, w, h),
safeDistance = r + halfDistance,
<!-- anchorX = options && options.anchorX,
//anchorY = options && options.anchorY,
path;
path = [
'M', x + r, y, //
'L', x + w - r, y, // top side
'C', x + w, y, x + w, y, x + w, y + r, // top-right corner
'L', x + w, y + h - r, // right side
'C', x + w, y + h, x + w, y + h, x + w - r, y + h, // bottom-right corner
'L', x + r, y + h, // bottom side
'C', x, y + h, x, y + h, x, y + h - r, // bottom-left corner
'L', x, y + r, // left side
'C', x, y, x, y, x + r, y // top-right corner
];
path.splice(23,
3,
'L',
w / 2 + halfDistance,
y + h,
w / 2,
y + h + arrowLength,
w / 2 - halfDistance,
y + h,
x + r,
y + h
);
return path;
};
}(Highcharts));
Highcharts.chart('container', {
plotOptions: {
pie: {
dataLabels: {
enabled: true,
style: {
fontWeight: 'bold',
color: 'white'
},
connectorWidth: 0,
distance: 10,
shape: 'callout',
backgroundColor: 'red',
<!-- backgroundColor: 'rgba(0, 0, 0, 0.75)', -->
style: {
color: '#FFFFFF',
textOutline: 'none'
}
},
startAngle: 0,
endAngle: 360,
center: ['50%', '50%']
}
},
series: [{
type: 'pie',
innerSize: '80%',
data: [
['Firefox', 10.38],
['IE', 56.33],
['Chrome', 24.03],
['Opera', 31.44]
]
}]
}, function(chart) {
});
</script>
</body>
</html>
'Thanks in advance'
I examined this subject and it seems that it's rather tricky thing to do in Highcharts.
The library uses
SVGRenderer.label
(https://api.highcharts.com/class-reference/Highcharts.SVGRenderer#label) function for creating the data labels.Chevron (small arrow) appears in
callout
shape label only whenxAnchor
andyAnchor
are definded and necessary conditions from theHighcharts.Renderer.prototype.symbols.callout
function are satisfied (https://github.com/highcharts/highcharts/blob/master/js/parts/SvgRenderer.js). When data labels are generated for pie series these values are not defined - chevron doesn't appear.You have overwritten this function and hardcoded the label path - that's not the solution when you want it to be responsive.
Here's a workaround that I found:
I set
dataLabels.format
to empty string - the label are generated, but they're not visible, because they have no content. I use their position inchart.events.render
to generate new labels:Live demo: http://jsfiddle.net/kkulig/8s968m7f/
The biggest challenge here is to find a proper coordinates for anchors. I only did that for the label(s) in the top-left part of the plot area (it's just for example purposes - better formulas need to be found). I used the dimensions of the chart to compute these values.
It's not very elegant solution, but if you find proper formulas and do some coding it'll work.