Session Objectives

Part 1: Animation the D3 Way

  • Transition fundamentals
  • Understand how D3 Transitions Work
  • Explore the Transitions methods

Part 2: Scatterplot - Adding Transitions between Data Fields

  • Transition between data held in two fields

Part 3: Bar Chart - Adding Transitions between Two Separate Datasets

  • Transition data between files

Part 4: Animate a Line Chart

  • Introduce Animating a Line

Suggested Prerequisites: Introduction to D3 - Make a Chart and D3 Part 2: Scatterplots and More.

To download the materials for exercises, click here. This is d3_part3_transitionsAnimations.


In the previous session, we looked at how you can load datasets, such as a CSV, into D3 and bind the values from the dataset to page elements. We also looked at how you can use examples and customize them to fit your datasets, and vice versa. Today, we are going to continue learning D3 by exploring animations, user interactions, and transitions. Now, we are going to learn the stuff you can't do in Excel!

Engage the User! Interactions, Animations, and Transitions

One of the powerful capabilities provided in the D3 library is the ability to animate and modify page elements. Animations in D3 are called Transitions. D3 transitions allow the ability to create an animation using HTML and SVG elements on your page. D3 uses Interpolation based animation, which means it will take key points (or key frames) and interpolate values between them to animate your SVG.

You can think of a transition in D3 as changing properties over a period of time and in a specific manner from one value to another. The transition can be slow, or instantaneous, and you can change position, modify color, trace lines, and listen for page events, among many other things. D3 contains numerous difference ways you can incorporate transition into your visualization, some of which very exciting. Let's discuss them.

Modification through Simple CSS

You can add some interaction without even using D3, these are page elements after all. And you might have initially thought, hey I can use CSS! You are right! The most elementary way to add interaction can be achieved by simply modifying CSS to do something on hover. After all we are working with page elements. For a quick and dirty demonstration, let's take a look at the one bar chart of Boston rats we've used in the last two sessions.

Bar Chart with Interactive Hover (Click to view this example on its own.)

Achieve this through a simple CSS style placed in the stylesheet.

rect:hover{
	fill: red;
}

Cool, but there is a better way to do this using D3.


Part 1: Animation the D3 Way - The Transition Method

To start, navigate to the weeks materials in terminal. Start your Python simple server

Open transitions.html in the class documents.

This is a simple template we can work with that draws a rectangle on the screen at (50,50).

Changing CSS is limiting though, and D3 can do so much more! The robust and real way to animate and modify elements using D3 is using the D3 Transition methods. You will be excited to learn that D3 has methods for transitions that you can activate through user input, such as clicks. These transitions can change size, color, position, and really anything that can be set in the attributes of a page element. Let's explore this a little further. Take a look at this example to one of the many things possible.1

To start, lets create a simple D3 visualization with a rectangle. To quote Jerome Cukier from his fantastic tutorial on Animations and Transitions, If you know how to draw in D3, you almost know how to animate! We use transitions to change the properties of the rectangle.

Our page layout, to give us a better idea, will look like the following.

Simple Rectangle SVG

Using Transitions

To implement a transition, you set up a trigger, be it a button or a click or some type of user event, and then within the trigger, change the respective attributes of the SVG you are seeking to modify. For example, set up a rectangle element and a button. When that button gets a click, have it change some of the attributes of the element.

Copy and paste the following code below the rectangle code in the script part of the document.

All of our transitions will go in the "start on click" function!

// Set up the reset button to move it back to 50,50
d3.select("#reset").on("click", function() {
	rectangle
		.transition()
		.attr("x", 50)
		.attr("y", 50);
});

d3.select("#start").on("click", function() {
	rectangle
		.transition(); // ALL OF OUR TRANSITIONS WILL GO HERE!
});

The following examples show some basic transitions. Two buttons have been added to help showcase the example, and demonstrate how to start the transition and then reset the transition. If you ever want to view the example on it's own and View Page Source to see the code behind the transition. The lines you need to add to your code are highlighted in each example


