Home > Enterprise >  How to change d3.nest to group using reverse
How to change d3.nest to group using reverse

Time:09-21

I'm trying to update some old code for D3 v5 to use the newer group command. I'm not familiar with the sorting, mapping methods but I have rewritten it partially but I do not know how to duplicate the reverse function.

Here's the original:

const years = d3.nest().key(d => d.date.getUTCFullYear()).entries(dateValues).reverse();

For D3 v7 I've gotten this far:

const years = d3.group(dateValues, d => d.date.getUTCFullYear());

However I still need to modify the array structure to duplicate what happens with .reverse().

The group function leaves it as:

Map(10) { 2010 → (276) […], 2011 → (365) […], 2012 → (366) […], 2013 →
(365) […], 2014 → (365) […], 2015 → (365) […], 2016 → (366) […], 2017 → (365) […], 2018 → (365) […], 2019 → (103) […] }

Whereas the original next and reverse left it as an array of key and values

Array(10) [ {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…} ]

0: Object { key: "2019", values: (103) […] } ​ 

1: Object { key: "2018",values: (365) […] } ​ 

2: Object { key: "2017", values: (365) […] } ​

3: Object { key: "2016", values: (366) […] } ​ 

4: Object { key: "2015", values: (365) […] }

5: Object { key: "2014", values: (365)[…] } ​ 

6: Object { key: "2013", values: (365) […] } ​ 

7: Object { key: "2012", values: (366) […] }

8: Object { key: "2011", values:(365) […] }

9: Object { key: "2010", values: (276) […] }

Sorry in advance if I'm not using the correct terminology but I don't work with JS or D3 often. Thanks.


Edit: the data is in json format. Example:

[{
    "Date": "2017-08-30",
    "AnswerCount": "9510"
},
{
    "Date": "2010-05-23",
    "AnswerCount": "2096"
},
{
    "Date": "2014-01-10",
    "AnswerCount": "11451"
},
{
    "Date": "2019-03-23",
    "AnswerCount": "4393"
},
{
    "Date": "2013-03-07",
    "AnswerCount": "11811"
}
]

Edit: doing this gets it closer to the original structure:

            var year_map = d3.group(dateValues, d => d.date.getUTCFullYear());
            var years=Array.from(year_map);
            years.reverse();

However it is not in the Key: Values sort of structure but rather

Array(10) [ (2) […], (2) […], (2) […], (2) […], (2) […], (2) […], (2) […], (2) […], (2) […], (2) […] ]
​
0: Array [ 2019, (103) […] ]
​
1: Array [ 2018, (365) […] ]
​
2: Array [ 2017, (365) […] ]
​
3: Array [ 2016, (366) […] ]
​
4: Array [ 2015, (365) […] ]
​
5: Array [ 2014, (365) […] ]
​
6: Array [ 2013, (365) […] ]
​
7: Array [ 2012, (366) […] ]
​
8: Array [ 2011, (365) […] ]
​
9: Array [ 2010, (276) […] ]

Where the object is an array of objects structured like this:

enter image description here

How would I make this an array of objects with a Key and Values in JS?

CodePudding user response:

After converting the Map object to an array (for instance using Array.from), you just need to reverse and map it to your desired object structure:

const years = Array.from(year_map).reverse().map(d => ({key: d[0], values: d[1]}));

You can also loop the array just once with reduce, but that is probably not necessary.

Here is the demo:

const csv = `year,value
2010,1
2010,2
2010,3
2011,1
2011,2
2011,3
2012,1
2012,2
2012,3`;

const data = d3.csvParse(csv, d3.autoType);
const year_map = d3.group(data, d => d.year);
const years = Array.from(year_map).reverse().map(d => ({key: d[0], values: d[1]}));

console.log(years)
<script src="https://d3js.org/d3.v7.min.js"></script>

  • Related