我使用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(); });
Run Code Online (Sandbox Code Playgroud)
test_grp.all()[{key: 11, value: 1}, {key: 12, value: 2}]像我期望的那样回归.
如果我将最后一行更改为
test_grp = test_dim.group(function(d) { return -d.getHours(); });
Run Code Online (Sandbox Code Playgroud)
test_grp.all()回报[{key: -11, value: 3}].
为什么不回归[{key: -11, value: 1}, {key: -12, value: 2}]呢?
我不认为这是crossfilter中的问题; 我认为你违反了crossfilter API,它指出:
与value函数一样,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; });
Run Code Online (Sandbox Code Playgroud)
这test_grp也包含[{"key":-11,"value":3}]
事实上,任何date.getAnything()函数通常都不会在组值函数中工作(具有维值函数的日期),除非观察恰好跨越任何一个.
例如,假设您使用date.getMonth()- 如果所有日期都是从一个月开始,那么您就可以了,因为维度的排序与该组的排序相匹配.但是如果日期是3月29日,3月31日,4月1日,4月2日,则crossfilter可以决定它可以在3月29日结束时创建一个组边界,并将最后三个日期粘贴在第二个bin中,或者在4月1日结束,前三个日期.
同样,我正在简化,这不是crossfilter的功能.但是它的算法依赖于<和<=维度值的工作方式与组值相同.如果不是这样,它将无法检测到问题(因为这会很慢) - 它只会默默地创建错误的聚合.
由于NaN没有正确排序的常见投诉不起作用,因此在crossfilter之上有验证库的空间.但是你仍然需要根据它的假设来设置crossfilter,这使它非常有效.