emi*_*ara 2 javascript json d3.js
我d3.nest()用来将平面JSON文件转换为分层树。如果您事先知道数据中的级别,则此方法就很好了:d3.nest()为传递给它的每个键函数创建一个嵌套级别。
但是,我想知道是否存在一种优雅的方式来动态传递键函数。这可能是一个基本问题,但是我的Javascript技能也是基本问题。
这是使用存储在数组中的键名的静态示例:
var levels = ['first', 'second', 'third']
var root = {
    "key":"root", 
    "values": 
        d3.nest()
            .key(function(d){ return d[levels[0]] })
            .key(function(d){ return d[levels[1]] })
            .key(function(d){ return d[levels[2]] })
            .entries(data)
}
现在,我的解决方案是一个if-else循环,该循环以伪动态方式创建不同的嵌套:
// build the nested tree pseudo-dynamically
if (levels.length === 1) {
    var nest = d3.nest()
           .key(function(d){return d[levels[0]]})
           .entries(data);
} else if (levels.length === 2) {
    var nest = d3.nest()
           .key(function(d){return d[levels[0]]})
           .key(function(d){return d[levels[1]]})
           .entries(data);
} else if (levels.length === 3) {
    var nest = d3.nest()
           .key(function(d){return d[levels[0]]})
           .key(function(d){return d[levels[1]]})
           .key(function(d){return d[levels[2]]})
           .entries(data);
}
[...]
有没有一种优雅的方法可以动态地将密钥传递给d3.nest()?我想要的是原则上类似以下示例的示例(该示例无效):
var root = {
    "key":"root", 
    "values": 
        d3.nest()
            for (var i = 0; i < levels.length; i++) {
                .key(function(d){return d[levels[i]]})
            }
            .entries(data)
}
谢谢你的时间!
它不像假设的优雅代码那么容易,但是与if-else方法相比,您当然可以简化它。
第一个本能是做这样的事情:
var levels = ['first', 'second', 'third']
var nest = d3.nest();
for (var i = 0; i < levels.length; i++) {
    nest = nest.key(function(d){return d[levels[i]]});
    //create a new nesting function that has one more key function added
    //and save it in the variable
}
var root = {
      "key":"root", 
      "values": nest.entries(data) //compute the nest
    }
但是,这不起作用,因为在创建所有嵌套函数之后才会使用嵌套函数,因此,在实际运行嵌套时,i变量等于3并levels[i]返回undefined,因此d[levels[i]]返回undefined。  这里的例子。
您需要创建一个单独的功能机柜,以便将的正确值levels锁定在:
function createNestingFunction(propertyName){
  return function(d){ 
            return d[propertyName];
         };
}
var levels = ['first', 'second', 'third']
var nest = d3.nest();
for (var i = 0; i < levels.length; i++) {
    nest = nest.key( createNestingFunction(levels[i]) );
    //create a new nesting function that has one more key function added
    //and save it in the variable
    //the function `createNestingFunction` is called *immediately*
    //with a parameter based on the current value of `i`
    //the returned function will always use that parameter,
    //regardless of how many times createNestingFunction is called
}
var root = {
      "key":"root", 
      "values": nest.entries(data) //compute the nest
    }
该示例的工作版本:http : //fiddle.jshell.net/brVLH/1/
| 归档时间: | 
 | 
| 查看次数: | 3701 次 | 
| 最近记录: |