D3 JSON Data

D3 JSON Data

In this section, you will understand how using JSON can simplify your D3.js code as well as your JavaScript code.

We will cover previous examples, how to bind JSON objects to the __data__ attribute and how we can use JSON to clean up the code for easier comprehension.

JSON

JSON stands for JavaScript Object Notion.

This is a JavaScript data structure where the indices are named.

The JSON is a collection of name/value pairs.

In JSON, the name must always be in double quotes. As an example:

var secretAgent = {
  "name":"James Bond",
  "drink":"dry martini - shaken, not stirred",
  "number":"007"
};

This allows us to get specific information from our variable using a "dot" by writing secretAgent.number

var secretAgent = {
  "name":"James Bond",
  "drink":"dry martini - shaken, not stirred",
  "number":"007"
};

secretAgent.number;

This gives us the following in the Chrome JavaScript Console

JSON Object Key Value Pair

This makes referencing code and data much easier.

Array of JSON Objects

As we discussed at the top of this section - Arrays can hold any type of information, even JSON.

Going back to our circle examples in a previous section (Using the SVG Coordinate Space With D3.js), we could write all the necessary data to visualize our circles are an array of circle objects:

var jsonCircles = [
  {
   "x_axis": 30,
   "y_axis": 30,
   "radius": 20,
   "color" : "green"
  }, {
   "x_axis": 70,
   "y_axis": 70,
   "radius": 20,
   "color" : "purple"
  }, {
   "x_axis": 110,
   "y_axis": 100,
   "radius": 20,
   "color" : "red"
}];

Let's look at the jsonCircles variable in the Chrome JavaScript Console:

jsonCircles;

We can see that jsonCircles is an array of three objects:

Array of JSON Objects

Let's rewrite our jsonCircles variable with lots of blank spaces and make the definitions more compact so that we can compare across lines:

var jsonCircles = [
  {"x_axis":  30, "y_axis":  30, "radius": 20, "color" :  "green"},
  {"x_axis":  70, "y_axis":  70, "radius": 20, "color" : "purple"},
  {"x_axis": 110, "y_axis": 100, "radius": 20, "color" :    "red"}
];

Now we can get data from any JSON object in the array of JSON objects.

We can also get data from a key value pair out of a specific JSON object.

For example, let's get the "color" of the first circle by typing jsonCircles[0].color into the JavaScript Console (remember JavaScript are 0-based indexed):

jsonCircles[0].color;

The result is:

JSON Object Key Value Pair Result One

We can the "y_axis" value for the second circle by typing jsonCircles[1].y_axis into the JavaScript Console:

jsonCircles[1].y_axis;

The result is:

JSON Object Key Value Pair Result Two

We can the "radius" value for the second circle by typing jsonCircles[2].radius into the JavaScript Console:

jsonCircles[2].radius;

The result is:

JSON Object Key Value Pair Result Three

This will be extremely useful in the next and subsequent sections for use inside of functions when using D3.js operators and methods.

Previous Example of Three Circles

In the Using the SVG Coordinate Space With D3.js section, we created and styled three circles using D3.js using the following D3 code:

var svgContainer = d3.select("body").append("svg")
                                    .attr("width", 200)
                                    .attr("height", 200);

var circles = svgContainer.selectAll("circle")
                          .data(spaceCircles)
                          .enter()
                          .append("circle");

var circleAttributes = circles
                       .attr("cx", function (d) { return d; })
                       .attr("cy", function (d) { return d; })
                       .attr("r", 20 )
                       .style("fill", function(d) {
                         
                         var returnColor;
                         
                         if (d === 30) { returnColor = "green";
                         } else if (d === 70) { returnColor = "purple";
                         } else if (d === 110) { returnColor = "red"; }
                         
                         return returnColor;
                       });

Running that code in the Chrome JavaScript Console, gave us the following on the webpage:

D3 JSON Data Visualization

