Javascript crossfilter.js-基于单独维度从组中排除事实

Javascript crossfilter.js-基于单独维度从组中排除事实,javascript,mapreduce,dc.js,crossfilter,Javascript,Mapreduce,Dc.js,Crossfilter,假设我在dc.js散点图中绘制了以下交叉过滤器对象(简化) 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, directio

假设我在dc.js散点图中绘制了以下交叉过滤器对象(简化)

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},
  ...
]);
如何设置交叉滤波器,使输出向量

x --> [0,1,2,...] 
y --> [8,9,14,...] // (average of all "1" direction transition counts, per whole integer time)
到目前为止,我所拥有的是

当我不关心排除方向时,它就起作用了:-1,所有这样做的尝试都破坏了我的交叉过滤器,例如

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

最后使用了还原。。。基于

并通过valueAccessor fxn访问值

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

很高兴接受任何更优雅的回答

维度和组函数中的每个路径都必须返回一个值,否则Javascript中的默认返回值为
undefined
,这将导致

此外,无法拒绝维度或组键函数中的行。相反,您必须将被拒绝的行减少为零:

const timeDim = ndx.dimension(d => d.time);
const binwidth = 1;
const timeHist = timeDim
  .group(d => {
    return binwidth * Math.floor(d / binwidth);
  })
  .reduceSum(d => d.direction > 0 ? 1 : 0);
这将计算所有正向。这相当于您的答案中ReduceTio的
.filter()

ReduceTio非常优雅,但只是为了比较,因为我在你发布答案之前就开始回答这个问题,所以计算平均值的直接交叉过滤方法是

.reduce(
  (p,v) => { // add
    p.sum += v.counts;
    p.count++;
    return p;
  },
  (p,v) => { // remove
    p.sum -= v.counts;
    p.count--;
    return p;
  },
  () => ({sum: 0, count: 0}));
告诉图表在读取数值时计算比率:

chart.valueAccessor(({value: {sum,count}}) => sum / count);
结合跳跃方向<0:

.reduce(
  (p,v) => { // add
    if(v.direction > 0) {
      p.sum += v.counts;
      p.count++;
    }
    return p;
  },
  (p,v) => { // remove
    if(v.direction > 0) {
      p.sum -= v.counts;
      p.count--;
    }
    return p;
  },
  () => ({sum: 0, count: 0}));


同样,reductio也在做同样的事情。如果您想使用光滑的EDSL或直接使用交叉过滤器,请选择。

您的答案总是非常棒!谢谢,我投了赞成票,但是接受了reductio版本,因为它对我来说更简单。。。我对更复杂的交叉过滤操作感兴趣,你知道关于交叉过滤自定义缩减器函数的任何好的博客文章/教程吗?我已经看过api文档,据我所知,它非常复杂,所以答案是最好的文档。我试图让我的每一个答案都解释得比手头任务所需的多一点,而不是全面的文档。(我从来没有时间写一本书。)这本书也很好。如果你能找到好的资源,请告诉我!
chart.valueAccessor(({value: {sum,count}}) => sum / count);
.reduce(
  (p,v) => { // add
    if(v.direction > 0) {
      p.sum += v.counts;
      p.count++;
    }
    return p;
  },
  (p,v) => { // remove
    if(v.direction > 0) {
      p.sum -= v.counts;
      p.count--;
    }
    return p;
  },
  () => ({sum: 0, count: 0}));