Reputation: 3829
i am using highcharts
in one of my project. Highcharts JQuery
version is being used and below is the reference:
http://code.highcharts.com/highcharts.js
Code used to draw chart is as below:
$(function () {
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type:'pie'
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr']
},
plotOptions: {
series: {
dataLabels: {
enabled: true,
formatter: function() {
return Math.floor(this.percentage*100)/100 + ' %';
},
distance: 20,
connectorWidth : 0,
color: 'rgb(0, 127, 209)'
}
}
},
series: [{
data: [29.9, 71.5, 106.4, 129.2,29.9, 71.5, 106.4,
129.2,29.9, 71.5, 106.4, 129.2]
}]
});
});
The problem here i am facing that Slice labels are running here and there. I want all labels exact in center of each slice.
JS Fiddle link for demo is PIE Chart JSFiddle
Upvotes: 2
Views: 2532
Reputation: 7886
Simplest, but not precise way would be to set negative distance for dataLabels. Value of distance would be related to size of chart, so it is possible to update series (with new distance for dataLabels) in load (to initiatie correct position) and redraw (after change of chart's size) events.
Precise solution for placing each of dataLabels in center of its slice can be based on getting center of slice and placing labels there. To keep chart responsive this adjustment of labels positions should be performed after each change of chart's size - in load and redraw events of chart.
Example: http://jsfiddle.net/mo8dfztx/2/
function redrawDatalabels() {
var chart = this,
cX = chart.series[0].center[0],
cY = chart.series[0].center[1],
shapeArgs, ang, posX, posY, bBox;
Highcharts.each(chart.series[0].data, function (point, i) {
if (point.dataLabel) {
bBox = point.dataLabel.getBBox();
shapeArgs = point.shapeArgs;
ang = (shapeArgs.end - shapeArgs.start) / 2 + shapeArgs.start;
posX = cX + (shapeArgs.r / 2) * Math.cos(ang);
posY = cY + (shapeArgs.r / 2) * Math.sin(ang);
point.dataLabel._pos.x = posX + ((point.labelPos[6] == "right" ? (1) : (-1)) * bBox.width/2);
point.dataLabel._pos.y = posY - bBox.height/2;
}
});
chart.series[0].placeDataLabels();
}
$(function () {
$('#container').highcharts({
chart: {
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false,
events: {
load: redrawDatalabels,
redraw: redrawDatalabels
}
},
title: {
text: 'Browser market shares at a specific website, 2014'
},
tooltip: {
pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>'
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
enabled: true,
connectorWidth: 0,
format: '<b>{point.name}</b>: {point.percentage:.1f} %',
style: {
color: (Highcharts.theme && Highcharts.theme.contrastTextColor) || 'black'
}
}
}
},
series: [{
type: 'pie',
name: 'Browser share',
data: [
['Firefox', 50],
['IE', 50],
['Safari', 25],
['Opera', 25]
]
}]
});
});
Upvotes: 2
Reputation: 649
It looks like that there's no build-in feature to do this. I think you have to use a negative distance, and if the chart size changes, you have to calculate the new distance to keep the labels centered on the slice.
You could handle this in the load event. Here's a simple example what you could refine to fit your needs:
http://jsfiddle.net/uhydP/317/
events: {
load: function(e) {
this.options.plotOptions.series.dataLabels.distance = (this.chartHeight / 5.5) * -1;
this.series[0].update(this.options);
}
}
Upvotes: 0