Crossfilter组功能的奇怪行为

时间:2016-09-12 17:51:36

标签: crossfilter

我使用dc.js和Crossfilter面临一个奇怪的问题。想象一下以下数据和代码

test_data = [{date: d3.time.format("%Y-%m-%dT%H:%M:%S+0100").parse("2014-11-24T12:00:00+0100"), cnt: 1}, 
             {date: d3.time.format("%Y-%m-%dT%H:%M:%S+0100").parse("2014-11-24T11:00:00+0100"), cnt: 2},
             {date: d3.time.format("%Y-%m-%dT%H:%M:%S+0100").parse("2014-11-24T12:00:00+0100"), cnt: 3}],
test_ndx = crossfilter(test_data),
test_dim = test_ndx.dimension(function(d) { return d.date; }),
test_grp = test_dim.group(function(d) { return d.getHours(); });

test_grp.all()按照我的预期返回[{key: 11, value: 1}, {key: 12, value: 2}]

如果我将最后一行更改为

test_grp = test_dim.group(function(d) { return -d.getHours(); });

test_grp.all()返回[{key: -11, value: 3}]

为什么不返回[{key: -11, value: 1}, {key: -12, value: 2}]

1 个答案:

答案 0 :(得分:5)

我不认为这是crossfilter中的一个问题;我认为你违反了crossfilter API,它指出:

  

与值函数一样, groupValue 必须返回一个自然排序的值;此外,此订单必须与维度功能一致!

https://github.com/crossfilter/crossfilter/wiki/API-Reference#dimension_group

具体地

由于减号, groupValue 函数返回的值的顺序将反转为尺寸函数值的顺序。

我过度简化了,但在下面,crossfilter组试图保持bin的索引的顺序与维度具有自己的所有值索引的顺序相同。如果组的索引中的值无序,则无法正确确定bin边界。这些简单的假设是使crossfilter如此之快的部分原因。

这是一个更简单的示例,不使用具有相同行为的日期:

test_data = [{date: 12, cnt: 1}, 
             {date: 11, cnt: 2},
             {date: 12, cnt: 3}],
test_ndx = crossfilter(test_data),
test_dim = test_ndx.dimension(function(d) { return d.date; }),
test_grp = test_dim.group(function(d) { return -d; });

test_grp还包含[{"key":-11,"value":3}]

一般

实际上,任何date.getAnything()函数通常都不会在组值函数中使用(具有维值函数的日期),除非观察恰好跨越了Anything。

例如,假设您使用date.getMonth() - 如果所有日期都是从一个月开始,那么您就可以了,因为维度的排序与群组相匹配。但是如果日期是3月29日,3月31日,4月1日,4月2日,则crossfilter可以决定它可以在3月29日结束时创建一个组边界,并将最后三个日期粘贴在第二个bin中,或者在4月1日结束,前三个日期。

同样,我简化了,这不是crossfilter的功能。但是它的算法依赖于<<=以相同的方式处理维度值和组值。如果这不是真的,它就不会检测到问题(因为这会很慢) - 它会默默地创建错误的聚合。

正如NaN由于订单排序不正常而导致的常见投诉一样,在crossfilter之上还有验证库的空间。但是你仍然需要根据它的假设设置交叉滤波器,这使得它的效率非常高。