I have some data that I've nested with d3. I now want to flatten it. I'm trying to use the map()
method to do this, but I am getting errors.
This is the error I'm seeing in my console log -- related to line 24 (where I try to get item.values[i].key
):
Uncaught (in promise) TypeError: Cannot read property 'key' of undefined
I don't see where I'm going wrong and I've spent hours googling. This question is similar, but it wasn't answered. It seems like this should be straightforward.
What am I missing? Thank you!
Here is my code:
<!DOCTYPE html>
<meta charset="utf-8">
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
const mhData = axios.get("https://docs.google.com/spreadsheets/d/e/2PACX-1vR-MzpkhMmVMkwmhKFvjPyru5LlYPvWo7_xU8ZARbQmdWP9AIh1VXhZ1aWLWR_PgAySq4gobndfpWP0/pub?gid=0&single=true&output=csv")
.then(content => {
const justData = content.data
const csv = d3.csvParse(justData)
const nestedData = d3.nest()
.key(d => d.date)
.key(d => d.industry)
.rollup(v => d3.sum(v, d => d.value))
.entries(csv)
console.log('nestedData',nestedData)
const flattenData = nestedData.map((item,i) => ({
date: item.key,
industry: item.values[i].key,
value: item.values[i].value
}));
console.log('flattenData',flattenData)
})
</script>
</body>
</html>
In your code: nestedData.map((item,i) => ({...
, i
is an index of nestedData
not values
- which is why you are running into errors.
Your nest
returns a single level of nesting eg
nestedData [
{
"key": "2020-01-07",
"values": [
{
"key": "Tech",
"value": 1352
},
{
"key": "Media",
"value": 2848
},
...
So within your map
you need a single nested map
. You can also change your 'outer' map
to flatMap
which will then return an array of objects.
I took a small sample of your data to accompany the working example below:
const csv = mockData(); //console.log(csv); const nestedData = d3.nest().key(d => d.date).key(d => d.industry).rollup(v => d3.sum(v, d => d.value)).entries(csv) //console.log('nestedData',nestedData); const flattenData = nestedData.flatMap((item, i) => { const date = item.key; return item.values.map(industry => ({ date: date, industry: industry.key, value: industry.value })); }); console.log('flattenData', flattenData); function mockData() { const str = `date,industry,gender,value 2020-01-07,Tech,Men,1004 2020-01-07,Tech,Women,348 2020-01-07,Media,Men,2468 2020-01-07,Media,Women,380 2020-01-07,Real Estate,Men,1214 2020-01-07,Real Estate,Women,391 2020-01-14,Tech,Men,989 2020-01-14,Tech,Women,357 2020-01-14,Media,Men,2430 2020-01-14,Media,Women,393 2020-01-14,Real Estate,Men,1322 2020-01-14,Real Estate,Women,366 2020-01-21,Tech,Men,975 2020-01-21,Tech,Women,339 2020-01-21,Media,Men,2416 2020-01-21,Media,Women,388 2020-01-21,Real Estate,Men,1336 2020-01-21,Real Estate,Women,3581`; return d3.csvParse(str); }
.as-console-wrapper { max-height: 100%;important: top; 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
This isn't a generic way to flatten the output of d3.nest
- you would need to consider n
levels of nesting and probably need a recursive method. But this should work for your example.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.