How to change d3.nest to group using reverse

Viewed 25

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?

1 Answers

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