This example used the data to set the cx, cy and style fill for each circle.

However, as you probably noticed, the cx and cy units were the same.

Also - perhaps more dangerous, was that the if statements had hard coded values ("green", "purple", "red").

Hard coded values are never a good idea, because if our data changes, then we would have to change our code in several places.


Binding JSON Objects to the __data__ Attribute

In the Data Structures D3.js Accepts section, we covered how we could use JavaScript JSON Objects in the Data Array we pass to D3.js.

Using our example above (the three circles) and the JSON notation, we could write our data structure as JSON :

var jsonCircles = [
  {
   "x_axis": 30,
   "y_axis": 30,
   "radius": 20,
   "color" : "green"
  }, {
   "x_axis": 70,
   "y_axis": 70,
   "radius": 20,
   "color" : "purple"
  }, {
   "x_axis": 110,
   "y_axis": 100,
   "radius": 20,
   "color" : "red"
}];

Note that we have moved our color from the if ... then functions in the D3.js code to our data.

This will not always be possible. For now, we will assume it is possible and deal with other cases later.

In doing this, we can now type the following into our JavaScript Console:

var jsonCircles = [
  {
   "x_axis": 30,
   "y_axis": 30,
   "radius": 20,
   "color" : "green"
  }, {
   "x_axis": 70,
   "y_axis": 70,
   "radius": 20,
   "color" : "purple"
  }, {
   "x_axis": 110,
   "y_axis": 100,
   "radius": 20,
   "color" : "red"
}];

var svgContainer = d3.select("body").append("svg")
                                    .attr("width", 200)
                                    .attr("height", 200);

var circles = svgContainer.selectAll("circle")
                          .data(jsonCircles)
                          .enter()
                          .append("circle");

Which gives us this in the webpage:

D3 JSON Data bind

To check to make sure the right D3 JSON data was bound to the right SVG Circle DOM element, let's look at the JavaScript circles variable we created.

This circles variable will contain the D3 selection containing the SVG Circle elements.

To access it, we type the following into the JavaScript console:

circles;

This gives us:

D3 JSON Data Bind in the JavaScript Console

We then click into it and scroll down to look for the __data__ property:

D3 JSON Data Bound to SVG Circle Element

As you can see the first JSON data element from the jsonCircles data structure was bound to the first SVG Circle element.

Which is fantastic!

Before we had been able to bind a single number to the __data__ attribute.

Now we have bound a JSON object to the __data__ attribute.

And because the object is bound to the __data__ attribute, it means that D3.js can use it within its operator and methods!


Use Bound JSON Objects to Alter SVG Elements

We will now use the bound JSON Objects in the __data__ attribute to alter the SVG Circles.

If you recall the Use D3.js To Create SVG Elements Based on Data section, we discussed the key to using the bound data, being the JavaScript function:

function (d) { return d; }

Above, we covered how JSON objects allow us to use their name/value pair to call specific data from them:


JSON Object Key Value Pair

Combining these two pieces of knowledge, allows us to write the following anonymous functions that use JSON Object key value pairs to get data in D3.js:

function (d) { return d.name; }

Where name is the name associated with the specific name/value pair in the JSON Object.

In our case, using our jsonCircles JSON data array that we re-wrote above to make it easier to compare across lines, we have:

var jsonCircles = [
  {"x_axis":  30, "y_axis":  30, "radius": 20, "color" :  "green"},
  {"x_axis":  70, "y_axis":  70, "radius": 20, "color" : "purple"},
  {"x_axis": 110, "y_axis": 100, "radius": 20, "color" :    "red"}
];

Remember that the extra spaces in the JSON definition don't matter as long as they are outside of the double quotes.

With that JSON data structure we can use D3 to access the JSON key value pairs using JavaScript Anonymous Functions

function (d) { return d.x_axis; }

function (d) { return d.y_axis; }

function (d) { return d.radius; }

function (d) { return d.color; }


Next Lesson: