首页 > 解决方案 > d3 分组和总结

问题描述

我有一个 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);

但我无法设法让两者一起工作。我考虑过手动循环遍历摘要对象并将原始对象中的相应记录填充到其中,但这似乎开销太大。

标签: javascriptd3.js

解决方案


你与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>


推荐阅读