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

后端 未结 4 1242
梦谈多话
梦谈多话 2020-12-05 08:31

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

4条回答
  •  粉色の甜心
    2020-12-05 08:58

    Since d3-collection has been deprecated in favor of d3.array, we can use d3.rollups to achieve what used to work with d3.nest:

    var input = [
      { "Continent": "Europe", "Country": "Spain", "City": "Madrid", "value": "3" },
      { "Continent": "Europe", "Country": "Spain", "City": "Barcelona", "value": "30" },
      { "Continent": "Europe", "Country": "France", "City": "Paris", "value": "243" },
      { "Continent": "America", "Country": "Argentina", "City": "Buenos Aires", "value": "300" },
      { "Continent": "America", "Country": "Argentina", "City": "Buenos Aires", "value": "250" },
      { "Continent": "America", "Country": "Argentina", "City": "Rosario", "value": "200" }
    ];
    
    // Nesting:
    var rolled_up = d3.rollups(
      input,                           // The array on which to apply the rollup
      vs => d3.sum(vs, v => +v.value), // The reducing function to apply on rollups' leafs
      d => d.Continent,                // A first level of nesting
      d => d.Country                   // A second level of nesting
    );
    
    // Formatting:
    var output = {
      key: "World",
      values: rolled_up.map(x => ({
        key: x[0], // continent
        values: x[1].map(x => ({
          key: x[0], // country
          values: x[1]
        }))
      }))
    }
    
    console.log(output);

    This:

    • Applies a d3.rollups:
      • d3.rollups take 3 parameters: the input array, a reducing function and a variable number of mappers for the different levels of nesting
      • The reducing function (vs => d3.sum(vs, v => +v.value)) takes the values associated to the grouped countries, cast them to int and sum them (using d3.sum)
      • The two levels of nesting group elements first on the Continent and then on the Country
    • Formats each nested part of the rollups' output in order to get the expected output.

    Here is the intermediate result produced by d3.rollups (before formatting):

    var input = [
      { "Continent": "Europe", "Country": "Spain", "City": "Madrid", "value": "3" },
      { "Continent": "Europe", "Country": "Spain", "City": "Barcelona", "value": "30" },
      { "Continent": "Europe", "Country": "France", "City": "Paris", "value": "243" },
      { "Continent": "America", "Country": "Argentina", "City": "Buenos Aires", "value": "300" },
      { "Continent": "America", "Country": "Argentina", "City": "Buenos Aires", "value": "250" },
      { "Continent": "America", "Country": "Argentina", "City": "Rosario", "value": "200" }
    ];
    
    var rolled_up = d3.rollups(
      input,
      vs => d3.sum(vs, v => +v.value),
      d => d.Continent,
      d => d.Country
    );
    
    console.log(rolled_up);

提交回复
热议问题