Position

Click the buttons to try it!

The code is pretty simple.

rectangle
	.transition()
	.attr("x", 250); // Set New Position

Size

And the code.

rectangle
	.transition()
	.attr("x", 250)
	.attr("width", 100) // New Width
	.attr("height", 100); // New Height

Opacity

And the code.

rectangle
	.transition()
	.attr("x", 250)
	.attr("width", 100)
	.attr("height", 100)
	.attr("opacity", 0.5); // New Opacity

Color

And the code.

rectangle
	.transition()
	.attr("x", 250)
	.attr("width", 100)
	.attr("height", 100)
	.attr("opacity", 0.5)
	.attr("fill", "red"); // New Color (Hex, RGB, or Web Safe)

Starting Transitions: Duration, Delay, and Easing

To finish off the fundamentals (a.k.a. before we move on to the crazy stuff...), some additional transition properties you can easily set are duration (or the amount of time taken to complete the transition), delay (the delay observed before the transition starts after initializing the transition), and easing type (the method in which the transition is completed). Read more in the D3 Documentation on Starting Transitions.

Delay

A delay to the start of your transition can be implemented by including the following in your script.

rectangle
	.transition()
	.attr("x", 250)
	.attr("width", 100)
	.attr("height", 100)
	.attr("opacity", 0.5)
	.attr("fill", "red")
	.delay(500); // Delay 500ms (0.5 seconds)

Delay is in milliseconds (ms), and the default is no delay.

Duration

Duration is the time it takes to complete the transition.

rectangle
	.transition()
	.attr("x", 250)
	.attr("width", 100)
	.attr("height", 100)
	.attr("opacity", 0.5)
	.attr("fill", "red")
	.delay(500)
	.duration(2500); // Set Duration of 5000ms (5 seconds)

Duration is in milliseconds (ms), and the default is 250ms.

Easing

Easing is the method in which the transition is completed.

rectangle
	.transition()
	.attr("x", 250)
	.attr("width", 100)
	.attr("height", 100)
	.attr("opacity", 0.5)
	.attr("fill", "red")
	.delay(500)
	.duration(2500)
	.ease(d3.easeBounce); // Use the Bounce Transition Ease

The default is 'cubic-in-out', which resembles a slow start, fast middle, and slow finish. There are many other types. To see an illustration of the easing types, view the D3js v4 Easing Example on bl.ocks. Add some of these to the above examples to see what they do! Start with 'bounce'.


Double Transitions

You might also find that one transition is not enough. There are a couple different methods avaiable to address this. Say you want the transition to first go to one spot, then to a second spot. You can run a function at the end of a transition using .each("end", function(){...}). Your function will run when the transition ends, meaning in here, you can actually put another transition. Let's take a look.

rectangle
	.transition() // first transition
		.attr("x", 250) 
		.attr("width", 100)
		.attr("height", 100)
		.attr("opacity", 0.5)
		.attr("fill", "red")
		.delay(500)
		.duration(2500)
		.ease(d3.easeBounce)
		.on("end",function() { // on end of transition...
		    d3.select(this)
		    	.transition() // second transition
					.attr("x", 150) // second x
					.attr("width", 75) // second width
					.attr("height", 75) // second height
					.attr("opacity", 0.75) // second opacity
					.attr("fill", "blue") // second color
					.delay(500) // second delay
					.duration(2500) // second time
					.ease(d3.easeBounce); // second ease
		});

This will run two transitions! View source on the example above to see how we implemented this.


These are the basics, and from this you can build a lot. Let's dive a little deeper, and animate something real. In the following sections, we will first make that scatterplot we made in the last session interactive, then take data from the Bureau of Labor Statistics and create a animated line chart. We'll conclude by looking at a few other interaction examples.


