dc.js - 如何从 crossfilter/reductionio 中的组创建组?

标签 dc.js crossfilter reductio

具有以下数据:

const now = new Date
const data = [
  { player: 'bob', color: 'blue', date: new Date(+now + 1000) },
  { player: 'bill', color: 'green', date: new Date(+now + 2000) },
  { player: 'bob', color: 'red', date: new Date(+now + 3000) },
  { player: 'barbara', color: 'blue', date: new Date(+now + 4000) },
  { player: 'barbara', color: 'cyan', date: new Date(+now + 8000) },
  { player: 'barbara', color: 'magenta', date: new Date(+now + 10000) },
  { player: 'barbara', color: 'yellow', date: new Date(+now + 20000) },
]

我想减少颜色维度上的计数,但计算每个玩家的第一个颜色。 (注意:第一个是可能被过滤的日期维度)。我一直在尝试使用异常功能使其与reductio一起使用,但它没有给出预期的结果:

reducer = reductio()
reducer.exception('player').exceptionCount(true)
reducer(colorGroup)

结果应如下所示:

blue,2     # bob and barbara
cyan,0
green,1    # bill
magenta,0
red,0
yellow,0

另一个示例,日期维度过滤为 now+2100..now+20000(即第一行被过滤掉):

blue,1     # barbara
cyan,0
green,0    # (bill's first color is not counted because it is outside the date range)
magenta,0
red,1      # bob (blue is his first color overall, red is his first in this date range)
yellow,0

注意:我还有其他使用所有行的分组,因此我不能在将列表加载到交叉过滤器之前对其进行预过滤。

有什么方法可以使用reductio()来实现这个目的吗?或者一些如何直接使用交叉过滤器进行“分组分组”的示例?

编辑

链接到 jsfiddle 显示意外结果:https://jsfiddle.net/qt5jxjm1/

最佳答案

我不确定 crossfilter 是否会对您有很大帮助 - 它并没有真正考虑值的顺序,而且它当然没有一种方法可以按一个键排序,然后按另一个键进行装箱。

这是一个假组,它通过使用另一个维度进行排序,以及组键和“第一个字段”(即您要查找第一个字段的字段)的几个访问器来实现接近您想要的功能的:

function double_reduce(dim, groupf, firstf) {
    return {
      all: function() {
      var recs = dim.bottom(Infinity);
      var hit = {}, bins = {};
      recs.forEach(function(r) {
        var fkey = firstf(r), gkey = groupf(r);
        var count = hit[fkey] ? 0 : 1;
        hit[fkey] = true;
        bins[gkey] = (bins[gkey] || 0) + count;
      });
      return Object.keys(bins).map(function(k) {
        return {key: k, value: bins[k]};
      });
    }
  }
}

像这样使用它:

var dubred_group = double_reduce(dateDim,
    function(r) { return r.color;}, function(r) { return r.player; });

它不能做的一件事是为任何被过滤掉的值提供零。通常,交叉过滤器会进行增量添加和删除,我不知道这里如何实现这一点。

因此,没有过滤任何日期的结果看起来不错:

[
  {
    "key": "blue",
    "value": 2
  },
  {
    "key": "green",
    "value": 1
  },
  {
    "key": "red",
    "value": 0
  },
  {
    "key": "cyan",
    "value": 0
  },
  {
    "key": "magenta",
    "value": 0
  },
  {
    "key": "yellow",
    "value": 0
  }
]

但是过滤后的情况缺少一个 bin,因为过滤后的数据中没有出现绿色:

[
  {
    "key": "red",
    "value": 1
  },
  {
    "key": "blue",
    "value": 1
  },
  {
    "key": "cyan",
    "value": 0
  },
  {
    "key": "magenta",
    "value": 0
  },
  {
    "key": "yellow",
    "value": 0
  }
]

这个问题可能会被修复,但我想我会发布这个以获得反馈。

fiddle 演示:http://jsfiddle.net/zdq4rj13/7/

关于dc.js - 如何从 crossfilter/reductionio 中的组创建组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39693350/

相关文章:

javascript - DC.js 等值线 map CSS 与颜色冲突,没有 map 显示。如何关闭填充:none?

javascript - 意外的画笔过滤行为

javascript - 使用 dc.js 进行简单列表过滤器和搜索过滤器?

d3.js - 使用大型数据集和 d3.scale.linear() 时,使 dc.js 中的条宽和间隙保持一致

d3.js - 从另一个数据集在 dc.js 中添加过滤器

d3.js - d3 onclick 获取具体路径/栏引用

javascript - Crossfilter 在数据集中没有负数的 dc.js 上显示负数

javascript - 在 crossfilter 的 reducio 中将自定义函数与预定义函数混合