Why every single dc.barChart example groups on dimension?

41 Views Asked by At

My mental image of crossfilter is that you

  1. create your dimension over the variable you wish to study, and
  2. create "bins" over that dimension, i.e. group().

I want to create a bar chart where every bar represents a range e.g. 0<x<10, 10<x<20, so naturally I create a .dimension((datapoint) => datapoint.x), and groups like:

dimension.group((x) => {
   if (x<10) return "<10";
   if (x>10 && x<20) return "10<x<20";
   /* and so on */
});

Now I struggle getting this dimension and group into a bar chart. Every single ordinal dc.barChart example I've come across does the grouping inside the dimension. The analogy in my example would be:

.dimension((datapoint) => {
   if (datapoint.x<10) return "<10";
   if (datapoint.x>10 && datapoint.x<20) return "10<x<20";
   /* and so on */
});
/* and then */
...group().reduceCount();

This feels backwards and wrong, and forces me to create additional, "custom" dimensions that are more or less useless outside the scope of the bar chart.

How would I feed "my" approach into a minimal, really simple dc.barChart?

1

There are 1 best solutions below

1
o-o On

So this turned out to be a wild goose chase.

It turns out you can easily reuse dimensions and do the binning in the group function. The simplest way I've found is to define your thresholds in an array, e.g. var thresholds = [-1000,-100,0,100,1000]; and pass the followin as the group function:

...group((datapoint) => d3.bisectLeft(thresholds, datapoint)-1); // -1 with .centerBar(false) will display things in the right bin

Also make sure you pass an ordinal scale to dc.barChart.x(d3.scale.ordinal()...). The reason I didn't get it to work in the first place (other than my d3 version 3.0.3 didn't play nicely with dc2.2) was that I omitted .xUnits((a) => thresholds.map((d)=>d.toString())).

Now for the wild goose chase part... There's a big reason you don't want to do this, and instead go for the more unorthodox approach of defining your bins in the .dimension function: brushing!

Brushing requires a quantitative scale, and I've found no way to tap into dc.js internal brushing procedure to do the translation between the brush and my xUnits.