将饼图标签精确设置在 PIE highcharts 切片的中心

set Pie chart labels exact in center of Slices of PIE highcharts

我在我的一个项目中使用 highchartsHighcharts JQuery版本正在使用中,参考如下:

http://code.highcharts.com/highcharts.js

用于绘制图表的代码如下:

$(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]        
        }]
    });
});

我面临的问题是切片标签到处都是 运行。我希望所有标签都位于每个切片的中心。

JS Fiddle link 演示是 PIE Chart JSFiddle

似乎没有内置功能可以执行此操作。 我认为你必须使用负距离,如果图表大小发生变化,你必须计算新的距离以保持标签在切片上居中。

您可以在加载事件中处理它。这是一个简单的示例,您可以对其进行改进以满足您的需要:

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);
        }
    }

最简单但不精确的方法是为数据标签设置负距离。距离的值将与图表的大小有关,因此可以在加载(以启动正确的位置)和重绘(更改图表大小后)事件中更新系列(数据标签的新距离)。

将每个数据标签放置在其切片中心的精确解决方案可以基于获取切片中心并将标签放置在那里。为了使图表保持响应,应在每次更改图表大小后执行此标签位置调整 - 在图表的加载和重绘事件中。

示例: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]
            ]
        }]
    });
});