Session Objectives

  • What is D3?
  • Drawing Shapes
  • Making Shapes Interactive
  • Entering and Exiting Data

Suggested Prerequisites: Working knowledge of HTML, CSS, and the structure of JavaScript.


Drawing and Manipulating SVG

D3 101: A Primer for Newbies (Click to view this example on its own.)

What is D3?

D3 stands for Data Driven Documents. It is a JavaScript library that interacts with elements in an HTML page and can draw and manipulate SVG (Scalable Vector Graphics) by binding data values to them.

For some great examples of the projects in D3, check out the following.

D3 is JavaScript, and if you don't have familiarity of JavaScript, it WILL be challenging. Please run through the DUSPviz Intro to JavaScript tutorial to get a nice primer in JavaScript and how it works.


Start a Development Server

The first step is to start up a development environment in which we can write our code. We'll use the Simple Python Server to do so. On a Mac, create a new folder in your Documents folder, call it d3-viz. In terminal, cd (change your current directory) to this folder. It will be empty.

Once here, start the server using the following command.

python -m SimpleHTTPServer

In your browser, navigate to localhost:8000 to see your current page. Nothing will be there, of course, we'll create the file in our next step.

Create an Page

Create a page for your d3 visualization. Open a text editor, such as Sublime Text or TextWrangler, and enter the following boilerplate code.

<!DOCTYPE html>
<html>
<head>
	<title>D3 VIZ</title>
	<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>

	<script>

	</script>
</body>
</html>

This is a basic page, save it as index.html into the folder in which you are running your Python server.


Drawing with SVG

D3 works with shapes called Scalable Vector Graphics (SVG). These exist as elements in our page, and we can use D3 to manipulate them, add them, remove them, and interact with them.

Create a Stage

First, lets create an SVG element that will act as the stage (also often called a canvas) for our shapes. Enter the following into the body of the code. This creates a stage that is 720px wide by 120px height.

<svg width="720" height="120">
</svg>

Give it a style. We're gonna use some D3 to do this! In the script section of your page, use the d3.selectAll method to select the element in the page called 'svg'. Then style it using the style method.

// Select the Stage
var stage = d3.selectAll("svg");

// Style the Stage background color
stage.style("background-color", "lightgray");

We used a D3 selection method to select the 'svg' element, and then the style method of selection to give it a background color.

Refresh your page in your browser. You'll see a gray box!


Draw a Rectangle

Draw a couple of SVG shapes in our stage. Let's create two rectangles. Put these in between the SVG tags.

<rect x="60" y="45" width="30" height="30"></rect> 
<rect x="120" y="45" width="30" height="30"></rect>

Save and refresh your page.

To illustrate, 0,0 is in the upper left.

Simple Rectangle SVG

Try a couple other types of SVG shapes!


Manipulate the Rectangles with D3

Use a D3 selection to manipulate the SVGs.

// Select all the rectangles (goes one by one)
var rect = d3.selectAll("rect"); // create variable that selects rectangle elements

// Style the rectangles
rect.style("fill", "firebrick")
	.attr("height", 40)
	.attr("width", 50); // this is called chaining

Refresh.

Modify the Rectangles (Selections and Chaining) (Click to view this example on its own.)

Bind Data to the Rectangles using D3

You can take JavaScript arrays and JSONS and bind them to elements in your page. This is actually one of the main concepts of D3 (the data drives the document). Use the data method of selection.

Enter the following in your script, this will take an array of data we define (just two values), then bind it to our rect elements. We then use a function in the selection attr method to set the X coordinate using the data provided.

// Create a dataset and adjust the data
rect.data([160, 220]);

// Apply the data to the X location (goes in sequence)
rect.attr("x", function(d){return d;});

This will change the X value one by one for our SVGs, moving them on the stage.

We adjusted their location through our dataset.


Creating Elements using Enter

OK, now things are going to get a bit weird. Here we go. Reset things a bit. Delete the rect elements in the SVG tag.

<rect x="60" y="45" width="30" height="30"></rect> 
<rect x="120" y="45" width="30" height="30"></rect>

ALSO DELECT THE RECT REFERENCES IN YOUR SCRIPT.

We're gonna use D3 to CREATE the svg shapes!

In your script, create a new array data set. We'll use the same array as above, a simple two value array. Using the selection method, bind data, then use enter to bring it into the stage and append a 'rect' element.

// Create a dataset with some values, bind them them to rect elements
var myRects = stage.selectAll("rect").data([160, 220]);

// Append rectangles, use enter to add to the stage. D3 creates them!
myRects.enter()
	.append("rect")
	.style("fill", "firebrick")
	.attr("y", 45)
	.attr("x", function(d){return d;})
	.attr("width", 30)
	.attr("height", 30);

This enters our data into the stage, then applies it, one by one, to rect elements. We have two. Try it with three, four, or more elements. Note we've reset our rectangles to be 30 x 30.

Entering Data and Creating Elements (Click to view this example on its own.)

Interact with the Rectangles

Let's use a transition to move the rectangles around the page. Transitions animate your D3 visualization. Enter the following script.

// Add a transition when stage element is clicked
stage.on("click", function() {
	d3.selectAll("rect")
		.transition()
		.attr("x", function(d){return d + 200;})
		.ease(d3.easeBack);
});

This uses a listener to wait for a click on the stage, then when it gets it, executes a function. This function selects the rectangles and uses D3 Transition to change properties. It also uses easing to define the way the transition is run.

Make the Rects Zip Around the Screen (Click to view this example on its own.)

Make the Rectangles Bounce Back and Forth

We can use class attributes and a conditional statement to make the boxes bounce back and forth on click. Replace the on Click function with the following statement. Observe what is happening.

// Add a transition when stage element is clicked
stage.on("click", function() {
	var position = d3.select(this).attr("class");
	if (position == null) {
		stage.attr("class", "moved");
		d3.selectAll("rect")
			.transition()
			.attr("x", function(d){return d + 200;})
			.ease(d3.easeBack);
	} else {
		stage.attr("class", null);
		d3.selectAll("rect")
			.transition()
			.attr("x", function(d){return d;})
			.ease(d3.easeBack);
	}
});

Refresh

Back and Forth Rectangles (Click to view this example on its own.)

Add more Rectangles

Update the dataset to include two more rectangles. Edit the myRects variable in your code.

// Create a bigger dataset
var myRects = stage.selectAll("rect").data([160, 220, 280, 340]);

Refresh


Exit and Remove

Use exit and remove to take data values off of your stage.

Add the following to the end of your code. Set up our dataset so that when you click on the rect element, it will remove two of the rectangles.

// Use a dataset with fewer values through Remove
var dataRemove = stage.selectAll("rect").data([160, 220]);

// Remove values on click
d3.selectAll("rect").on("click", function() {
	dataRemove.exit().remove();
});

Refresh


Next Steps and Challenges

Add a circle element, and a few additional SVG shapes.

You might want to add a CSV to get more data on your state.

Or, you might want to make a chart or make a map. Things can get pretty elaborate from here.

Slider Map - Rodent Incidents by Month, 311 Reports (Click to view this example on its own.)
Data Source: City of Boston Open Data

Happy coding.

D3 Reference Documentation

Find the Reference Documentation Here


References and Bibliography

Based on Mike Bostocks Three Little Circles exercise, with some modifications.


Go to main DUSPVIZ tutorials page