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

时间:2015-04-16 04:43:26

标签: javascript jquery charts highcharts

我在我的一个项目中使用highcharts。正在使用Highcharts 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]        
        }]
    });
});

我面临的问题是Slice标签在这里和那里运行。我希望所有标签都精确地位于每个切片的中心。

演示的JS小提琴链接是PIE Chart JSFiddle

2 个答案:

答案 0 :(得分:2)

最简单但不精确的方法是为dataLabels设置负距离。距离的值与图表的大小有关,因此可以在加载(到初始化正确的位置)和重绘(在更改图表大小之后)事件时更新系列(具有dataLabels的新距离)。

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

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

答案 1 :(得分:0)

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

您可以在load事件中处理此问题。这是一个简单的例子,您可以根据自己的需求进行优化:

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