Array manipulation with d3.nest and rollup

谁都会走 提交于 2020-01-03 00:52:11

问题


This is the array I want to reproduce:

[{ plts: 'Zlnd', values: { '150k': 4786, '200k': 1319, '250k': 249 }}
,{ plts: 'Hsls', values: { '150k': 1101, '200k': 412, '250k': 674 }}]

However, I don't get beyond the point of where 1) I have a grouping which just gives me a total sum at 'plts' level and not any of the detail elements and 2) the sum is located at the leaf level of 'values', but I need it to be at the 'plts'level.

Using this to get the flat data from mysql (which works, but does not yet give the values for the grouping):

 d3.json("php/data3.php", function (error, JsonData) {
            JsonData.forEach(function (d) {
                d['150k'] = +d['150k'];
                d['200k'] = +d['200k'];
                d['250k'] = +d['250k']; 

The result:

[{"plts":"Zlnd","150k":4786,"200k":1319,"250k":249}
,{"plts":"Hsls","150k":1101,"200k":412,"250k":674}

and this to format the flat array to the one I need:

        var nested_data = d3.nest()
             .key(function (d) { return d.plts; })
             .rollup(function (v) {
                      return {
                      total: d3.sum(v, function (g) { return +g['150k'] + g['200k'] + g['250k'];})
                             };
                       })
                      .entries(JsonData)
                  });

Any help is very appreciated!


回答1:


This is not the use case for d3.nest. Nest would be appropriate if your data was in the form:

[
    { "plts": "Zlnd", "bin": "150k", "amount": 4786 },
    { "plts": "Zlnd", "bin": "200k", "amount": 1319 },
    { "plts": "Zlnd", "bin": "250k", "amount": 249 },
    { "plts": "Hsls", "bin": "150k", "amount": 1101 },
    { "plts": "Hsls", "bin": "200k", "amount": 412 },
    { "plts": "Hsls", "bin": "250k", "amount": 674 }
]

Then

d3.nest()
  .key(function (d) { return d.plts; })
  .entries(JsonData)

Would produce

[
  { key: "Zlnd", values: [
    { "plts": "Zlnd", "bin": "150k", "amount": 4786 },
    { "plts": "Zlnd", "bin": "200k", "amount": 1319 },
    { "plts": "Zlnd", "bin": "250k", "amount": 249 }
  ] },
  { key: "Hsls", values: [
    { "plts": "Hsls", "bin": "150k", "amount": 1101 },
    { "plts": "Hsls", "bin": "200k", "amount": 412 },
    { "plts": "Hsls", "bin": "250k", "amount": 674 }
  ] }
]

which you could rollup using

.rollup(function(values) {
  return d3.sum(values, function(v) { return v.amount; });
})

producing

[
  { key: "Zlnd", values: 6354 },
  { key: "Hsls", values: 2184 }
]

You can also use

d3.nest()
  .key(function (d) { return d.bin; })
  .entries(JsonData)

which would produce

[
  { key: "150k", values: [
    { "plts": "Zlnd", "bin": "150k", "amount": 4786 },
    { "plts": "Hsls", "bin": "150k", "amount": 1101 }
  ] },
  { key: "200k", values: [
    { "plts": "Zlnd", "bin": "200k", "amount": 1319 },
    { "plts": "Hsls", "bin": "200k", "amount": 412 }
  ] },
  { key: "250k", values: [
    { "plts": "Zlnd", "bin": "250k", "amount": 249 },
    { "plts": "Hsls", "bin": "250k", "amount": 674 }
  ] }
]

That way you can similarly use rollup to get the sum total of each bin — across all plts.

Hope that makes sense. Not sure if this is what you're trying to achieve, but it gives you a sense of what nest is good for. If none of this applies, just use vanilla javascript to derrive the values you want from the data you're loading and skip using d3.nest.



来源:https://stackoverflow.com/questions/25642422/array-manipulation-with-d3-nest-and-rollup

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!