Opened 6 years ago

Closed 6 years ago

#17495 closed defect (invalid)

Pie Chart where a single category is 100% crashes Legend creation

Reported by: beck3905 Owned by: beck3905
Priority: undecided Milestone: tbd
Component: Charting Version: 1.8.3
Keywords: Cc:
Blocked By: Blocking:

Description

I am creating a Pie Chart using dojox.charting that has an associated legend. Under certain situations, my code crashes when trying to build the Legend.

After looking at the source code for dojox.charting.Chart, dojox.charting.plot2d.Pie, and dojox.charting.widget.Legend I found what appears to be an inconsistency.

In the render function of dojox.charting.plot2d.Pie the dyn property of the plot is created as an array and filled with slices of the plot. While looping through the slices, they are checked to see if they are 0 or 1 first. If one of the slices is >= 1 then iteration stops. So the dyn array could contain less objects than the run.

In the refresh function of dojox.charting.widget.Legend there is a loop that iterates over the run and finds the associated object in the dyn property of the plot. However, if the iteration stopped in the Pie.render function because a slice was >= 1, the Legend.refresh function will fail because any index above the slice >= 1 in the run does not exist in the dyn.

Here is the section of interest from Pie.render:

arr.some(slices, function(slice, i){
    if(slice < 0){
        // degenerated slice
        return false;	// continue
    }
    if(slice == 0){
    this.dyn.push({fill: null, stroke: null});
    return false;
    }
    var v = run[i], theme = themes[i], specialFill, o;
    if(slice >= 1){
        // whole pie
        specialFill = this._plotFill(theme.series.fill, dim, offsets);
        specialFill = this._shapeFill(specialFill,
            {
                x: circle.cx - circle.r, y: circle.cy - circle.r,
                width: 2 * circle.r, height: 2 * circle.r
            });
        specialFill = this._pseudoRadialFill(specialFill, {x: circle.cx, y: circle.cy}, circle.r);
        var shape = s.createCircle(circle).setFill(specialFill).setStroke(theme.series.stroke);
        this.dyn.push({fill: specialFill, stroke: theme.series.stroke});
    
        if(events){
            o = {
                element: "slice",
                index:   i,
                run:     this.run,
                shape:   shape,
                x:       i,
                y:       typeof v == "number" ? v : v.y,
                cx:      circle.cx,
                cy:      circle.cy,
                cr:      r
            };
            this._connectEvents(o);
            eventSeries[i] = o;
        }
    
        return true;	// stop iteration
    }
    ...

Here is the section from Legend.refresh:

arrayUtil.forEach(t.run.data, function(x, i){
    this._addLabel(t.dyn[i], x.legend || x.text || x.y);
}, this);

Change History (3)

comment:1 Changed 6 years ago by cjolif

Do you have an example reproducing the issue so that we can more easily fix and confirm the fix?

comment:2 Changed 6 years ago by cjolif

Owner: set to beck3905
Status: newpending

I tried to reproduce without luck. So the example is definitely required.

comment:3 Changed 6 years ago by trac-o-bot

Resolution: invalid
Status: pendingclosed

Because we get so many tickets, we often need to return them to the initial reporter for more information. If that person does not reply within 14 days, the ticket will automatically be closed, and that has happened in this case. If you still are interested in pursuing this issue, feel free to add a comment with the requested information and we will be happy to reopen the ticket if it is still valid. Thanks!

Note: See TracTickets for help on using tickets.