Rotating dataLabels in a Highcharts pie chart

后端 未结 2 1220
终归单人心
终归单人心 2021-01-06 04:44

I\'m trying to rotate and position the dataLabels in each segment of a Highcharts pie chart and just feel like Im getting myself deeper and deeper without getting closer to

2条回答
  •  清歌不尽
    2021-01-06 05:25

    I found rotating the labels themselves to be problematic, because when using highcharts to rotate them, it seems to rotate them about their own axis. To achieve the best result, you want to rotate the label about the origin of the pie chart. To accomplish this, I appended absolutely positioned divs directly on top of the pie chart, and iterated over the points to calculate the rotation based on percentages. The downside, of course, is that external divs are being used for the labels, rather than highcharts's own labeling functions.

    Here is the code I added:

    First, some CSS styles for the divs which hold the labels, and the pie chart itself:

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

    Then, custom load event code to calculate the labels

            load: function () {
                var cumulativePercentage = 0;
                var $labelTemplate = $("
    "); $.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(); }

    Also, I deleted the dataLabels property.

    Brief explanation:

    cumulativePercent keeps track of how much of the pie each section contributes, so that we can insert the label exactly in the middle of each section. We check if the angle is greater than 90 degrees so that we can

    1. Flip the label div so that the text is not upside down (or leave it if less than 90 degrees)

    2. Decide if the text should be on the left or right side of the div, depending on its orientation.

    See it in action:

      $('#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 = $("
    "); $.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%' }] });
        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;
        }

提交回复
热议问题