Reputation: 13
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
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:
Now, for the parseFloat version:
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