3

I'm trying to use a nested json array to graph a multi-series chart with d3.js. I've looked a lot of places on this site and others, and while there are similar topics, I can't seem to make the syntax work with my specific problem (which is a simple one).

To make a line chart (like the one here: http://bl.ocks.org/mbostock/3883245), I can parse this JSON file:

[{"date":"1-May-12","close":58.13},{"date":"30-Apr-12","close":53.98},{"date":"27-Apr-12","close":67}]

By using this javascript syntax:

d3.json("data/data2.json", function(error, data) {              
data.forEach(function(d) {                              
    d.date = parseDate(d.date);                         
    d.close = +d.close;                                 
});

But what if the JSON is a nested array? For example:

{
"Stock01":[{"date":"1-May-12","close":58.13},{"date":"30-Apr-12","close":53.98},{"date":"27-Apr-12","close":67}]
"Stock02":[{"date":"1-May-12","close":28.13},{"date":"30-Apr-12","close":33.98},{"date":"27-Apr-12","close":47}]
}

I've tried options like the script below, but I'm not having any luck:

d3.json("data/data2.json", function(error, data) {              
data.forEach(function(d) {                              
    d.date = parseDate(d[0].date);                          
    d.close = +d[0].close;                                  
});

If anyone has advice for how to navigate a nested JSON array with the data.forEach function, I'd be grateful. Thanks in advance for any help.

ekatz
  • 1,050
  • 1
  • 11
  • 29
  • 1
    To further clarify: the [`.forEach()` function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) only works on arrays, calling the internal function once for each element in the array. You need to access the individual arrays in your data object and then use `.forEach()` to scan through them. – AmeliaBR Jan 10 '14 at 04:27

1 Answers1

1

You want to iterate over the keys in data, use the key to look up the corresponding value in data, and operate on the values.

You want something like this:

d3.json("data/data2.json", function(error, data) {
    for (k in data) {
        var k_data = data[k];
        k_data.forEach(function(d) {                              
            d.date = parseDate(d[0].date);                          
            d.close = +d[0].close;                               
        });
    }
});

Also, it looks like forEach takes a function that has two arguments, key and value:

forEach: function(f) {
  for (var key in this) {
    if (key.charCodeAt(0) === d3_map_prefixCode) {
      f.call(this, key.substring(1), this[key]);
    }
  }
}

For example:

values: function() {
  var values = [];
  this.forEach(function(key, value) {
    values.push(value);
  });
  return values;
}

Later: AmeliaBR is correct about forEach: it is not available for use on objects/dictionaries.

var a = {"stock1": [1, 2, 3, 4], "stock2": [2, 3, 5, 7], "stock3": [1,2, 4,8]};
a.forEach(function(value, key){ console.log(value, key);});
/* TypeError: Object #<Object> has no method 'forEach' */

But this works:

a["stock1"].forEach(function(value, key){ console.log(value, key);});
1 0
2 1
3 2
4 3
Mario Lenci
  • 10,422
  • 5
  • 39
  • 50
hughdbrown
  • 47,733
  • 20
  • 85
  • 108
  • 1
    The first version is the right idea, but you copied over the errors from @ekatz's confused attempt. Here's the corrected function: http://fiddle.jshell.net/4QCsX/ . Another option would be to use [d3's `entries(object)`](https://github.com/mbostock/d3/wiki/Arrays#wiki-d3_entries) method to convert the data object into an array, which will have to be done anyway in order to assign the different stocks to different lines in the graph, like this: http://fiddle.jshell.net/4QCsX/1/ – AmeliaBR Jan 10 '14 at 04:23
  • This is really helpful, and I'm getting the data to properly parse within each array. However when I try to run the chart, I'm now getting an error which reads: Error: Problem parsing d="MNaN,NaNLNaN,NaN". Any idea why this may be? – ekatz Jan 10 '14 at 18:50
  • Thanks for your help. The jsfiddle from this disccusion helps as well: http://stackoverflow.com/questions/20016549/d3-multi-series-line-chart-from-pivoted-json – ekatz Jan 10 '14 at 19:59