数据填充正确所需的group.all()调用

时间:2014-09-09 07:09:10

标签: dc.js crossfilter

因此,当交叉过滤器使用数组而不是文字数时,处理基于变量的组处理时遇到了一个奇怪的问题。

我目前有一个日期的输出数组,然后是4个值,然后我将其映射到复合图形。问题是4个值可能会根据给页面的输入而波动。我的意思是,基于它收到的东西,我可以有3个值,或10,并且没有办法提前知道。将它们放入阵列中,然后将其放入交叉滤波器中。在测试时,我正在使用

进行访问
dimension.group.reduceSum(function(d) { return d[0]; });

其中0被改为我需要的任何东西。但是我已经完成了大部分测试,并开始将其调整为一个可以改变的动态系统,但总是至少前两个。为此,我创建了一个整数,用于跟踪我所处的索引,然后在创建组后增加它。正在使用以下代码:

var range = crossfilter(results);
var dLen = 0;
var curIndex = 0;
var dateDimension = range.dimension(function(d) { dLen = d.length; return d[curIndex]; });
curIndex++;
var aGroup = dateDimension.group().reduceSum(function(d) { return d[curIndex]; });
curIndex++;
var bGroup = dateDimension.group().reduceSum(function(d) { return d[curIndex]; });
curIndex++;
var otherGroups = [];
for(var h = 0; h < dLen-3; h++) {
    otherGroups[h] = dateDimension.group().reduceSum(function(d) { return d[curIndex]; });
    curIndex++;
}
var charts = [];
for(var x = 0; x < dLen - 3; x++) {
    charts[x] = dc.barChart(dataGraph)
        .group(otherGroups[x], "Extra Group " + (x+1))
        .hidableStacks(true)
}
charts[charts.length] = dc.lineChart(dataGraph)
    .group(aGroup, "Group A")
    .hidableStacks(true)
charts[charts.length] = dc.lineChart(dataGraph)
    .group(aGroup, "Group B")
    .hidableStacks(true)

问题是: 图表变为空白。我多次检查了curIndex变量,它始终是正确的。我最终决定使用.all()方法检查实际组的结果数据。

奇怪的是,在我使用.all()之后,现在数据正常工作。如果没有.all()调用,图形无法确定数据并且绝对不输出任何内容,但是如果我在创建组后立即调用.all(),则会正确填充。

每个组都需要调用.all(),或者只调用那些可以工作的.all()。例如,当我第一次调试时,我只在aGroup上使用.all(),并且只有aGroup填充到图中。当我将它添加到bGroup时,则同时填充aGroup和bGroup。因此,在当前构建中,每个组在创建后都会直接调用.all()。

从技术上讲,没有问题,但我真的很困惑为什么需要它。我完全不知道这是什么原因,我想知道是否有任何洞察力。当我使用文字时,没有问题,它只发生在我使用变量来创建组时。我试图稍后获得输出,当我这样做时,我收到所有值的NaN。我不确定为什么.all()正在将值改变为应该是什么,尤其是当它只在我创建组后立即执行时才会发生。

下面是图表的屏幕截图。顶部是在创建后所有内容都有.all()调用时,而底部是在额外组(在for循环中定义的那些)不再具有.all()调用时。数据根本就不存在,我不确定为什么。任何想法都会很棒。

http://i.stack.imgur.com/0j1ey.jpg

1 个答案:

答案 0 :(得分:0)

看起来你可能已经遇到了经典的“从循环中生成lambdas”JavaScript问题。

您正在创建一大堆引用curIndex的函数,但除非您立即调用这些函数,否则它们将在全局环境中引用同一个curIndex实例。因此,如果您在初始化后调用它们,它们可能都会尝试使用超过结束的值。

相反,您可以创建一个生成lambdas的函数,如下所示:

function accessor(curIndex) {
    return function(d) { return d[curIndex]; };
}

然后每次拨打.reduceSum(accessor(curIndex))

这会导致每次调用accessor函数时都会复制curIndex的值(或者您可以将每个生成的函数视为具有自己的curIndex自己的环境。)