What is D3?
D3 is a powerful JavaScript framework predominately used to manipulate data and create beautiful visualizations. The name is an acronym standing for Data Driven Documents.
Here is an example of a visualization Mike Bostock has created with D3.js:
This may seem like more of a game than anything else, but D3 enables developers to easily display data to end users and allow them to interact with the data in a meaningful way. In the above example your mouse acts as a force against the gravity holding the circles together. Other beautiful and intuitive visualizations can be found at d3js.org.
Here is the definition Mike Bostock, the creator of D3 provides for D3:
D3.js is a JavaScript library for manipulating documents based on data. D3 helps you bring data to life using HTML, SVG, and CSS. D3’s emphasis on web standards gives you the full capabilities of modern browsers without tying yourself to a proprietary framework, combining powerful visualization components and a data-driven approach to DOM manipulation. Source: D3js.org
Using D3
D3 uses standard javascript objects and nodes that your browser understands. This means it can interact with the browser, creating elements like that in this first “visualization” below.
Adding Elements
Here all we are doing is using the following code:
d3.select("body").append("p").text("New paragraph!");
to add an element to our page. If you look below you can see the element that was created.
Binding Data
The power of D3 comes not from its ability to manipulate elements in the DOM, but rather its ability to bind data elements to actual elements in the DOM. This allows developers to easily represent their data in the manner in which they see fit. Here we are going to use our data to determine the number of times we display the sentence “New Paragraph!”.
var dataset = [ 5, 10, 15, 20, 25 ];
d3.select("body").selectAll("p").data(dataset)
.enter()
.append("p")
.text("New Paragraph!");
d3.select("body")
.append("p")
.text("New paragraph by chaining elements!");
Notice there were five elements in our dataset, and for each element, we printed out a new sentence. This wasn’t really a good representation of our data though because we’re not exposed in any way to the value of data element in this visualization.
Using Your Data
Take the below script:
d3.select("body").selectAll("p").data(dataset)
.enter()
.append("p")
.text(function(d) { return d;} )
.style("color", function(d) {
if (d > 15) { //Threshold of 15
return "red";
} else {
return "black";
}
});
d3.select("body")
.append("p")
.text("New paragraph by chaining elements!");
The above code gives us:
Note that we were able to add a conditional statement to manipulate how we display our data. If the value of the data point is greater than 15, the text is red, if not, it is black.
Drawing Divs
It would be nice to actually visualize the data, and we can do that easily with D3 as well.
The Power of Data
We can take the value of a datapoint and use it to represent the height of the bar. We are using divs to represent our bars here:
var dataset = [];
for (var i = 0; i < 25; i++) { //Loop 25 times
var newNumber = Math.round(Math.random() * 30); //New random number (0-30)
dataset.push(newNumber); //Add new number to array
}
d3.select("body").selectAll("div").data(dataset)
.enter()
.append("div")
.attr("class","bar")
.style("height", function(d) { return d*5+"px";});
d3.select("body")
.append("p")
.text("New paragraph by chaining elements!");
An SVG Primer
The code below isn’t even D3 code, but rather simply an experimentation with drawing SVG. Thought I would include it anyways since it was a useful exercise.
Drawing SVGs
This code uses a randomized dataset to generate a series of circles. The radius of each circle corresponds to that of the data element it is representing.
Making a Bar Chart
Making a Scatter Plot
Here is the script used to generate the below scatterplot. As you can see, it is very straightforward for how nice the visualization is.
/* CONSTANTS */
var h = 150;
var w = 500;
var barPadding = 2;
/* GLOBALS */
var dataset = [];
var svg = d3.select("body").append("svg");
svg.attr("width",w).attr("height",h);
/* CODE */
for (var i = 0; i < 15; i++) { //Loop 25 times
var newArray = [];
var newNumber = Math.round(Math.random() * 25); //New random number (0-30)
var newNumber2 = Math.round(Math.random() *25);
newArray.push(newNumber); //Add new number to array
newArray.push(newNumber2); //Add new number to array
dataset.push(newArray);
}
svg.selectAll("circle")
.data(dataset)
.enter()
.append("circle")
.attr("cx", function(d, i) {
return d[0]*20;
})
.attr("cy",function(d) { return d[1]*4+5;})
.attr("r", function(d) {
return Math.sqrt(h - d[1]*4);
})
.attr("fill", function(d) {return "rgb("+ "0" + "," + "150" + "," +(d[0]*10) + ")"; });
svg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.text(function(d) { return d[0] + "," + d[1];})
.attr("x", function(d, i) {
return d[0]*20;
})
.attr("y",function(d) { return d[1]*4+5;})
.attr("font-family", "sans-serif")
.attr("font-size", "11px")
.attr("fill", "red");
Scales
Axes
Axes will automatically arrange themselves based on the data put in and the number of tick marks you’d like to present on each axis.
Transitions
For example, to fade the background of the page to sky blue:
d3.select("body").transition()
.style("background-color", "lightcyan");
Click this text to try it!
So that’s the introduction to D3! I am very interested in developing complex visualizations to better illustrate arguments in writing so keep an eye out for any original visualizations you may see in the near future.
Check out Mike Bostocks personal webpage, his GitHub account, and D3js.org for more information. Mike also has a gallery of visualizations here.
by Taylor