我正在使用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”级别),是否有“跳过”嵌套级别的方法。我怎么能这样做?
非常感谢您的阅读!
答案 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()
的规范场所