Part 2: Scatterplot - Adding Transitions between Data Fields

Open scatterplot.html in weeks materials.

In the scatterplots session, we made a scatterplot based on set of X and Y data. A common operation will be to change the dataset, then apply a transition to move the points in the dataset to the new locations. Say we now have data that looks like this, with two values we want to transition between.

City # of Rats (2015) # of Coffee Shops (2015) # of Rats (2016) # of Coffee Shops (2016)
Brookline 40 50 60 30
Boston 90 120 10 30
Cambridge 30 90 80 100
Chelsea 10 10 100 120
Somerville 60 40 40 60

And we want the scatterplot to transition the data between the two years.

Scatterplot with Transition between Datasets (Click to view this example on its own.)

You can apply the transitions learned above to complete this task.

Start with our basic CSV loaded scatterplot. Copy and paste this code into a blank document.

Scatterplot with CSV Data Loading (Click to view this example on its own.)

1. Add some buttons

From here, we can make some adjustments to read in our new dataset. First, let's add two buttons that can be used to trigger the transition. We will set them up to listen for click events. Put these in the body of the page.

<button id="start">Transition</button>
<button id="reset">Reset</button>

2. Load the new dataset and update the fields

Next, in our code, we need to adjust the dataset to read in the new dataset. The circles we create should be at the locations found in the new dataset. In the CSV, the fields we are interested in are rats_2015, coffee_2015, rats_2016, and coffee_2016.

var ratData = [];
			
d3.csv("data/coffee_rodents_transform.csv", function(d) { // updated dataset
	return {
		city : d.city,
		rats2015 : +d.rats_2015, // new field
		coffee2015 : +d.coffee_2015, // new field
		rats2016 : +d.rats_2016, // new field
		coffee2016 : + d.coffee_2016 // new field
	};
}, function(error, rows) {
	ratData = rows;
	console.log(ratData);
	createVisualization();
});

