Home > Software engineering >  Place percentage labels inside each slice using Highcharts' 3D Pie Chart
Place percentage labels inside each slice using Highcharts' 3D Pie Chart

Time:09-15

I'm using Highcharts v9.2.2. Placing the labels on top of the slices for the regular Pie Chart works without problems, but switching to the 3D variant messes up the placement as demonstrated below:

Regular Pie chart

$(function() {

  $('#container').highcharts({
    chart: {
      type: 'pie',
      backgroundColor: 'rgba(0,0,0,0)',
      y: 100,
      options3d: {
        enabled: true,
        alpha: 65,
        fitToPlot: false,
        beta: 0
      }
    },
    title: {
      text: 'Regular Pie'
    },
    plotOptions: {
      pie: {
        y: 1,
        shadow: true,
        center: ['50%', '50%'],
        borderWidth: 0,
        showInLegend: false,
        size: '80%',
        data: [{
            "name": "First slice",
            "y": 100,
            "sliced": true
          },
          {
            "name": "Second slice",
            "y": 100,
            "sliced": true
          },
          {
            "name": "Third slice",
            "y": 70,
            "sliced": true
          },
          {
            "name": "Fourth slice",
            "y": 100,
            "sliced": true
          },
          {
            "name": "Fifth slice",
            "y": 100,
            "sliced": true
          }

        ]
      }
    },
    tooltip: {
      valueSuffix: '%'
    },
    series: [{
        type: 'pie',
        name: 'Browser share',

        dataLabels: {
          color: 'white',
          distance: -20,
          formatter: function() {
            if (this.percentage != 0) return Math.round(this.percentage)   '%';

          }
        }
      },
      {
        type: 'pie',
        name: 'Browser share',

        dataLabels: {
          connectorColor: 'grey',
          color: 'black',
          y: -10,
          softConnector: false,
          connectorWidth: 1,
          verticalAlign: 'top',
          distance: 20,
          formatter: function() {
            if (this.percentage != 0) return this.point.name;

          }
        }
      }
    ]
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/accessibility.js"></script>
<div id="container" style="min-width: 400px; height: 400px; margin: 0 auto"></div>

3D Pie Chart

$(function() {

  $('#container').highcharts({
    chart: {
      type: 'pie',
      backgroundColor: 'rgba(0,0,0,0)',
      y: 100,
      options3d: {
        enabled: true,
        alpha: 65,
        fitToPlot: false,
        beta: 0
      }
    },
    title: {
      text: '3D Pie'
    },
    plotOptions: {
      pie: {
        y: 1,
        shadow: true,
        center: ['50%', '50%'],
        borderWidth: 0,
        showInLegend: false,
        depth: 35,
        size: '80%',
        data: [{
            "name": "First slice",
            "y": 100,
            "sliced": true
          },
          {
            "name": "Second slice",
            "y": 100,
            "sliced": true
          },
          {
            "name": "Third slice",
            "y": 70,
            "sliced": true
          },
          {
            "name": "Fourth slice",
            "y": 100,
            "sliced": true
          },
          {
            "name": "Fifth slice",
            "y": 100,
            "sliced": true
          }

        ]
      }
    },
    tooltip: {
      valueSuffix: '%'
    },
    series: [{
        type: 'pie',
        name: 'Browser share',

        dataLabels: {
          color: 'white',
          distance: -20,
          formatter: function() {
            if (this.percentage != 0) return Math.round(this.percentage)   '%';

          }
        }
      },
      {
        type: 'pie',
        name: 'Browser share',

        dataLabels: {
          connectorColor: 'grey',
          color: 'black',
          y: -10,
          softConnector: false,
          connectorWidth: 1,
          verticalAlign: 'top',
          distance: 20,
          formatter: function() {
            if (this.percentage != 0) return this.point.name;

          }
        }
      }
    ]
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>
<script src="http://code.highcharts.com/highcharts-3d.js"></script>
<script src="https://code.highcharts.com/modules/accessibility.js"></script>
<div id="container" style="min-width: 400px; height: 400px; margin: 0 auto"></div>

Is there a way to properly do this for the 3D chart? I've tried tweaking distance in series[0].dataLabels but couldn't achieve a much better result than the provided example.

CodePudding user response:

This behaviour occurs due to the following issue: https://github.com/highcharts/highcharts/issues/3259

As a workaround you can move dataLabels with attr() method:

  function(chart) {
    var x, angle, centerX = chart.series[0].center[0],
      rad = chart.series[0].center[2] / 3;
    Highcharts.each(chart.series[0].data, function(p, i) {
      angle = p.angle;
      x = centerX   rad * Math.cos(angle);
      p.dataLabel.attr({
        x: x,
        'text-anchor': 'right'
      });
    })
  }

Demo: https://jsfiddle.net/BlackLabel/2z4nfybg/

  • Related