D3 was designed for more than just graphs and charts. It's also capable of presenting maps, networks, and ordered lists. It was created for the efficient manipulation of documents based on data.
This demonstration will focus on creating a simple scatter plot.
D3 provides the ability to select DOM elements and bind data to them (any kind of element, including images and text).
The magic of D3 comes from the ability to use data and web page elements together. Elements can be selected and their appearance modified to reflect differences in the data.
Note: D3 makes use of web standards such as HTML5, CSS3, and SVG, so it is therefore designed for modern browsers. It also requires utf-8 encoding.
First include the d3.js file which can be downloaded from D3js.org, or linked through a CDN. I'll be using the downloaded file.
My graph will be created with a script embedded in this html page. The d3.js file will be included before the graph script.
We will be using SVG elements to create our graph, so we need to create an SVG canvas to contain it.
D3 has a
select() method for grabbing DOM elements. Once selected, you can apply operators to these elements. This method selects the first element of that type.
Operators can then be used to get or set items such as attributes, properties, styles, text, and html.
D3 methods can be chained with a syntax much like jQuery.
Each operator in the chain returns a selection and the next operator in the chain operates on that selection.
Notice that order matters, the last item is on top.
D3 can load data from a number of types of external resources. These include CSV, TSV, JSON, and XML. We just need to ultimately construct an array from the data. For now we'll use an array of JSON objects.
There are several methods required for for binding data points to our graph (I've chosen to represent the data with circles):
selectAll('circle') - selects all circles in our SVG and returns an empty array if there aren't any yet.
data(dataArray) - this joins an array of data to the current selection.
enter() - joins the data to placeholders for the circles.
append('circle') - appends the circles to the SVG.
Mike Bostock has a pretty good explanation of this in his article: Thinking with Joins.
Note that when we use a data array, we need to reference the data from an anonymous function.
We need to scale our data to fit the space available. D3 provides functions to help us do this. There are different scale types available, but for this example we'll use a linear scale,
d3.scale.linear(). We need to specify a domain and range. The domain refers to the data and the range refers to the SVG space.
The origin of the SVG is in the upper left corner, but our graph origin will be in the lower left corner.
So far we've hard-coded our domain, but it would be better to have D3 help us determine our domain by calculating the max and min for our data using the
We can use the SVG text element to add labels to our data points. The text is appended just like the other elements. We add it last so it's on top. The position is offset slightly, otherwise it would be on top of our circles.
Our elements are hanging over the edge of our SVG, so we need some margin. This will also provide room for axes. We do this in a way that keeps our data normalized.
Next we'll add the x and y axes. We'll use the
call() methods to create our axes.
The last elements that we'll add are the title and axis labels. These are simple text elements that are appended to the SVG and positioned using the height and margin variables. Some of the margins were increased to better accomodate the added text.
d3js.org has an introduction, lots of examples, and documentation.
For an extensive list of tutorials, see https://github.com/mbostock/d3/wiki/Tutorials.
www.dashingd3js.com has a detailed tutorial (up to the point of adding axes).
egghead.io (pro) - good method for margins.
www.d3noob.org - good example for adding axis labels.
Interactive Data Visualization for the Web - O'Reilly book, free to read online.
http://www.jeromecukier.net/blog/2011/08/11/d3-scales-and-color - a very detailed explanation of scales.