2016-11-30 70 views
3

我有一个非常类似的任务D3.js nesting and rollup at same time@altocumulus提供的解决方案,因为d3.js v3对我来说(测试)完美地工作。但是,我在我的网站上使用d3.js v4,并且在使用v4复制相同的方法时遇到困难 - 我没有得到相同的结果。也许,因为我不懂sumChildren函数。请随时提供更好的或不同的方法,以便如何使用d3.js v4将每个节点级别的小计重新组织为加载的csv文件。在我的情况下,我需要在国家,州和城市层面有人口D3.js在v4中同时嵌套和汇总

免责声明:我一直在使用SO多年,在大多数情况下,我从其他人发布的问题中得到答案,但这是我的第一个问题。除了这个,我小白在d3.js

population.csv:

Country,State,City,Population 
"USA","California","Los Angeles",18500000 
"USA","California","San Diego",1356000 
"USA","California","San Francisco",837442 
"USA","Texas","Austin",885400 
"USA","Texas","Dallas",1258000 
"USA","Texas","Houston",2196000 

的index.html:

<!DOCTYPE html> 
<html> 
<head> 
    <title> Test D3.js</title> 
</head> 
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script> 
--> 
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.4.0/d3.min.js"></script> 
<body> 

<script> 
d3.csv("population.csv", function(error, data) { 
if (error) throw error; 

var nested = d3.nest() 
       .key(function(d) { return d.Country; }) 
       .key(function(d) { return d.State; }) 
       .rollup(function(cities) { 
       return cities.map(function(c) { 
        return {"City": c.City, "Population": +c.Population }; 
       }); 
       }) 
       .entries(data); 


// Recursively sum up children's values 
function sumChildren(node) { 
    node.Population = node.values.reduce(function(r, v) { 
    return r + (v.values ? sumChildren(v) : v.Population); 
    },0); 
    return node.Population; 
} 

// Loop through all top level nodes in nested data, 
// i.e. for all countries. 
nested.forEach(function(node) { 
    sumChildren(node); 
}); 

// Output. Nothing of interest below this line. 
d3.select("body").append("div") 
    .style("font-family", "monospace") 
    .style("white-space", "pre") 
    .text(JSON.stringify(nested,null,2)); 

}); 
</script> 
</body> 
</html> 

结果:

[ 
    { 
    "key": "USA", 
    "values": [ 
     { 
     "key": "California", 
     "value": [ 
      { 
      "City": "Los Angeles", 
      "Population": 18500000 
      }, 
      { 
      "City": "San Diego", 
      "Population": 1356000 
      }, 
      { 
      "City": "San Francisco", 
      "Population": 837442 
      } 
     ] 
     }, 
     { 
     "key": "Texas", 
     "value": [ 
      { 
      "City": "Austin", 
      "Population": 885400 
      }, 
      { 
      "City": "Dallas", 
      "Population": 1258000 
      }, 
      { 
      "City": "Houston", 
      "Population": 2196000 
      } 
     ] 
     } 
    ], 
    "Population": null 
    } 
] 

期望的结果:

[ 
    { 
    "key": "USA", 
    "values": [ 
     { 
     "key": "California", 
     "values": [ 
      { 
      "City": "Los Angeles", 
      "Population": 18500000 
      }, 
      { 
      "City": "San Diego", 
      "Population": 1356000 
      }, 
      { 
      "City": "San Francisco", 
      "Population": 837442 
      } 
     ], 
     "Population": 20693442 
     }, 
     { 
     "key": "Texas", 
     "values": [ 
      { 
      "City": "Austin", 
      "Population": 885400 
      }, 
      { 
      "City": "Dallas", 
      "Population": 1258000 
      }, 
      { 
      "City": "Houston", 
      "Population": 2196000 
      } 
     ], 
     "Population": 4339400 
     } 
    ], 
    "Population": 25032842 
    } 
] 

回答

3

V4的changelog告诉我们,

当结合nest.rollup使用,nest.entries现在返回{键,值}对象,而不是为叶条目,{键,值}。

这是从valuesvalue在叶节点最终打破代码这个小改名。相应地更改辅助功能应该能让您重新走上正轨:

// Recursively sum up children's values 
function sumChildren(node) { 
    if (node.value) { 
    node.values = node.value; // Ensure, leaf nodes will also have a values array 
    delete node.value;   // ...instead of a single value 
    } 
    node.Population = node.values.reduce(function(r, v) { 
    return r + (v.value? sumChildren(v) : v.Population); 
    },0); 
    return node.Population; 
}