Animesh
Animesh

Reputation: 13

dc.js chart groups not updating with correct values on charts after click on a parent chart

My issue here is that I have a crossfilter group reduce function for calculating savings, but when a filter is applied on a chart, it seems to not pass the correct filter across. I also have a similar case working example.

I have created two jsbin's out of which one of them has correct behavior.

I have data for two years in this case 2010 and 2014. But in the Savings(not working) chart the carrier pie chart doesn't filter by year whereas it does in the DIFOT(working) chart.

The links are : DIFOT(Working) : http://jsbin.com/bagohavehu/2/edit Savings (Not working as expected) : http://jsbin.com/yudametulo/2/edit

Thanks a lot for your time and effort.

Regards, Animesh

Upvotes: 1

Views: 533

Answers (1)

Gordon
Gordon

Reputation: 20120

To track these calculation problems down, you really need to use the debugger and put breakpoints in the reduction functions or in the draw functions to see what reduced values you ended up with.

I find using the browser's debugger very difficult (impossible?) to do in jsbin, so I have again pasted your code into two jsfiddles:

parseFloat version: http://jsfiddle.net/gordonwoodhull/aqhLv0qc/

parseInt version: http://jsfiddle.net/gordonwoodhull/9bnejpLx/1/

Now, we set a breakpoint in chart.redraw (dc.js:1139) to see what values it's trying to plot on clicking the slice.

The first time the breakpoint is hit isn't interesting, because it's just the yearly chart we clicked on, but the second hit is the carrier chart, which reveals a lot. Printing _chart.group().all() for the parseInt version:

parseInt group bin values

Now, for the parseFloat version:

enter image description here

Since the calculations come out exact for the int version, you end up with 1 - 0/0 === NaN, and somewhere along the way dc.js or d3.js silently forces NaN to zero.

But since float calculations are never exact, you end up with 1 - 0/-3e-15 === 1.

You want to avoid dividing by zero, or anything close to zero, so adding a check in your reduction function produces (I think) the desired result:

var group = Dim.group().reduce(
    function(p,v){
        p.current += parseFloat(v.currentPrice);
        p.compare += parseFloat(v.comparePrice);
        if(Math.abs(p.compare) > 0.01) {
            p.savings  = p.current/p.compare;
            p.result   = 1-p.savings;
        }
        else p.result = 0;
        return p;
    },
    function(p,v){
        p.current -= parseFloat(v.currentPrice);
        p.compare -= parseFloat(v.comparePrice);
        if(Math.abs(p.compare) > 0.01) {
            p.savings  = p.current/p.compare;
            p.result   = 1-p.savings;
        }
        else p.result = 0;
        return p;
    },
    function(){return { current: 0, compare: 0,savings:0, result:0};}
);

Working version (I think): http://jsfiddle.net/gordonwoodhull/y2sf7y18/1/

Upvotes: 2

Related Questions