Highcharts: Pie chart data labels draw outside of the canvas

Created on 17 Feb 2011  ·  32Comments  ·  Source: highcharts/highcharts

The pie chart is not taking into account the length of the data label when trying to position it, so they often render partially outside of the canvas. I was able to use margins on the chart to give myself enough padding, but this isn't the way to fix it,

Highcharts Enhancement

Most helpful comment

Why is this issue closed? It was started in 2011, but I still have this problem in 2017.

All 32 comments

I'm having this issue as well - I think this should be labeled as a bug rather than an enhancement, as the software doesn't work as expected

+1 on this issue, could the pie be automatically sized depending on the data labels ??

+1

+1 here too. My company purchased a license to use this software recently. Fixing this bug would a big help. Can anyone at Highslide chime in with priority/comment on what's going on here? This has been open for a year.

+1. What randallmorey said - exact same situation. Also, agree with rowanmanning, chopping off things is a bug.

This bug was opened 2 years ago. Any progress? Piecharts are useless to us if the labels get chopped off.
It's still marked as an enhancement.

Detecting the space needed for data labels is very complicated, and we
won't give it top priority at this time. You need to add the appropriate
margins and pie size to avoid this. You can also set the width style of the
dataLabels to force word wrap.

+1

I'm also having this problem.

this should be tagged as a Bug, Enhancement means its working properly but can be improved which isn't the case here obviously.
+1

hey @highslide-software , is there going to be any solution for this? can canvas based chart be a possible solution?

+1

+1 I'm having this problem as well.

me too

Okay folks, I'll try to come up with a solution. We need som recursive logic that draws data labels, finds out if they're spilling out, then recursively reduce the size of the pie until all labels are in.

Here's what we did:

  • Changed the default pie size option to null. When the pie size is null, the pie is automatically fitted within the plot area. When data labels are disabled, the pies fills the plot area completely. When data labels are enabled, the data labels are also fitted within the plot area.
  • Changed the default pie center option to [null, null]. Centering is handled independently for X and Y option. Null means auto, so the pie will fit inside the plot area whenever the size is also null.
  • Added an option, minSize. When the size is null, it will not go below this.

Demos:

All comments are appreciated!

I have a bunch of really long data labels (I can't really make them shorter) that will likely result in the chart being absurdly tiny. Is there a way to make the labels auto wrap to two or three lines if they exceed a certain width?

Thanks!

Yes, I think you can set the dataLabels.style.width to, say, '100px'.

Thanks very much for this - Is there an estimate for when this will be merged into 'master' or in a release?

I have a case where I'm displaying multiple pie charts on one page in a a 2x2 formation. Each pie has the same labels but different data.

So this solution may generate 4 differently sized pies which is not desirable - is there a way to avoid this and still make the labels fit? Really what I want is the datalabels to be adjusted to fit the chart, not the pie. Thanks in advanced.

This will be released and merged into master when Highcharts 3.0 is out, hopefully before Christmas.

In the case where you have multiple pies in the same chart, you still need to use absolute size. In theory, I think what you describe could be solved by adjusting each pie, then use the smallest pie size for all of them. But I'm not sure how this will work in practice, since the pies are adjusted within the plot area and not relative to each other.

@highslide-software Note the examples above are not working due to the CDN for highcharts. I have fixed the fiddle examples for anyone interested in them:

http://jsfiddle.net/CjgLg/13/ . Grab the resizing handle at the lower right to observe how the autosize is handled.
http://jsfiddle.net/9tqSn/11/ . As a consequense of the dynamic size, the size of the pie itself may change depending on what data labels are present. Note how it changes as slices are shown and hidden in this demo.

Thanks for the fix! +1 :)

