d3使用循环嵌套在几个键上

时间:2012-09-13 21:10:18

标签: javascript csv svg nested d3.js

我正在使用d3.nest()来从CSV文件制作分层对象。

您能帮我理解为什么以下代码不起作用。 我没有设法在循环中使用嵌套函数,如下所述。

我有以下CSV文件,取自d3网站上的示例:

"type1","type2","type3","type4","type5","size"
"flare","analytics","cluster","AgglomerativeCluster","","3938"
"flare","analytics","cluster","CommunityStructure","","3812"
"flare","analytics","cluster","MergeEdge","","743"
"flare","analytics","graph","BetweennessCentrality","","3534"
"flare","analytics","graph","LinkDistance","","5731"

这个基本的嵌套工作:

data = data.entries(csv)
        .key(function(d) {return d.type1; })
        .key(function(d) {return d.type2; })
        .key(function(d) {return d.type3; })
        .entries(csv);

我想使用一组值来指定我的键,以便动态修改它们。

这有效:

    var data = d3.nest();
    var nesting = ["type1","type2","type3"];
    data = data.key(function(d) {return d[nesting[0]]; });
    data = data.key(function(d) {return d[nesting[1]]; });
    data = data.key(function(d) {return d[nesting[2]]; });
    data = data.entries(csv);

但它不适用于循环......

    var data = d3.nest();
    for(var i=0;i<nesting.length;i++)
    {
        data = data.key(function(d) {return d[nesting[i]]; });
    }
    data = data.entries(csv);

我无法理解为什么循环版本不起作用...也许我想念d3.nest()功能......

此外,我想知道如果在此级别没有任何内容填充(例如:上面提取的所有行中的“type5”级别),是否有“跳过”嵌套级别的方法。我怎么能这样做?

非常感谢您的阅读!

2 个答案:

答案 0 :(得分:15)

这不是.nest()运算符的问题,这是JavaScript闭包的问题。只要你有这种模式:

for (var x=0; x < y; x++) {
    something.attachCallback(function() {
        // now do something with x
    });
}

你将遇到关闭问题。您定义的内部匿名函数不包含x值的副本,它包含外部变量x引用,它将在更新时更新外部变量更新。因此,在循环结束时,每个一个回调函数中x的值将是循环中x的最终值(在上面的代码中, y;在您的代码中nesting.length)。

D3 .nest()运算符使用其.key()参数作为回调 - 在您致电.map().entries()之前,它们不会被执行。所以上面的问题适用。

有多种方法可以解决这个问题;我倾向于使用.forEach()而不是for循环。这在旧版浏览器中不起作用,但D3的大多数都不适用,所以你可能很安全:

var data = d3.nest();
nesting.forEach(function(key) {
    data.key(function(d) {return d[key]; })
});

另一种选择是使用单独的函数进行回调定义。将迭代器变量传递给另一个函数将“修复”其值,因为回调现在具有对创建者函数的参数的引用,而不是对原始x变量的引用:

var data = d3.nest();

function addKey(index) {
    data.key(function(d) { return d[nesting[index]]; })
}

for(var i=0;i<nesting.length;i++) {
    addKey(i);
}

还有一些其他方法,但在我看来forEach是最优雅的。

答案 1 :(得分:1)

游戏后期,但这是对@Ciwan上述评论#2的回应。我没有足够的声誉和#34;发表评论,所以我必须在这里回答:

ggplot() + ggtitle("this is title") + xlab("this is x") + ylab("this is y") + theme(plot.title = element_text(margin = margin(b = -10)), axis.title.x = element_text(margin = margin(t = -10)), axis.title.y = element_text(margin = margin(r = -10))) 的结果是正确的:

d3.nest()

如果您想要计算这些项目,可以使用d3.nest()&#39;汇总,如下所示:

{ key: something, values: [all,the,items,that,are,grouped,by,the,key] }

Phoebe Bright's bl.ock是了解d3.nest()

的规范场所