need help in centering the pie data labels on top of slices. I'm using React Highchart.
Currently the Chart looks like this.
Sample Code for label centering:
function redrawDatalabels() {
var chart = this,
cX = chart.series[0].center[0],
cY = chart.series[0].center[1],
shapeArgs,
ang,
posX,
posY,
bBox;
Highchart.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;
const labelPos = point.labelPosition.alignment === "right" ? 1 : -1;
posX = cX + (shapeArgs.r / 2) * Math.cos(ang) + (labelPos * bBox.width) / 2;
posY = cY + (shapeArgs.r / 2) * Math.sin(ang) - bBox.height / 2;
point.dataLabel._pos.x = posX;
point.dataLabel._pos.y = posY;
}
});
chart.series[0].placeDataLabels();
}
CodeSandBox: https://codesandbox.io/s/hc-animate-9j72hn?file=/src/App.js
You can Center your labels on top of your chart slices, the main changes will be on the options.plotOptions.pie.dataLabels.distance
property to control the distance of your labels.
So the fixed code will be something like this :
import Highcharts from "highcharts";
import { each } from "lodash";
import { PureComponent } from "react";
import "./styles.css";
function redrawDatalabels() {
var chart = this,
cX = chart.plotWidth / 2,
cY = chart.plotHeight / 2,
shapeArgs,
ang,
posX,
posY,
bBox;
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;
let labelPos = point.labelPosition.alignment === "right" ? 1 : -1;
labelPos = (labelPos * bBox.width) / 2;
posX = cX + (shapeArgs.r / 2) * Math.cos(ang) + labelPos;
posY = cY + (shapeArgs.r / 2) * Math.sin(ang) - bBox.height / 2;
point.dataLabel._pos.x = posX;
point.dataLabel._pos.y = posY;
}
});
chart.series[0].placeDataLabels();
}
const options = {
chart: {
animation: false,
renderTo: "chart1",
type: "pie",
},
legend: {
enabled: true,
},
plotOptions: {
chart: {
animation: false,
renderTo: "chart1",
type: "pie",
events: {
load: redrawDatalabels,
redraw: redrawDatalabels
}
},
legend: {
enabled: true
},
pie: {
allowPointSelect: true,
cursor: "pointer",
dataLabels: {
enabled: true,
connectorWidth: 0,
format: "{point.percentage:.1f}%",
distance: -25, // Adjust the distance of labels from the cente
style: {
color:
(Highcharts.theme && Highcharts.theme.contrastTextColor) || "black",
textOutline: "none",
},
},
size: "80%",
innerSize: "65%",
},
},
series: [
{
type: "pie",
name: "Browser share",
data: [
["Firefox", 50],
["IE", 10],
["Chrome", 30],
["Safari", 5],
["Opera", 5],
],
},
],
};
class App extends PureComponent {
componentDidMount() {
this.chart1 = Highcharts.chart(options);
}
render() {
return (
<div className="App">
<div id="chart1" />
</div>
);
}
}
export default App;
I edited this code on your sandbox and it looks like this :