alexc101 alexc101 - 6 months ago 44
JSON Question

Iterating through multi-dimensional arrays with d3.js

mbostock recently answered my question around the best practices of using data with d3, here is a link to the post;

https://github.com/d3/d3/issues/2828

However, trying to follow his advice I'm still confused how to iterate over the multi-dimensional data which he suggested. I am just trying to console log the data for now, and was hoping someone could help me produce practical examples following the post, the relevant snippet can be seen below;


you could have a separate array of countries, and then require a two-dimensional array of values, similar to the trick used to avoid redundantly specifying the dates. In fact, you could just generalize it to an n-dimensional matrix of organizations, countries and dates:


{
"organizations": ["EA", "EB", "EC"],
"countries": ["Netherlands", "Belgium", "France"],
"dates": ["Jan_2016", "Feb_2016", "Mar_2016"],
"values": [
[
[11.7999, 15.0526, 13.2411],
[25.7713, 24.1374, null],
[27.6033, 23.6186, 20.2142]
],
[
[11.7999, 15.0526, 13.2411],
[25.7713, 24.1374, null],
[27.6033, 23.6186, 20.2142]
]
]
}



That would be the most concise, I expect, but you’d have to remember the dimension order when accessing the data:


var organization = "EA",
country = "Netherlands",
date = "Jan_2016",
value = data.values[organization][country][date]; // 11.7999


I've been trying to understand how to achieve this result, however as I'm relatively new to all this, it has been difficult. The most useful resources I have found have been > video1 + video2 and trying to use this guide as reference.

I'm still non the wiser on how to actually do this, and I'm not sure if it's just not possible with the data structure mbostock suggested or if I'm just missing something(read:alot)? (I am 99.99% sure it's the latter).

So here is what I'm trying to do;

http://plnkr.co/edit/2O9Gn28WuMCE1ajOonzY?p=preview

d3.json("data.json", function(error, data) {
if (error) {
console.log(error)
} else {
console.log(data)
data = d3.entries(data);
console.log(data)
}

data.forEach(function(d) {
var org = Object.keys(data[0]);
console.log(org)
})

});


So, from what I can gather I need to turn the json into an array, then produce a series of forEach loops to tie everything together. That is the thing I'm really struggling with, and any help would be much appreciated.

I hope everything is explained / question relevant,

Thanks

Answer

A good old for loop is the probably the clearest way to go in this case:

for (var organization=0; organization<data.organizations.length; organization++) {
  for (var country=0; country<data.countries.length; country++) {
    for (var date=0; date<data.dates.length; date++) {
       console.log(data.values[organization][country][date]);
    }
  }
}

Keep in mind that organization, country, and date are integers here: you can use data.organizations[organization] to access the actual label.

There is a lot of flexibility, you can reorder the loops and add intermediary code. For instance if you want to extract an array for each organization and date:

for (var organization=0; organization<data.organizations.length; organization++) {
  for (var date=0; date<data.dates.length; date++) {
     var group = [];
     for (var country=0; country<data.countries.length; country++) {
       group.push(data.values[organization][country][date]);
     }
     console.log("values for "+data.organizations[organization]+" at time "+data.dates[date]+":")
     console.log(group);
  }
}

PS: To get a single country (or organization or date) instead of enumerating through all, you can replace the corresponding for loop by:

var country= data.countries.indexOf("france")