d3分组和总结

时间:2018-05-21 18:33:35

标签: javascript d3.js

我有一个JSON数据对象,包含区域,邮政编码和每个邮政编码的项目数量。我试图按区域汇总(汇总)数量总和和记录数量的总和。我目前正在使用d3.js,但如果它们更适合需要,我会对其他库开放。

原始数据结构的一个示例:

var test = [  
   {  
      "Name":"One Name",
      "Zip":"75001",
      "Zone":"A",
      "qty":60
   },
   {  
      "Name":"Two Name",
      "Zip":"75003",
      "Zone":"A",
      "qty":40
   },
   {  
      "Name":"Three Name",
      "Zip":"75009",
      "Zone":"B",
      "qty":20
   }
]

这是我想要实现的理想结果:

[  
   {  
      "Zone":"A",
      "qtySum":100,
      "cnt":2,
      "values":[  
         {  
            "Name":"One Name",
            "Zip":"75001",
            "Zone":"A",
            "qty":60
         },
         {  
            "Name":"Two Name",
            "Zip":"75003",
            "Zone":"A",
            "qty":40
         }
      ]
   },
   {  
      "Zone":"B",
      "qtySum":20,
      "cnt":1,
      "values":[  
         {  
            "Name":"Three Name",
            "Zip":"75009",
            "Zone":"B",
            "qty":20
         }
      ]
   }
]

我可以通过以下方式实现没有摘要数据的分组:

d3.nest()
.key(function(d) { return d.Zone; })
.entries(test)

我可以通过以下方式将数据汇总到摘要对象中:

d3.nest()
.key(function(d) { return d.Zone; })
.rollup(function(v) { return {
        count: v.length,
        total: d3.sum(v, function(d) { return d.qty; }),
    }; 
})
.entries(test);

但我无法让两者一起工作。我想过手动循环遍历摘要对象并用原始对象中的相应记录填充它,但这似乎是太多的开销。

1 个答案:

答案 0 :(得分:0)

你与rollup非常接近。 要添加原始对象,请将values: v添加到返回的对象。 然后,使用map更改对象并以所需格式返回。

var test = [  
   {  
      "Name":"One Name",
      "Zip":"75001",
      "Zone":"A",
      "qty":60
   },
   {  
      "Name":"Two Name",
      "Zip":"75003",
      "Zone":"A",
      "qty":40
   },
   {  
      "Name":"Three Name",
      "Zip":"75009",
      "Zone":"B",
      "qty":20
   }
];

var grouped = d3.nest()
  .key(function(d) { return d.Zone; })
  .rollup(function(v) { 
    return {
      cnt: v.length,
      qtySum: d3.sum(v, function(d) { return d.qty; }),
      values: v
    }; 
  })
  .entries(test)
  .map(function(d) {
    return {
      Zone: d.key,
      qtySum: d.value.qtySum,
      cnt: d.value.cnt,
      values: d.value.values
    };
  });

d3.select("#foo").text(JSON.stringify(grouped, null, 2));
<script src="https://d3js.org/d3.v4.min.js"></script>
<pre id="foo"></pre>