0
votes

I'm making some dashboard using crossfilter.js, d3.js and dc.js but I'm having some problems when a value of the data set is "0"
In the dashboard there is a dc.geoChoroplethChart() and I use .colorCalculator() to distinguish the filtered value: if d is defined but not 0 use color, else use #666

.colorCalculator(function (d) { 
  return d ? map.colors()(d) : '#666';
})

The problem is:

  • crossfilter return 0 for the values not respecting the filter (and these value are correctly rendered as #666 on the map by the .colorCalculator() function)
  • if I have 0 value in the filtered values this also are rendered as #666!

I can't distinguish if a value is 0 because it has to be 0 or because it is non respect the filter!

[Example]
I've made a super simple jsfiddle to show the problem http://jsfiddle.net/danielepennati/77pqh/
the data set is like this:

{id:"a1", tipo: "a", val: 0},
{id:"a2", tipo: "a", val: 1},
{id:"a3", tipo: "a", val: 2},
...

there are 2 dimensions (one by id and one by tipo) and 1 group on the id dimension.
Firstly I just print the output of the id group.
Than if you click the button you get the output of the same id group after the filtering by "tipo" = "a" to the tipo dimension.
as you can see in the fiddle the record with "id" = "a1", that is part of the filtered dimension because it has "tipo" = "a", has the same 0 value (because it is its own value) as the other record that are not part of filtered dimension (b1, b2, b3, ..., c4, c5)

This is the same kind of output I have in the dc.geoChoroplethChart() after I add a filter by clicking one of the other chart in the dashboard and a can't handle the value = 0 properly:

  • Is there a way to make crossfilter return undefined or null or everything else but not 0?
  • Or there is a way I can modify the colorCalculator function to be able to check if a value is 0 which kind of 0 it is?

[UPDATE]
I tried to check if a record with "value = 0" is also part of the output of the filtered dimension. In the fiddle example a could check if the key associated to a value = 0 is also present in the output of dimId.top(Infinity).
The problem is I can't do that inside the .colorCalculator() function. Inside this function I just have access to the value not to the key... Moreover, iterate through all the dimension values for each record doesn't look like a smart solution (the dimension is made by hundreds of thousand element...)

Thank for the help!

1

1 Answers

1
votes

The best way to do this is probably to use custom reduce functions that track both a sum and a count for each group. Like:

var dimId = cf.dimension( function (d) { return d.id; } );
var groupId = dimId.group().reduce(
  function(p,v) {
    p.count = p.count + 1;
    p.sum = p.sum + v.val;
    return p;
  }, function (p, v) {
    p.count = p.count - 1;
    p.sum = p.sum - v.val;
    return p;
  }, function () { return { count: 0, sum: 0 }; }
);

Here, when you do groupId.top(10), you'll get an array of groups and each group's 'value' will be an object with both 'sum' and 'count' properties. You can use the 'count' property to figure out if there are currently any records in the group, and if there are you can read the value from the 'sum' property.