Using the D3 JavaScript Library
for Interactive Graphs and Maps

Three little circles - a first attempt at D3

Create an HTML file called 3LittleCircles.html, and make sure its contents match the code in the Listing below. As explained in the Preparation section, you can copy code from the listing to avoid having to type it all.

Open the file in a web browser. You should see the result depicted in the figure below. We will use these three SVG circles to show you how selections and data-binding in D3 work.

Using SVG for drawing

The D3 library can be used to manipulate any element within the webpage, through the Domain Object Model (DOM). In this exercise, we use it to draw graphics, therefore we need to use the graphics elements within a DOM. We use the Scalable Vector Graphics language (SVG) for this. The SVG element can be thought of as a viewport --- things within the SVG Viewport's dimensions are visible, things outside of the dimensions are not. The SVG element dimensions are defined using the attribute value pairs of "height" and "width". Note that the top-left corner is 0,0, the x-axis is drawn left-to-right, but the y-axis is drawn top-to-bottom. In SVG, drawing instructions are coded like HTML code, e.g. line 8 <circle cx="40" cy="60" r="10"></circle> draws a circle of radius 10 at xy-coordinate (40,60).

There are various ways to use D3 to manipulate your SVG and HTML elements. A very easy way, with immediate results and feedback, is to interactively type the code in the Web browsers' javascript console (as demonstrated in class). The disadvantage is that your changes are not saved.

Therefore, in these exercises, you will type the code within the script tag in the html file (where its says //our D3 code will go here...). All the fragments we show in the coming pages should be entered in there, and then tested by saving the file and reloading it in the browser. We will not always tell you the exact place where to enter the code, this is for you to figure out...!

Selecting Elements for script access

The d3.selectAll method takes a selector string, such as "circle", and returns a selection representing all elements that match the selector:

let circles = d3.selectAll("circle");

The selector string will select all elements in the HTML DOM that match it. There are several types of selector strings, that select:

  • By default by element name (as in the case above). You can select any named element, in SVG as well as HTML elements (such as a "div"): d3.selectAll("div");
  • If you add a "." before the name, you will be selecting by CSS class: d3.selectAll(".shaded");
  • If you add a "#" before the name, you will be selecting by HTML id: d3.selectAll("#myID");
  • The selectors can be combined, e.g. selecting all div elements of class shaded: d3.selectAll("div.shaded");

You can use selectAll() to select all elements or simply select() to select only the first one encountered. Once we have a selection, we can make various changes to the selected elements. For example, we might change the fill color using selection.style and the radius using selection.attr:

Insert the three new lines of code shown in Listing 3, the D3 library sets styles and attributes for all selected elements to the same values. If you refresh the file in the browser, you will see the changes, and if you would look at the HTML DOM in its active state (e.g. by using the browser developer tools), you will see the SVG part has been changed to include the style elements

Changing Individual Elements

We can also set values in a selection seperately (on a per-element basis) by using anonymous functions. Such a function (without a name, hence the title 'anonymous') is evaluated once for every selected element. Anonymous functions are used extensively in D3 to compute attribute values.

To set each circle's radius to a random value, change the line that sets the radius to:

Note that the parameter for the radius has been changed from a simple value (20) to a function. This function will be evaluated for every element in the selection. In this case, the function will return a random value in the range 0-50, because Math.random() returns a random number between 0 and 1, which gets multiplied by 50.

Now experiment by adding lines that also makes the locations of the circles random. For this, you should look at the original SVG circle definition to see which attributes you have to change, and think about the range of the random numbers you should generate...