2016-11-30 4 views
3

Ich habe eine sehr ähnliche Aufgabe wie D3.js nesting and rollup at same time und Lösung von @altocumulus für d3.js v3 funktioniert völlig in Ordnung für mich (getestet). Allerdings verwende ich d3.js v4 auf meiner Website und ich habe Schwierigkeiten, den gleichen Ansatz mit v4 zu replizieren - ich bekomme nicht die gleichen Ergebnisse. Vielleicht, weil ich nicht verstehen, die sumChildren Funktion. Bitte zögern Sie nicht einen besseren oder anderen Ansatz zu geben, wie die geladenen CSV-Datei als Json mit Teilsumme an jeder Knotenebene v4 mit d3.js restrukturieren. In meinem Fall muss ich Bevölkerung im Land, Staat und die Stadt Ebenen haben.D3.js Verschachtelung und Rollup zur gleichen Zeit in v4

Haftungsausschluss: Ich habe SO seit vielen Jahren mit und in den meisten Fällen die ich von Fragen meine Antworten bekam von anderen Leuten geschrieben, aber dies ist meine erste Frage. Zusätzlich dazu bin ich Noob in 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> 

Ergebnisse:

[ 
    { 
    "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 
    } 
] 

Gewünschte Ergebnisse:

[ 
    { 
    "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 
    } 
] 

Antwort

3

Die v4 changelog sagt uns, dass

Wenn mit nest.rollup in Verbindung, nest.entries kehrt nun {Schlüssel, Wert} Objekte für die Blatteinträge, statt { Schlüssel, Werte}.

Es ist diese kleine Umbenennung von values zu value in den Blattknoten, die schließlich den Code bricht. die Hilfsfunktion ändern entsprechend sollten Sie wieder auf die Strecke:

// 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; 
}