0

Total noob to D3.js and working on creating my first grouped bar chart. However I'm having trouble making my data fit with the examples online. I am trying to use this example here, with my data that has been nested JSON with D3.

My problem is i cant use the d3.keys method to retrieve keys because my keys are not the state names. They are just Key.

Not to mention the second half forEach wont work because again the keys are not the State names, they are just the term key. So +d[name] will try d[MAPLE] when really my value is inside a key of d.values[(Get the Value where the key = name)]. Just really confused how to do this once the data has been nested in JSON

How would I go about getting all possible Key Values, and then mapping the keys with the next level of keys and values? Using a similar example as below but with my JSON nested data.

var ageNames = d3.keys(data[0]).filter(function(key) { return key !== "State"; });

  data.forEach(function(d) {
    d.ages = ageNames.map(function(name) { return {name: name, value: +d[name]}; });
  });

My data is as so

{
    "key": "1/10/2014",
    "values": [
      {
        "key": "Texas",
        "values": 200
      },
      {
        "key": "Colorado",
        "values": 300
      },
      {
        "key": "Utah",
        "values": 227
      }
    ]
  },{
    "key": "2/10/2014",
    "values": [
      {
        "key": "Texas",
        "values": 225
      },
      {
        "key": "Colorado",
        "values": 241
      },
      {
        "key": "Utah",
        "values": 500
      }

    ]
  }
Stedy
  • 7,359
  • 14
  • 57
  • 77
KingxMe
  • 43
  • 1
  • 7
  • To clarify, do you want to group by state or date (ie, along the x-axis will it be "Texas", "Colorado"... or "1/10/2014", "2/10/2014")? – Henry S Apr 25 '15 at 11:08

1 Answers1

1

It's not clear from the question if the aim is to group by state ("Texas", "Colorado"...) or date ("1/10/2014", "2/10/2014"...) along the x-axis.

Assuming date (because that's how the data is currently structured), here's a working plunk: http://plnkr.co/edit/C8lkPMGanFY9BkTc6f1i?p=preview

The code that processes the data into a format that your existing D3 code for grouped bar chart can handle looks like this:

// Call the first mapping function on every 'date' in the data array
processed_data = data.map( function (d) {
    var y0 = 0;
    var total = 0;
    return {
        date: d.key,
        // Call the second mapping function on every 'state' in the given date array
        values: (d.values).map( function (d) {
            return_object = {
                state: d.key,
                count: d.values,
                y0: y0,
                y1: y0 + d.values
            };
        // Calculate the updated y0 for each new state in a given date
        y0 = y0 + d.values;
        // Add the total for a given state to the sum total for that date
        total = total + d.values;
        return return_object;
        }),
        total: total
    };
});

We use nested array.map transforms to manipulate your two-level nested data into the expected format and calculate y0, y1 and total values. Your processed_data object will then look like this:

processed_data view in console

The only other tricky bit will be to calculate your list of unique states, in order to define the color.domain. If you don't want to hard-code this (e.g. because the list may vary from dataset to dataset, you could use this approach:

// Define the color domain, by first building a list of states:
var states = [];
// Loop through each date
processed_data.forEach(
    function (d) {
        // Loop through each state in that date
        d.values.forEach(
            function(d) {
                // add to the array if not already present
                if (!(states.indexOf(d.state) > -1)) {
                    states.push(d.state)
                }
            }
        ) 
    }
);
color.domain(states);
Henry S
  • 3,072
  • 1
  • 13
  • 25
  • Took a while but i was able to hack it together and make it work, just came across your answer and its alot cleaner than what i did. Will implement this now! Thanks! – KingxMe Apr 30 '15 at 20:30