Week 6 Follow-up: Data Import and Parse; Mining; Representing

In Weeks 5 and 6, we used Ben Fry’s data visualization pipeline as a framework to break down and solve the visualization problem of a scatterplot. A succinct recap of this pipeline can be found here.

We also began to learn how d3 implements solutions to these tasks. In particular, in week 5 we focused on using d3.csv to import and parse data. In week 6, we previewed how d3 uses the concept of joining to generate DOM elements and bind them to data.

Please review the API reference for the following before starting this assignment.

  1. d3.csv
  2. selection.data
  3. d3.scaleLinear
  4. d3.min and d3.max
This assignment will likely be difficult for beginners. Please allot a decent amount of time to this assignment (~2 hours) and try to complete as much of this on your own as you can. We will offer tutorial time to help with this assignment.

The Assignment: Create a Bar Chart

Based on a dataset of Olympic medal counts for selected countries, we would like to generate a simple bar chart similar to the following:

This simple bar chart uses the vertical dimension of rectangles to encode medal count. Each group of rectangle + label represents a country. The x-axis location of these groups doesn’t encode any information. We simply take the top 5 countries and space them equally across in descending order.

Step 1: Import and Parse

Please refer to the previous week to see instructions for this step:

Step 2: Mine the data, and set up scales

To establish the appropriate y-scale for this chart, we need to know what the maximum and min are. You can use d3.max() to find this. Alternatively, since the dataset is so small, a quick visual scan should suffice!

Knowing the max and min, set up a d3.scaleLinear() function to map domain (medal count) to range (pixel count along the y axis).

Step 3: Sorting and slicing the array

You’ll notice that the example shows the top 5 countries only. This involves two steps: sorting, in which we rearrange elements in the array according to their medal count; and slicing, in which we take the first 5 elements in the array.

To sort the array, use array.sort(). In our example, the implementation would look something like this:

array.sort(function(b,a){
return b.count2012 - a.count2012;
})
/* this will sort the array by descending order, according to the "count2012" property */

To slice the array and extract the first 5 elements, do this

array.slice(0,5);

Step 4: Represent, using join

Here comes the fun part. To represent 5 countries as 5 bars, we need to create 5 DOM elements that correspond to array elements.

We know how to do this with array.forEach(). However, in this case, let’s put our knowledge of join to work.

Join is the process whereby we create 1 DOM element for 1 data element, and bind them so that data becomes a property of the DOM element. One example of this would be:

/* If I were trying to join circles to data array elements */
var circles = plot.selectAll('circle')
.data(dataArray)
.enter()
.append('circle')
.attr('cx',function(d){
return d.someProperty
})

Let’s focus on the last few lines. What is happening here?

.attr('cx',function(d){
return d.someProperty;
})

A simplified explanation goes like this. Now that we’ve created new DOM elements (circles) and joined them to data, we can use the data to set attributes of the DOM element. Using “function(d){…}”, we can access the data joined to each element directly. The argument “d” stands for the data element.

Step 5: Axis

This is the final step. Please review in-class work and add a vertical axis for medal count.

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.