Search code examples
javascriptd3.jstreemap

d3.nest() key and values conversion to name and children


I am working on creating a Treemap from a csv file. The data in the csv file is hierarchical, as a result I used d3.nest().

However, the resulting JSON is in the form of {key:"United States", values:[...]}. The zoom-able treemap requires hierarchy as {name:"United States", children:[...]}. I have tried replacing name and children to key and values in the example, but it doesn't work.

If anyone has already looked into using key and values on a zoomable treemap, please help. I am new to D3 and I don't know whether d.children means structure or value from the data.

This is the code to convert World Continents, Regions, and Countries from CSV to a hierarchy using d3.

$ d3.csv("../Data/WorldPopulation.csv", function (pop) {
    var treeData= { "key": "World", "values": d3.nest()
   .key(function (d) { return d.Major_Region; })
   .key(function (d) { return d.Region; })
   .key(function (d) { return d.Country; })
   .entries(pop)
};

The first few lines of the result is:

 `[{"key":"AFRICA","values":[{"key":"Eastern Africa","values"
 [{"key":"Burundi","values":[.........`

I can not use the zoomable treemap because it requires name and children labels in json rather than key and values.


Solution

  • The best way to convert a nest to a treemap is specifying children accessor function with Treemap.children().

    In the zoomable treemap example , it requires not only "children" but also "name" and "size". You can do either:

    1)change the accessor functions of those properties so that keep using "key" and "value".

    Let's change the source code.

    1.1)line 79 & 86:

     .style("fill", function(d) { return color(d.parent.name); });
    
     .text(function(d) { return d.name; })
    

    Replace ".name" with ".YOUR_NAME_KEY"(i.e. ".key")

     .style("fill", function(d) { return color(d.parent.YOUR_NAME_KEY); });
    
     .text(function(d) { return d.YOUR_NAME_KEY; })
    

    1.2)line 47:

    var treemap = d3.layout.treemap()
    .round(false)
    .size([w, h])
    .sticky(true)
    .value(function(d) { return d.size; });
    

    Append a line to specify children accessor function.(i.e ".values")

    var treemap = d3.layout.treemap()
    .round(false)
    .size([w, h])
    .sticky(true)
    .value(function(d) { return d.YOUR_SIZE_KEY; })
    .children(function(d){return d.YOUR_CHILDREN_KEY});
    

    1.3)line 97 & 51:

    function size(d) {
      return d.size;
    }
    

    Replace ".size" with ".YOUR_SIZE_KEY"(you didn't mention in your resulting JSON)

    function size(d) {
      return d.YOUR_SIZE_KEY;
    }
    

    P.S. Maybe something omitted, you need verify it yourself.

    2)convert your JSON structure to fit the example with Array.map().