function createVisualization(){

	//Width and height
	var w = 180;
	var h = 180;

	//Create SVG element
	var svg = d3.select("#main")
				.append("svg")
				.attr("width", w)
				.attr("height", h)
				.attr("style", "outline: thin solid black;");

	var circle = svg.selectAll("circle")
	   .data(ratData)
	   .enter()
	   .append("circle")
	   .attr("cx", function(d) {
	   		return d.rats2015; // new data field
	   })
	   .attr("cy", function(d) {
	   		return d.coffee2015; // new data field
	   })
	   .attr("r", 5);

3. Write the transition functions

Our last step is to write two functions that will transition the data between our two datasets when they hear a click on one of the buttons. We can use the d3 on click functionality to listen for this. The functions will look like as follows. Check them out.

d3.select("#start").on("click", function() {
	circle
		.transition()
		.attr("cx", function(d) {
			return d.rats2016;
		})
		.attr("cy", function(d) {
			return d.coffee2016;
		})
});

d3.select("#reset").on("click", function() {
	circle
		.transition()
		.attr("cx", function(d) {
			return d.rats2015;
		})
		.attr("cy", function(d) {
			return d.coffee2015;
		})
});

These functions transition the circle objects on the page to new locations based different fields in the dataset when a click is heard on either #start or #reset. They functions take each circle and apply a new X and Y.

Save and refresh your map.

Scatterplot with Transition between Datasets (Click to view this example on its own.)

In this example, we only transitioned location, but we could also transition color, size, and other attributes as described above.


Part 3: Bar Chart - Adding Transitions between Two Separate Datasets

Open barchart.html in weeks materials.

Bar Chart (Non-working Data Toggle) (Click to view this example on its own.)

View the code, it's just our bar chart of the rodent example from the first session. The only thing added are two buttons, one that says 'Dataset 1' and another that says 'Dataset 2'.

1. Write up a function to load the new dataset

The first thing you want to do is write up a function to load the new dataset. In the data folder, it is called rat-data-larger-v2.csv. In order to replace the dataset, we have to use the D3 CSV load function again. Input the following above where you create the axis elements.

d3.select("#start").on("click", function() {
	d3.csv("rat-data-larger-v2.csv", function(d) {
		return {
			city : d.city,
			rats : +d.rats
		};
	}, function(error, rows) {
		ratData = rows;
		console.log(ratData);
		updateData();
	});
});

2. Write up our reset function

The next thing you want to do is write up a function to reload the old dataset. This will allow for toggling. In the data folder, it is called rat-data-larger.csv. Use the D3 CSV load function again. Input the following right after the 'start' function you just added.

d3.select("#reset").on("click", function() {
	d3.csv("rat-data-larger.csv", function(d) {
		return {
			city : d.city,
			rats : +d.rats
		};
	}, function(error, rows) {
		ratData = rows;
		console.log(ratData);
		updateData();
	});
});

3. Create the UpdateData function

Lastly, we want to create a function called updateData that will include our transitions. This is where the y and the height values can changed using a D3 transition, and we can reestablish our mouseover. Note, mouseovers are not part of the transition module, so you have to recreate them separately. The updateData function looks like this. It simply updates the various components of our visualization that need the transition applied.

function updateData() {
	var maxValue = d3.max(ratData, function(d) { return +d.rats;} ); 
	
	// update the scale to get the new max value
	yScale = d3.scaleLinear()
	    .domain([0, maxValue])
	    .range([0, y_axisLength]);

	// select all the rectangles and transition to new 'y' and 'height' properties
	svg.selectAll("rect")
		.data(ratData)
		.transition()
		.attr("y", function(d){
			return h - yScale(d.rats) - 5; // Set y coordinate of rect using the y scale
		})
		.attr("height", function(d) {
			console.log(d.rats);
			return yScale(d.rats);
		})			

	// recreate the mouseovers with the new data
	svg.selectAll("rect")
		.on("mouseover", function(d){
			return tooltip.style("visibility", "visible").text(d.city + ": " + d.rats);
		})
		.on("mousemove", function(d){
			return tooltip.style("top", (event.pageY-10)+"px").style("left",(event.pageX+10)+"px").text(d.city + ": " + d.rats);
		})
		.on("mouseout", function(d){
			return tooltip.style("visibility", "hidden");
		});
}

Save and refresh your file. When you open it in your browser, you'll see the following!

Bar Chart with Data Toggle (Click to view this example on its own.)

You might also want to sort a bar chart. Check out this great example here.

Sortable Bar Chart

Part 4: Animate a Line Chart: An Unemployment Graph

Open linechart.html in weeks materials.

Lets continue exploring animation by look In this next component, lets look at a chart of national unemployment. This chart is based off of the Line Chart example from Mike Bostocks bl.ocks, and I went and downloaded unemployment data from the Bureau of Labor Statistics. The chart, using the Bureau of Labor Statistics data, looks like the following. Open the linechart.html file in the materials package for this exercise to view the code.

U.S. Unemployment Rate, January 2005-July 2015 - Data source: Bureau of Labor Statistics
(Click here to view this example on its own.)

This chart is fairly simple. To add some bells and whistles, we can use the fundamentals of transitions we learned above and build on them. Because we grabbed some code and customized, the base line chart and associated code is complete. Our task is to identify the lines of code we need to change in order to create our animation.

Time Animation with an "Unrolling" Line Chart

A common and nice looking transition for a line chart like the one above is the "unrolling" line chart. An "unrolling" line chart is one in which the lines gradually enter from origin point by point. This style of animation works particularly well for time series animation, showing the change on the X-Axis over time. The unemployment rate is a nice example of this, let's animate the line chart to achieve the following.

U.S. Unemployment Rate, January 2005-July 2015 (with Animation) - Data source: Bureau of Labor Statistics
(Click here to view this example on its own.)

i. Identify the Code that Draws the Line

In the code, locate the lines in which the SVG path is appended to our document. It will look like the following, near the bottom, within the method that loads the CSV.

svg.append("path")
	.datum(data)
	.attr("class", "line")
	.attr("d", line);

We need to modify these lines of code to set up the transition but only slightly. This is where our data is being bound to our line. The method we are going to use to animate is the Stroke Dash Array property of the SVG Path element that describe how an element is stroked. Mike Bostock has a nice example of Stroke Dash Interpolation on his bl.ocks pages.

Replace the above with the following. All we are doing is setting our append method to a variable.

// Set svg.append("path") equal to a variable
var path = svg.append("path")
	.datum(data)
	.attr("class", "line")
	.attr("d", line);

ii. Manipulate the Stroke Dash Array

To "unroll" the line chart, we are going to manipulate the array that describes the dash we want for the line. This might be a bit confusing at first, but hang in there. The Stroke Dash Array property of the SVG path element lets us create an array that has the stroke and dash of the path. To illustrate, this looks like the following. Because we are creating an array of the dash and gap, we can set these to be dynamic and changing.

Dash Array and Dash Offset

The Stroke Dash Offset value specifies the distance into the dash pattern to start the dash. Therefore, we can start the Dash Offset at the length of the path, then transition the offset to zero using the built in D3 transition methods. To get the length of the path, create a variable called total length. Total length will hold the total length of the path using the getTotalLength method of the SVG Path Element. The code will look like this. Enter this at the bottom of the script, but still within the main load CSV method that our path is being in drawn in!.

// Variable to Hold Total Length
var totalLength = path.node().getTotalLength();

// Set Properties of Dash Array and Dash Offset and initiate Transition
path
	.attr("stroke-dasharray", totalLength + " " + totalLength)
	.attr("stroke-dashoffset", totalLength)
  .transition() // Call Transition Method
	.duration(4000) // Set Duration timing (ms)
	.ease(d3.easeLinear) // Set Easing option
	.attr("stroke-dashoffset", 0); // Set final value of dash-offset for transition

This block of code get the total length of the line, sets the dasharray and dashoffset properties to the total length, then sets up the transition to adjust the dash offset to zero. The result is an animation that makes it appear that the graph is unraveling over time! Save and refresh your page.

U.S. Unemployment Rate, January 2005-July 2015 (with Animation) - Data source: Bureau of Labor Statistics
(Click here to view this example on its own.)

iii. Control it with some Buttons

By default, the transition will run on page load. You might want to give your user a bit more control over this so they view the animation, or even start it over. If you looked at the examples above, you noticed a 'Start Time Animation' button and a 'Reset' button that controled the visualization. Insert buttons into the body element of your HTML, right above the script, by entering the following.

<body>
	<button id="start">Start Time Animation</button>
	<button id="reset">Reset</button>
<script>
...

Then, in your script, put the entire creation of the SVG and the associated animating transition within the d3 onClick event. Read more about D3 click events here. Your code will look like the following.

// Start Animation on Click
d3.select("#start").on("click", function() {
	var path = svg.append("path")
	    .datum(data)
	    .attr("class", "line")
	    .attr("d", line);

	// Variable to Hold Total Length
	var totalLength = path.node().getTotalLength();

	// Set Properties of Dash Array and Dash Offset and initiate Transition
	path
		.attr("stroke-dasharray", totalLength + " " + totalLength)
		.attr("stroke-dashoffset", totalLength)
	.transition() // Call Transition Method
		.duration(4000) // Set Duration timing (ms)
		.ease(d3.easeLinear) // Set Easing option
		.attr("stroke-dashoffset", 0); // Set final value of dash-offset for transition
});

// Reset Animation
d3.select("#reset").on("click", function() {
	d3.select(".line").remove();
});

Save and refresh!

U.S. Unemployment Rate, January 2005-July 2015 (with Animation) - Data source: Bureau of Labor Statistics
(Click here to view this example on its own.)

Other Methods

Another method for unrolling a bar chart that involves creating a custom interpolation function is outlined in a fantastic post on 'Unrolling' Line Charts by Simon Kendall, of Big Elephants. I highly recommend running through this tutorial to help you understand another way to 'unroll' a line chart. Also, explore, compare, and contrast the following examples on unrolling line charts.

Challenge! Want to add a Tooltip?

There are many circumstances you might want to add a tooltip to your chart to retrieve exact values. Take a look at this example on X-Value Mouseovers from Mike Bostock and give it a shot. See the completed example below!

Unemployment, January 2005-July 2015 (with Tooltip on Hover after Animation) - Data source: Bureau of Labor Statistics
(Click here to view this example on its own.)

Supplemental: Focus and Context via Brushing

We are not going to do much with this file, but you can view brushing.html to view the code.

When working with big data, you will often find that you might want to focus or filter your data. Let's take another look at the U.S. Unemployment Rate data and how we could visualize it, this time showcasing Brushing and Scrubbing. Mike Bostock's bl.ocks have a nice example of Focus and Context via Brushing available that works very nicely with our data.

Open a blank document and steal some code!

I'm gonna let you start this one from scratch. Open a blank HTML document, and then go to the Focus and Context via Brushing Example by Mike Bostock. I've grabbed and modified the example to work with our unemployment data and the finished product is below, let's take a look at it and what lines of code we need to change to work with the unemployment data. Do this now, in the next step, we will perform some simple steps to customize it to work with our unemployment CSV.

U.S. Unemployment, January 2005-July 2015 (with Focus and Context via Brushing)
Data source: Bureau of Labor Statistics
(Click here to view this example on its own.)

The Structure of the Brushing Example

The brushing example from Mike Bostock is arranged as two separate graphs that are organized using CSS to sit right next to one another. D3 JavaScript is then used to bind the data to the two graphs, one called focus and the other called context. The data is bound separately to each graph, meaning you can set different variables for each graph if you want. Finally, the D3 Brushing Component is used to provide interaction between the two graphs. If something changes in one, you will see the effects in the other.

With an understanding of the example, we can begin to modify, adjust, and customize the code, the next steps will perform this action.

Adjust the Code

With the code from the example copied to our own document, adjust it to work with the unemployment_2005_2015.csv. This example is nicely situated for us to incorporate our own data, there are just a couple items we need to adjust.

i. Adjust the Data Source

Locate the following line of code. This is the location in our script where the CSV method is called to bind our data to our document. Change the path and name of the CSV to where you are storing unemployment_2005_2015.csv in your development environment.

Change the following line...

d3.csv("sp500.csv", type, function(error, data) {
	...
};

to the location of your dataset.

d3.csv("path/to/unemployment_2005_2015.csv", type, function(error, data) {
	...
};
ii. Change the Variables

Change the variables from the columns in the example table to the column names in the unemployment table. In the example, the variables are date and price, in the unemployment table, the variables are date and rate.

There is no need to change the date variable, which is signified by d.date in the code, but locate all instances of d.price. Change these to d.rate.

Find all instances of the following...

d.price

and change to the variable we want to show from our dataset.

d.rate

That is it! Save and refresh!

Date Formatting and Date Capabilities

An important item to note, although not the case in this example, the date format in your data might be different in the example than in the dataset you want to work with. D3 has robust and supports many formats. The D3 Date Formatting page provides documentation the built-in variables that support various date formats. For more general reading on time capabilities in D3, read the documentation here.

To change the date to the proper formatting, locate the following line that defines the format in which the date is read in and modify it as needed.

var parseDate = d3.timeParse("%b %Y");

At this point, our graph looks like the following. Get creative, can you add a tooltip?

U.S. Unemployment, January 2005-July 2015 (with Focus and Context via Brushing)
Data source: Bureau of Labor Statistics
(Click here to view this example on its own.)

The D3 Brush Component

This example uses the D3 Brush component. Brushing refers to the connection of two or more views of the same data, such that a change to the representation in one view affects the representation in the other3. As mentioned above, when working with large datasets, using brushing and scrubbing can be a great way to drill down into the data or provide greater context when viewing a small portion of a very large dataset.

In this example, brushing is implemented in a few steps. Read more on the brushing options in the D3 Brush documentation. You can also check out these other exciting brushing examples.


Click and Drag an SVG

We are not going to do much with this file, but you can view drag.html to view the code.

Finally, we are going to end our exercise today by doing something fun and simple, but perhaps useful in opening up your creative side in D3. Let's look at how we can draw a dot, then click and drag it around the page. We will base this off of the following JSFiddle example on clicking and dragging SVG elements using D3. Copy and paste this into a blank document, or just play with the JSFiddle.

Introducing the D3 Drag Behavior

I won't spend alot of time on the nuances of this code, by this time, you should be able to understand what is happening in the D3 script. The important item to point out here is the Drag Behavior. This behavior automatically creates event listeners to hand drag gestures on an element, both by mouse and touch!

The D3 script for this visualization is below. The highlighted lines are where we invoke the Drag Behavior, and styling is done with simple CSS.

// The Dataset in JSON format
dataset = [
  { x: 100, y: 100, value: 50, city: "Cambridge" },
  { x: 175, y: 250, value: 80, city: "Boston" },
  { x: 300, y: 100, value: 30, city: "Brookline" },
  { x: 400, y: 200, value: 40, city: "Somerville" },
  { x: 225, y: 125, value: 20, city: "Watertown" },
  { x: 450, y: 100, value: 50, city: "Medford" }
];

// Create SVG
var svg = d3.select("svg"),
    width = +svg.attr("width"),
    height = +svg.attr("height"),
    radius = 32;

// Set up a color scale (color our dots)
var color = d3.scaleOrdinal()
    .range(d3.schemeCategory20);

// Create Circles
svg.selectAll("circle")
  .data(dataset)
  .enter().append("circle")
    .attr("cx", function(d) { return d.x; })
    .attr("cy", function(d) { return d.y; })
    .attr("r", function(d) { return d.value; })
    .style("fill", function(d, i) { return color(i); })
    .call(d3.drag()
        .on("start", dragstarted)
        .on("drag", dragged)
        .on("end", dragended));

// Function to handle what happens when drag is started
function dragstarted(d) {
  d3.select(this).raise().classed("active", true);
}

// Function to handle what happens when drag is in progress
function dragged(d) {
  d3.select(this).attr("cx", d.x = d3.event.x).attr("cy", d.y = d3.event.y);
}

// Function to handle what happens when drag is ended
function dragended(d) {
  d3.select(this).classed("active", false);
}

More on Dragging and Dropping and D3 Behaviors

Dragging and dropping elements can be a powerful way to add interactivity to your visualization. A suggested read on how to handle dragging and dropping can be found in here in the excellent blog post on Implementing Drag and Drop by Jason Graves.


Animate your charts by using transitions!

This week we looked deeply into animations and transitions. Think about how you can apply some of the fundamentals learned here to your D3 visualizations. Next week, we are going to look at a different part of D3, one that you find yourself using alot as a planner... maps!



References and Bibliography

1 - Animations and Transitions - Jerome Cukier - http://blog.visual.ly/creating-animations-and-transitions-with-d3-js/

2 - Notes on Animating Line Charts with D3 - Simon Kendall (Big Elephants)http://blog.visual.ly/creating-animations-and-transitions-with-d3-js/

3 - Modern Information Retrieval - User Interfaces and Visualization - Marti Hearst http://people.ischool.berkeley.edu/~hearst/irbook/10


Go to main DUSPVIZ tutorials page