Tutorial Material

This tutorial was prepared by Wellesley student, Lucy Shen '17, while she was learning D3.js, using the book D3.js in Action. Lucy took examples that appeared in the book, broke them into pieces, in the style of labs we have in our CS courses and added additional information and questions to facilitate understanding.

Task 0 - Preparing the HTML

Base HTML code that you can copy into a file. Alternatively, create an HTML skeleton file with your editor (e.g. Brackets) and made sure to link to the D3.js library. The Javascript code in the snippets should go within the script tag! You should enter your code snippets one by one and then test the code. Don't enter all code at once.

<html>
  <head>
    <script src="http://d3js.org/d3.v3.min.js"></script>
  </head>

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

Task 1 - Selecting and appending

Concepts:

  • Method Chaining
  • Selecting

Step 1: Appending the div

d3.select("body")
    .append("div")
    .style("border", "1px black solid")
    .text("hello world");

In English:

  1. Selecting the “<body>” element in the HTML,
  2. we create and append a “<div>” to it ,
  3. with the CSS style rule of a solid, black, 1px-thick border,
  4. and containing the text "hello world".

Step 2: Event Binding

d3.selectAll("div")
    .style("background-color", "pink")
    .style("font-size", "24px")
    .attr("class", "d3div")
    .on("click", function() {alert("You clicked a div")})

In English:

  1. Selecting the first <div> of the document (there is a second method, .selectAll() to choose all elements with the selector name),
  2. we color the background of the <div> pink in the CSS
  3. and change the font size of the <div> to 24px in the CSS.
  4. We add to the <div> tag a “class” attribute and name this new class "d3div".
  5. We bind an event handler to the <div> tag selected in the first line. The event is the action of a "click", and when that action is executed (when someone clicks the <div>), a function is called. In this example, that function has only one line: alert that will display "You clicked a div".

Task 2 - The <svg> element

This task is completely separate from Task 1. You can keep the base HTML file, but your script area will look entirely different! Remember to save the different files separately for future reference.

Concepts:

  • svg element
  • DOM order - no z-scale!
  • coordinate attributes

Step 0:

Add the svg element in the HTML file, within the body.

<svg style="width:500px; height:500px; border:1px lightgray solid;">

</svg>       

Step 1:

d3.select("svg")
    .append("line")
    .attr({"x1":20, "y1":20, "x2":250, "y2":250})
    .style("stroke","red")
    .style("stroke-width","4px");

Select the “<svg>” tag added in the HTML file and append a line with starting point (20,20) and ending point (250,250). The line is 4px wide and red.

Step 2:

d3.select("svg")
    .append("text")
    .attr({"x": 20, "y": 20})
    .text("HELLO");

Select the <svg> tag again and append “text” to it at the coordinate (20, 20) with the text content “HELLO”. (Note: Hit inspect element to see what your HTML looks like after the script has been run!)

Step 3:

d3.select("svg")
    .append("circle")
    .attr({"r": 20, "cx": 20, "cy": 20})
    .style("fill","purple");
    
d3.select("svg")
    .append("circle")
    .attr({"r": 100, "cx": 400, "cy": 400})
    .style("fill", "lightblue");

Now, select the <svg> again and this time, append a circle with the specified attributes (cx and cy denote center coordinates). Select it again and append the other circle with its own attributes.

Step 4:

d3.select("svg")
    .append("text")
    .attr({"x": 400, "y": 400})
    .text("WORLD");

Now, append the final text “WORLD” to the <svg>, positioned at the point (400,400).

Food for thought: Why do the elements overlap the way they do? What determines what goes on top and what goes below?

Task 3 - Transitions

To add transitions (the D3.js equivalent of animations), we’ll need to change our base code up a bit. To start off with, make a copy of your previous file, and then replace the <script> code with the one shown below.

Step 1:

d3.select("svg")
    .append("circle")
    .attr({"r": 20, "cx": 20, "cy": 20})
    .style("fill","red");
            
d3.select("svg")
    .append("text")
    .attr("id","a")
    .attr({"x": 20, "y": 20})
    .style("opacity", 0)
    .text("HELLO WORLD");          

d3.select("svg")
    .append("circle")
    .attr({"r": 100, "cx": 400, "cy": 400})
    .style("fill","lightblue");
            
d3.select("svg")
    .append("text")
    .attr("id","b")
    .attr({"x": 400, "y": 400})
    .style("opacity", 0)
    .text("Uh, hi.");

Take a look at the code above.

  • Why is the code broken up in the way it is?
  • Find all the added instructions (were not in the previous code). Why don't you see all elements?
  • Can you see the purpose of the added instructions, with respect to transitions (which we'll add in the next step).

Step 2:

Add the following code:

d3.select("#a")
    .transition()
    .delay(1000)
    .style("opacity", 1);

Time to add transitions with the .transition() method. .delay(milliseconds) determines the amount of time to elapse before the transition is applied. We usually delay animations by a little bit because instantaneous changes can be jarring for the user. This particular transition above waits a second (1000 milliseconds) before it transitions the opacity of #a (one of the text fields) from 0 (transparent, therefore invisible) to 1 (full opacity).

Step 3:

d3.select("#b")
    .transition()
    .delay(2000)
    .style("opacity", .75);
d3.selectAll("circle")
    .transition()
    .duration(2000)
    .attr("cy", 200);

What do you think the above code does?

Here are some things you can try:

  • Have 4 circles on the canvas, each moving in different directions.
  • Have each of the circles move at different times.
  • Make it look like there is only one circle when the page first loads, but reveal through transitions that there are actually many layers.