2016-11-30 6 views
3

私はD3.js nesting and rollup at same timeと非常によく似た仕事をしています.d3.js v3の@altocumulusで提供される解決策は、私にとっては完璧にうまく動作します。しかし、私は私のウェブサイト上でd3.js v4を使用していますが、私は同じアプローチをv4で複製することができません - 私は同じ結果を得ていません。おそらく、私はsumChildrenの機能を理解していないためです。 d3.js v4を使用して、ロードされたcsvファイルをすべてのノードレベルで小計付きのjsonとして再構築する方法について、より良い方法または異なる方法を自由に提供してください。私の場合は、人口を国、州および市レベルで設定する必要があります。D3.js v4で同時にネストしてロールアップする

免責事項:私は長年にわたってSOを使用していますが、ほとんどの場合、他の人が投稿した質問から回答がありますが、これが私の最初の質問です。これに加えて、私はd3.jsでnoobの

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は現在{リーフ・エントリの{キー、値}のオブジェクトを返し、代わりのことを教えてくれるキー、値}。

それは最終的にコードを破るリーフ・ノード内のvaluesからvalueに、この小さな改名です。それに応じてヘルパー機能を変更すると、軌道に戻るでしょう:

// 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; 
} 
関連する問題