score:1

Accepted answer

The following minor patch to highcharts.src.js v4.0.1 achieves the desired behaviour:


    --- highcharts.src.orig.js  2014-04-24 08:25:52.000000000 +0000
    +++ highcharts.src.js   2014-06-24 13:57:42.957605307 +0000
    @@ -12167,6 +12167,22 @@
                positions = [pick(centerOption[0], '50%'), pick(centerOption[1], '50%'), options.size || '100%', options.innerSize || 0],
                smallestSize = mathMin(plotWidth, plotHeight),
                isPercent;
    +
    +       /**
    +        * Allow a chart (pie) to specify a size relative to another series. In
    +        * that case, simply copy the center position of the parent, and scale
    +        * the radius.
    +        */
    +       if ( options.relativeSize ) {
    +           parentPositions = chart.series[options.relativeSize.parentSeries].center;
    +           positions[0] = parentPositions[0];
    +           positions[1] = parentPositions[1];
    +           positions[2] = options.relativeSize.size * parentPositions[2];
    +
    +           return map(positions, function (length, i) {
    +               return positions[i]
    +           });
    +       }

            return map(positions, function (length, i) {
                isPercent = /%$/.test(length);

Then, when configuring the donut:

            series: [{
            name: 'Browsers',
            data: browserData,
            center: ['50%', '50%'],
            dataLabels: {
                formatter: function() {
                    return this.y > 5 ? this.point.name : null;
                },
                color: 'white',
                distance: -30
            }
        }, {
            name: 'Versions',
            data: versionsData,
            relativeSize: {
                parentSeries: 0, // index of parent series
                size: 0.75       // 75% of parent pie
            }
            dataLabels: {
                formatter: function() {
                    // display only if larger than 1
                    return this.y > 1 ? ''+ this.point.name +': '+ this.y +'%'  : null;
                }
            }
        }]

Note that the parent (outer) pie must be explicitly centered in the container, otherwise in certain cases the two pies may not be concentric.

Also, requiring the index of the series to be specified is clearly not ideal, but in a tightly controlled graph (as is a donut), it seems to do the job.

score:1

The dataLabels: formatter... is only controlling whether or not to show datalabel for thinner slices. It's not controlling the size of the pie chart. That is being specified by the series:[{size parameter. In your example it's set to 85% of the container which does lead to overflow.

According to the docs

The default behaviour (as of 3.0) is to scale to the plot area and give room for data labels within the plot area.

If you comment out the size on your example, it does indeed squeeze in the labels but I'm not sure you'll love the look of it.

score:0

Unfortunately this option is not available, so I advice you to post your request on the uservoice


Related Articles