Javascript “如何区分”;0“;dc.js GeogoroplethChart中过滤出的值?

Javascript “如何区分”;0“;dc.js GeogoroplethChart中过滤出的值?,javascript,d3.js,dc.js,crossfilter,Javascript,D3.js,Dc.js,Crossfilter,我正在使用crossfilter.js、d3.js和dc.js制作一些仪表板,但是当数据集的值为“0”时,我遇到了一些问题 在仪表板中有一个dc.geogoroplethChart(),我使用.colorCalculator()来区分过滤后的值:如果定义了d而不是0,则使用颜色,否则使用#666 问题是: 对于与过滤器无关的值,crossfilter返回0(这些值在映射上由.colorCalculator()函数正确呈现为#666) 如果过滤值中的值为0,则也会呈现为#666 我无法区分一个

我正在使用crossfilter.js、d3.js和dc.js制作一些仪表板,但是当数据集的值为“0”时,我遇到了一些问题
在仪表板中有一个dc.geogoroplethChart(),我使用.colorCalculator()来区分过滤后的值:如果定义了d而不是0,则使用颜色,否则使用#666

问题是:

  • 对于与过滤器无关的值,crossfilter返回0(这些值在映射上由.colorCalculator()函数正确呈现为#666)
  • 如果过滤值中的值为0,则也会呈现为#666
我无法区分一个值是0,因为它必须是0,还是因为它与过滤器无关

[示例]
我制作了一个超级简单的jsfiddle来说明这个问题
数据集如下所示:

{id:"a1", tipo: "a", val: 0},
{id:"a2", tipo: "a", val: 1},
{id:"a3", tipo: "a", val: 2},
...
id维度上有两个维度(一个是id维度,一个是tipo维度)和一个组。
首先,我只打印id组的输出。
如果单击按钮,则通过“tipo”=“a”对tipo维度进行过滤后,您将获得相同id组的输出。
正如您在fiddle中看到的,“id”=“a1”的记录是过滤维度的一部分,因为它有“tipo”=“a”,它的0值(因为它是它自己的值)与其他不属于过滤维度的记录(b1、b2、b3、…、c4、c5)相同

这与我通过单击仪表板中的另一个图表添加过滤器后在dc.geogoroplethChart()中得到的输出相同,但a无法正确处理值=0:

  • 有没有一种方法可以使交叉筛选返回undefined或null或其他所有值,但不返回0?
  • 或者有一种方法可以修改colorCalculator函数,以检查值是否为0,它是哪种类型的0
[更新]
我试图检查“value=0”的记录是否也是筛选维度输出的一部分。在小提琴示例中,a可以检查dimId.top(无穷大)的输出中是否也存在与值=0相关联的键。
问题是我无法在.colorCalculator()函数中实现这一点。在这个函数中,我只访问值,而不是键。。。此外,遍历每个记录的所有维度值看起来不像是一个智能解决方案(维度由数十万个元素组成…)


谢谢你的帮助

最好的方法可能是使用自定义reduce函数来跟踪每个组的总和和计数。比如:

var dimId = cf.dimension( function (d) { return d.id; } );
var groupId = dimId.group().reduce(
  function(p,v) {
    p.count = p.count + 1;
    p.sum = p.sum + v.val;
    return p;
  }, function (p, v) {
    p.count = p.count - 1;
    p.sum = p.sum - v.val;
    return p;
  }, function () { return { count: 0, sum: 0 }; }
);

在这里,当您执行groupId.top(10)时,您将得到一个组数组,每个组的“值”将是一个具有“sum”和“count”属性的对象。您可以使用“count”属性来确定组中当前是否有记录,如果有,您可以从“sum”属性中读取值。

亲爱的Ethan,您第一次来到意大利,您将赢得一个比萨饼!你的代码工作得很好。我只需要更改.colorCalculator()函数来检查(d&&d.count)是否正确,非常感谢。达妮埃莱
var dimId = cf.dimension( function (d) { return d.id; } );
var groupId = dimId.group().reduce(
  function(p,v) {
    p.count = p.count + 1;
    p.sum = p.sum + v.val;
    return p;
  }, function (p, v) {
    p.count = p.count - 1;
    p.sum = p.sum - v.val;
    return p;
  }, function () { return { count: 0, sum: 0 }; }
);