在Highcharts饼图中旋转dataLabels

时间:2015-01-31 06:22:19

标签: javascript highcharts

我试图在Highcharts饼图的每个片段中旋转和定位dataLabel,只是觉得我越来越深入,而没有更接近解决方案。会喜欢一些提示或建议。

用于说明所需目标的图形:

enter image description here

我的饼图中会有三个部分。我理想的是喜欢:

  • 要旋转的每个dataLabel基本上为每个段创建一条中心线(由品红线表示);和
  • 无论类型大小如何,dataLabel都将以细分为中心。

关于从哪里开始这个的建议,或者让我接近的样本?



$(function () {
	$('#container').highcharts({
		chart: {
			type: 'pie',
			backgroundColor: 'transparent',
			spacing: [0, 0, 0, 0],
			margin: [0, 0, 0, 0],
			events: {
				load: function() {
					$.each(this.series[0].data, function(index, point) {

						var degree = (point.angle * 180) / Math.PI;
						var rotation = 0;
						(degree < 0) && (degree += 360);

						// If the slice is in the left half, then rotate 180
						// so the text won't look upside down
						if (degree >= 90 && degree <= 270) {
							rotation = degree - 180;
							point.dataLabel.x = 0;
							point.dataLabel.y = 0;
							point.dataLabel.translateX = (point.labelPos[2] + point.labelPos[4]) / 2;
							point.dataLabel.translateY = (point.labelPos[3] + point.labelPos[5]) / 2;
						} else {
							point.dataLabel.x = 0;
							point.dataLabel.y = 0;
							rotation = degree - 180;
							point.dataLabel.translateX = (point.labelPos[2] + point.labelPos[4]) / 2;
							point.dataLabel.translateY = (point.labelPos[3] + point.labelPos[5]) / 2;
						}

						point.dataLabel.rotation = Math.floor(rotation);
						point.dataLabel.show();
						point.dataLabel.updateTransform();
					});
				}
			}
		},
		title: {
			text: null
		},
		yAxis: {
			title: {
				text: 'Total percent market share'
			}
		},
		plotOptions: {
			pie: {
				borderColor: 'rgb(243, 243, 243)',
				borderWidth: 2,
				shadow: false,
				center: ['50%', '50%'],
				colors: ['rgb(77, 196, 215)', 'rgb(50, 68, 132)', 'rgb(85, 119, 183)']
			}
		},
		tooltip: {
			enabled: false
		},
		series: [{
			type: 'pie',
			name: 'Votes',
			data: [
				['Yes', 9],
				['No', 5],
				['Undecided', 2]
			],
			size: '90%',
			dataLabels: {
				formatter: function () {
					return this.point.name;
				},
				color: 'white',
				connectorWidth: 0,
				distance: -80
			}
		}]
	});
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>
<div id="container" style="height: 600px; width: 100%;"></div>
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:3)

Highcharts不提供饼图中自动旋转数据标签的选项。您可以为dataLabels rotation编写自定义函数。

以下是如何做到这一点的简单示例:

var allY, angle1, angle2, angle3,
    rotate = function () {
        $.each(options.series, function (i, p) {
            angle1 = 0;
            angle2 = 0;
            angle3 = 0;
            allY = 0;
            $.each(p.data, function (i, p) {
                allY += p.y;
            });

            $.each(p.data, function (i, p) {
                angle2 = angle1 + p.y * 360 / (allY);
                angle3 = angle2 - p.y * 360 / (2 * allY);
                p.dataLabels.rotation = -90 + angle3;
                angle1 = angle2;
            });
        });
    };

首先,我计算所有Y值的总和。然后我计算所有饼图中间的角度。然后我以相同的角度旋转数据标签。

例如: http://jsfiddle.net/izothep/j7as86gh/6/

类似主题: Radial Pie Chart Datalabels in Highcharts

答案 1 :(得分:2)

我发现旋转标签本身是有问题的,因为当使用highcharts旋转它们时,它似乎围绕它们自己的轴旋转它们。要获得最佳结果,您需要围绕饼图的原点旋转标签。为了实现这一点,我将绝对定位的div直接添加到饼图顶部,并迭代这些点以根据百分比计算旋转。当然,缺点是外部div正用于标签,而不是highcharts自己的标签功能。

以下是我添加的代码:

首先,一些用于保存标签的div的CSS样式和饼图本身:

<强> CSS

div#container{
    position:relative;
}
div.outerContainer{
    width:600px;
    height:40px;
    position:absolute;
    top:280px;
    display:none;
    color:white;
    font-family:Helvetica, Arial, Sans;
    font-size:16px;
    font-weight:bold;
    text-transform:uppercase;
}
div.outerContainer > span{
    float:left;
    width:300px;
    text-align:center;
    height:40px;
    line-height:40px;
}

