bob*_*bby 4 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"
Run Code Online (Sandbox Code Playgroud)
这个基本的嵌套工作原理:
data = data.entries(csv)
.key(function(d) {return d.type1; })
.key(function(d) {return d.type2; })
.key(function(d) {return d.type3; })
.entries(csv);
Run Code Online (Sandbox Code Playgroud)
我想使用一个值数组来指定我的键,以便动态地修改它们.
这有效:
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);
Run Code Online (Sandbox Code Playgroud)
但它不适用于循环......
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);
Run Code Online (Sandbox Code Playgroud)
我无法理解为什么循环版本不起作用...也许我想念d3.nest()功能...
此外,我想知道是否有一种方法可以"跳过"嵌套级别,如果此级别没有任何内容填充(即:上面提取的所有行中的"type5"级别).我怎么能这样做?
非常感谢阅读!
nra*_*itz 16
这对.nest()
运算符来说不是问题,这是JavaScript闭包的问题.任何时候你有这种模式:
for (var x=0; x < y; x++) {
something.attachCallback(function() {
// now do something with x
});
}
Run Code Online (Sandbox Code Playgroud)
你将会遇到关闭问题.您定义的内部匿名函数不包含值的副本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]; })
});
Run Code Online (Sandbox Code Playgroud)
另一种选择是使用单独的函数进行回调定义.将迭代器变量传递给另一个函数将"修复"其值,因为回调现在具有对创建者函数的参数的引用,而不是对原始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);
}
Run Code Online (Sandbox Code Playgroud)
还有一些其他的方法,但在我看来forEach
是最优雅的.