Intro to D3.js -- Caroline Cypranowska

February 28, 2018 at 5-6:30pm in BIDS, 190 Doe Library

d3_simplemap

D3 tutorial for making a map with data on US campgrounds from recreation.gov.

Intro to D3

How to prepare for this tutorial

  1. Download an install Brackets *(This is my preferred tool for building visualizations with D3, but isn’t strictly necessary. It has a nice live preview function that serves the page to your browser. Other options include using node.js)
  2. Fork or download the repository with the data (link coming soon) *It has a template in the main directory that we’ll use to write our code, our raw data in a .csv file in the /data directory

So what is D3?

Data-driven Documents, better known as D3, is a JavaScript library for creating interactive data visualizations for the web. Mike Bostock, the primary developer of D3, first published D3 in 2011, and it’s been a favorite data visualization tool.

However, D3 has a reputation for being a challenging library to master. This is because it requires knowledge of how SVG works, a bit about HTML/CSS, and a large dose of JavaScript. The goal of this workshop is to help you get a good enough sense of how D3 works so that you can try things on your own!

Going in (SVG) circles

D3 visualizations usually begin with creating SVG objects. So let’s create 3 circles using SVG.

<svg width="720" height="120">
    <circle cx ="40" cy="60" r="10"></circle>
    <circle cx ="80" cy="60" r="10"></circle>
    <circle cx ="120" cy="60" r="10"></circle>
</svg>

D3 allows you to select elements and then manipulate them. Let’s change the color of the circles to steelblue and the radius to 30.

var circle = d3.selectAll("circle");
circle.style("fill", "steelblue");
circle.attr("r",30);

Now if you inspect the circles in your browser, the SVG markup should look like this:

<svg width="720" height="120">
    <circle cx ="40" cy="60" r="30" style="fill:steelblue;"></circle>
    <circle cx ="80" cy="60" r="30" style="fill:steelblue;"></circle>
    <circle cx ="120" cy="60" r="30" style="fill:steelblue;"></circle>
</svg>

Instead of passing a string or an integer to a .style or .attr call, you can also pass a function. Try adding this line to your javascript code. What do you think the result would be?

circle.attr("cx",function () { return Math.random()*720 });

Inspect the circles again in your browser. Now the cx parameter should be changing with each page refresh.

Binding data to HTML or SVG elements is the foundation of D3

How do I change the attributes of my SVG elements based on my data? The first step is to bind the data to the SVG elements. In the javascript portion of our document, delete the circle.attr("r",30) line and add the following:

circle.data([32,57,112]);
circle.attr("r", function(d) { return Math.sqrt(d); });

Here d refers to the data we bound to the circles. Open the web inspector and run console.log(d3.selectAll("circle")). Each element should have a __data__ parameter, and that value should correspond to the data value.

We can also pass the index of elements that are selected. After removing the circle.attr("cx", ...) line, add the following:

circle.attr("cx", function(d, i) {  return i * 100 + 30; });

Now the x location of each circle is a function of its index!

But what if I had 1000000000000000 rows of data!!!

With D3 you don’t need to explicitly write out every SVG element you want for your final data visualization. What you can do is make a virtual selection with D3, bind your data to it, and then create the elements that you want on the page. THIS is the magic of D3.

Go ahead, and delete the <circle> elements from the SVG portion of your document. The javascript portion should look like this:

/* create an svg canvas, 300 by 100 px */
var svgCanvas = d3.select("body").append("svg")
                  .attr("width", 300)
                  .attr("height", 100);

/* the data */
var dat = [32,57,112,293];

/* select circles virtually, bind the data, add attributes */
svgCanvas.selectAll("circle")
    .data(dat)
    .enter()
    .append("circle")
    .attr("cy", 60)
    .attr("cx", function (d, i) { return i * 100 + 30;})
    .attr("r", function (d) { return Math.sqrt(d); });

Appending to the virtual selection allows us to create circles for each data point, even if we don’t have those circles already drawn on the canvas.

You don’t need to reinvent the wheel

There are tons of resources for learning D3, and lots of code blocks to peruse through.

Online learning resources

Example galleries

Fancy examples

And if all else fails… there’s always Google. alt text

Now let’s make a map!

alt text

Share