然后,自定义load事件代码来计算标签

        load: function () {
            var cumulativePercentage = 0;
            var $labelTemplate = $("<div class=outerContainer><span class=left></span><span class=right></span></div>");
            $.each(this.series[0].data, function (i, point) {
                $label=$labelTemplate.clone();
                $label.find('span').text(point.name);
                var angle=-90+(cumulativePercentage+point.percentage/2)*360/100;
                if (angle > 90) {
                    angle=angle+180;
                    $label.find('span.right').css({visibility:'hidden'});
                }
                else {
                    $label.find('span.left').css({visibility:'hidden'});
                }
                $label.css({transform:'rotate('+angle+'deg)'});    
                cumulativePercentage+=point.percentage;


                $('#container').append($label);

            });
            $('div.outerContainer').show();
        }

另外,我删除了dataLabels属性。

简要解释:

cumulativePercent跟踪每个部分贡献的饼图,以便我们可以在每个部分的中间准确插入标签。我们检查角度是否大于90度,以便

  1. 翻转标签div,使文字不倒置(或小于90度时保留)

  2. 决定文本是否应位于div的左侧或右侧,具体取决于其方向。

  3. 查看实际操作:

    &#13;
    &#13;
      $('#container').highcharts({
            chart: {
                type: 'pie',
                backgroundColor: 'transparent',
                spacing: [0, 0, 0, 0],
                margin: [0, 0, 0, 0],
                events: {
                    load: function () {
                        var cumulativePercentage = 0;
                        var $labelTemplate = $("<div class=outerContainer><span class=left></span><span class=right></span></div>");
                        $.each(this.series[0].data, function (i, point) {
                            $label = $labelTemplate.clone();
                            $label.find('span').text(point.name);
                            var angle = -90 + (cumulativePercentage + point.percentage / 2) * 360 / 100;
                            if (angle > 90) {
                                angle = angle + 180;
                                $label.find('span.right').css({visibility: 'hidden'});
                            }
                            else {
                                $label.find('span.left').css({visibility: 'hidden'});
                            }
                            $label.css({transform: 'rotate(' + angle + 'deg)'});
                            cumulativePercentage += point.percentage;
    
    
                            $('#container').append($label);
    
                        });
                        $('div.outerContainer').show();
                    }
                }
            },
            title: {
                text: null
            },
            yAxis: {
                title: {
                    text: 'Total percent market share'
                }
            },
            plotOptions: {
                pie: {
                    borderColor: 'rgb(243, 243, 243)',
                    borderWidth: 2,
                    shadow: false,
                    center: ['50%', '50%'],
                    colors: ['rgb(77, 196, 215)', 'rgb(50, 68, 132)', 'rgb(85, 119, 183)']
                }
            },
            tooltip: {
                enabled: false
            },
            series: [{
                    type: 'pie',
                    name: 'Votes',
                    data: [
                        ['Yes', 9],
                        ['No', 5],
                        ['Undecided', 2]
                    ],
                    size: '90%'
                }]
        });
    &#13;
        div#container{
            position:relative;
        }
        div.outerContainer{
            width:600px;
            height:40px;
            position:absolute;
            top:280px;
            display:none;
            color:white;
            font-family:Helvetica, Arial, Sans;
            font-size:16px;
            font-weight:bold;
            text-transform:uppercase;
        }
        div.outerContainer > span{
            float:left;
            width:300px;
            text-align:center;
            height:40px;
            line-height:40px;
        }
    &#13;
    <div id="container" style="height: 600px; width: 600px;"></div>
    
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="http://code.highcharts.com/highcharts.js"></script>
    &#13;
    &#13;
    &#13;