Search code examples
javascriptmapreducedc.jscrossfilter

crossfilter.js - exclude facts from group based on separate dimension


Presume I have the following crossfilter object (simplified) to be plotting in a dc.js scatterPlot

var ndx = crossfilter([
  {time: 0.5, counts: 8, direction: 1},
  {time: 0.8, counts: 0, direction: -1},
  {time: 1.0, counts: 8, direction: 1},
  {time: 1.2, counts: 1, direction: -1},
  {time: 1.8, counts: 10, direction: 1},
  {time: 2.0, counts: 2, direction: -1},
  {time: 2.2, counts: 14, direction: 1},
  {time: 2.5, counts: 0, direction: -1},
  ...
]);

How do I setup a crossfilter such that the output vectors are

x --> [0,1,2,...] 
y --> [8,9,14,...] // (average of all "1" direction transition counts, per whole integer time)

What I have so far is from here

const timeDim = ndx.dimension(d => d.time);
const binwidth = 1;
const timeHist = timeDim
  .group(d => {
    return binwidth * Math.floor(d / binwidth);
  })
  .reduceCount(); // I believe this only gives sum, but haven't gotten to averaging yet

Which works when I don't care about excluding direction: -1, all attempts to do so have broken my crossfilter, e.g.

const timeSignalDim = ndx.dimension(d => {
    if (d.direction === 1) {
      return d.time;
    }
  });

Solution

  • Ended up using reductio... based on this post

    const binwidth = 1;
    const timeDim = ndx.dimension(d => d.time);
    const timeSignalGroup = reductio()
      .count(true)
      .sum(d => d.counts)
      .avg(true)
      .filter(d => {
        return d.direction === 1;
      })(
      timeDim.group(d => {
        return binwidth * Math.floor(d / binwidth);
      })
    );
    

    And accessed the values via valueAccessor fxn

    ...
    .valueAccessor(d => {
      return d.value.avg;
    })
    

    Very happy to entertain any more elegant answers!