I've a problem with this auto-sizing feature on donuts. It works fine for single pies, but when used on a 2-series pie (i.e. a donut), both the inner and outer pies are resized independently. In particular, when the inner pie doesn't have spider-like legends and the outer pie does have them, the inner pie is not resized at all and the outer pie is indeed resized to fit into the viewport. This results in a distorted chart (usually the inner pie becomes wider than the outer pie, completely breaking the look and semantics of the chart).

Is there any chance that you extend this fix to support donuts too, as a single big pie?

Here's an example: http://jsfiddle.net/mmarchetta/34VAT/2/

The pie that seems to be the outer one there (green/blue) is actually the inner pie, and the one with more slices that looks to be the inner one is actually the outer one.

Thanks!

I have the same issue with donut chart, labels are extending out side the chart.

This case shows how labels are clipped: http://jsfiddle.net/highcharts/7okk430t/

I have worked on this and explored logic to add ellipsis to overflowing data labels. It currently works well on static charts, but breaks on dynamically resizing or updating the chart.

A live demo can be seen at http://jsfiddle.net/highcharts/7okk430t/1/.

.. and here's the diff:

diff --git a/js/parts/DataLabels.js b/js/parts/DataLabels.js
index c72fabf..a7222c5 100644
--- a/js/parts/DataLabels.js
+++ b/js/parts/DataLabels.js
@@ -619,13 +619,41 @@ if (seriesTypes.pie) {
     * fall within the plot area.
     */
    seriesTypes.pie.prototype.placeDataLabels = function () {
+
+       var chart = this.chart,
+           spacing = chart.spacing;
        each(this.points, function (point) {
            var dataLabel = point.dataLabel,
-               _pos;
+               _pos,
+               overflow,
+               ellipsis;

            if (dataLabel && point.visible) {
                _pos = dataLabel._pos;
                if (_pos) {
+                   
+                   if (dataLabel._attr.align === 'right') {
+                       overflow = _pos.x - dataLabel.width;
+                       if (overflow < spacing[3]) {
+                           ellipsis = true;
+                       }
+                   }
+
+                   if (dataLabel._attr.align === 'left') {
+                       overflow = chart.chartWidth - _pos.x - dataLabel.width - spacing[1] - spacing[3];
+                       if (overflow < spacing[1]) {
+                           ellipsis = true;
+                       }
+                   }
+
+                   if (ellipsis) {
+                       dataLabel._attr.width = dataLabel.width + overflow;
+                       dataLabel.css({
+                           width: dataLabel._attr.width + PX,
+                           textOverflow: 'ellipsis'
+                       });
+                   }
+
                    dataLabel.attr(dataLabel._attr);
                    dataLabel[dataLabel.moved ? 'animate' : 'attr'](_pos);
                    dataLabel.moved = true;
diff --git a/js/parts/SvgRenderer.js b/js/parts/SvgRenderer.js
index 1f8b71d..fcc629d 100644
--- a/js/parts/SvgRenderer.js
+++ b/js/parts/SvgRenderer.js
@@ -10,7 +10,7 @@ SVGElement.prototype = {
    opacity: 1,
    // For labels, these CSS properties are applied to the <text> node directly
    textProps: ['fontSize', 'fontWeight', 'fontFamily', 'fontStyle', 'color', 
-       'lineHeight', 'width', 'textDecoration', 'textShadow'],
+       'lineHeight', 'width', 'textDecoration', 'textOverflow', 'textShadow'],

    /**
     * Initialize the SVG renderer

I tried the javascript from here (http://jsfiddle.net/CjgLg/13/) and get following:

Uncaught TypeError: $(...).resizable is not a function

The resizable method requires jQuery UI.

Ah... imported these 2 (jquery-ui.css and jquery-ui.min.js) and works fine now, thanks!

I also have data labels cutting off.

+1 for the ellipsis solution to be implemented into high charts.

Why is this issue closed? It was started in 2011, but I still have this problem in 2017.

This is still happening
e

I'm using the version 5.0.11
And it is still happening on the donut chart.

donutchart size

Was this page helpful?
0 / 5 - 0 ratings