0
votes

I'm trying to figure out how to add a filter onto a crossfilter group that is not related to a dimensional filter. Let's look at an example:

var livingThings = crossfilter({
  // Fact data.
  { name: “Rusty”,  type: “human”, legs: 2 },
  { name: “Alex”,   type: “human”, legs: 2 },
  { name: “Lassie”, type: “dog”,   legs: 4 },
  { name: “Spot”,   type: “dog”,   legs: 4 },
  { name: “Polly”,  type: “bird”,  legs: 2 },
  { name: “Fiona”,  type: “plant”, legs: 0 }
});  //taken from http://blog.rusty.io/2012/09/17/crossfilter-tutorial/

if we were to make a dimension on type and a group of that dimension:

var typeDim = livingThings.dimension(function(d){return d.type});
var typeGroup = typeDim.group();

we would expect typeGroup.top(Infinity) to output

 {{human:2},
 {dog:2},
 {bird:1},
 {plant:1}}

My question is how can we filter the data such that they include only 4 legged creatures in this grouping? I also don't want to use dimension.filter... because i don't want this filter to be global, just for this one grouping. In other words

var filterDim = livingThings.dimension(function(d){return d.legs}).filterExact(4);

is not allowed.

I'm thinking of something similar to what I did to post-filter dimensions as in https://stackoverflow.com/a/30467216/4624663 basically I want to go into the internals of the typeDim dimension, and filter the data before it is passed into the groups. Creating a fake group that calls typeDim.group().top() will most likely not work as the individual livingThings records are already grouped by that point. I know this is tricky: thanks for any help.

V

2

2 Answers

0
votes

Probably best to use the reduceSum functionality to create a pseudo-count group that only counts records with 4 or more legs:

var livingThings = crossfilter({
  // Fact data.
  { name: “Rusty”,  type: “human”, legs: 2 },
  { name: “Alex”,   type: “human”, legs: 2 },
  { name: “Lassie”, type: “dog”,   legs: 4 },
  { name: “Spot”,   type: “dog”,   legs: 4 },
  { name: “Polly”,  type: “bird”,  legs: 2 },
  { name: “Fiona”,  type: “plant”, legs: 0 }
});  //taken from http://blog.rusty.io/2012/09/17/crossfilter-tutorial/

var typeDim = livingThings.dimension(function(d){return d.type});
var typeGroup = typeDim.group().reduceSum(function(d) {
  return d.legs === 4 ? 1 : 0;
});

That will sum across a calculated value that will be 1 for records with 4 legs and 0 for records with ... not 4 legs. In other words, it should just count 4-legged creatures.

0
votes

I think, this is what you are looking for. Comment back if I'm wrong.

var dimByLegs = livingThings.dimension(function(d){return d.legs});
dimByLegs.filterExact(4);
var dogs = dimByLegs.group();
dimByLegs.top(Infinity).forEach(function(d){console.log(d.type, d.legs);});
dimByLegs.dispose();