1 of 32

Overview of d3.js

Sept. 6, 2016

2 of 32

CS 205 Workbook

python workbook.py

Data Source

View

Data Processing

/res directory

txt, csv, jpg, json

/py directory

compute.py

/res for output

/res

data.json

/web directory

index.html

<script> ⇒ vis.js

3 of 32

Anatomy of a d3.js visualization

  1. Boilerplate Code
  2. Scales
  3. Axes
  4. Visual Encodings

4 of 32

d3.js coordinate system

5 of 32

d3.js Boilerplate Code

var margin = { top: 50, right: 50, bottom: 50, left: 50 },� width = 970 - margin.left - margin.right,� height = 700 - margin.top - margin.bottom;��var svg = d3.select("#chart").append("svg").attr("width", width + margin.left + margin.right).attr("height", height + margin.top + margin.bottom).style("width", width + margin.left + margin.right).style("height", height + margin.top + margin.bottom).append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");

6 of 32

d3.js Boilerplate Code

var margin = { top: 50, right: 50, bottom: 50, left: 50 },� width = 970 - margin.left - margin.right,� height = 700 - margin.top - margin.bottom;

7 of 32

d3.js Boilerplate Code

var svg = d3.select("#chart")

Connects the JavaScript/d3.js to the HTML, via an element that has an id=”chart”.

<div id="chart">

8 of 32

d3.js Boilerplate Code

var svg = d3.select("#chart")� /* … */.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");

9 of 32

d3.js: Scales

Consider a plot of exam grades:

  • Student grades are [0, 100]
  • We want to graph them on a horizontal line

10 of 32

  • Solving Mathematically:

11 of 32

  • Solving Mathematically:
    • grade / 100 = y-coord / width�data / 100 = y / width �width * (data / 100) = y

12 of 32

  • Solving Mathematically:
    • grade / 100 = y-coord / width�data / 100 = y / width �width * (data / 100) = y
    • f(data) = width * (data / 100)

13 of 32

d3.js: Scales

d3.js scales allow us to map an input domain to an output range by specifying the domain, range, and function:

  • input domain: [0, 100]
  • output range: [0, width]
  • function: linear

14 of 32

d3.js: Scales

var gradeScale = d3.scaleLinear().domain([0, 100]).range([0, width]);

15 of 32

d3.js: Scales

gradeScale(65) finds the value for ???

16 of 32

d3.js: Scales

Quantitative Scales:

d3.scaleLinear()�d3.scalePow()�d3.scaleLog()

Discrete Categories (Ordinal) Scales:

d3.scaleOrdinal()�d3.scaleBand()�

17 of 32

d3.js: Axes

Given a d3.js scale variable, it is simple to draw an axis:

var axisVariable = d3.axisTop().scale( scaleVariable );

svg.append("g").call( axisVariable );

18 of 32

Visual Encodings

How do we draw the circles?

The data we want to visualize must be an array:

data = [� { "student": "1", "grade": 87 },� { "student": "2", "grade": 91 },� …� ]

19 of 32

Visual Encodings

d3 allows us to “loop” through our data:

svg.selectAll("grade")� .data(data)� .enter()� /* ... everything here runs once *� * per entry in our array ... */

20 of 32

svg.selectAll("grade")� .data(data)� .enter() .append("circle") .attr("r", function (d, i) {� return 4;� })� /* ...more .attr functions... */

21 of 32

Basic Shapes in d3.js

  • Circle ("circle")
    • Requires a cx, cy, and r (radius)�
  • Rectangle ("rect")
    • Requires an x, y, width, and height�

22 of 32

svg.selectAll("grade")� .data(data)� .enter() .append("circle") .attr("r", function (d, i) {� return 4;� }) /* ...more .attr functions... */

23 of 32

.attr("r", function (d, i) {� return 4;� })�

Every attribute (.attr) function takes in two arguments:

  1. An attribute value (eg: "r")
  2. An attribute value, in the form of either:
    1. A function that returns a value, in the format of:� function(d, i) { }d, the array element from the data arrayi, the current index in the array
    2. A value (string, number, etc)

24 of 32

svg.selectAll("grade")� .data(data)� .enter()� .append("circle")� .attr("r", function (d, i) {� return 4;� })� .attr("cx", function (d, i) {� return gradeScale( d["grade"] );� })� .attr("cy", 0)� .attr("fill", "red")� .attr("stroke", "black")� ;

25 of 32

Rental Encodings

  • Fill Color ("fill")
    • Any string representing a color�
  • Stroke Color ("stroke")
    • Any string representing a color�
  • Stroke Width (“stroke-width”)
    • Any number

26 of 32

svg.selectAll("grade")� .data(data)� .enter()� .append("circle")� .attr("r", function (d, i) {� return 4;� })� .attr("cx", function (d, i) {� return gradeScale( d["grade"] );� })� .attr("cy", 0)� .attr("fill", "red")� .attr("stroke", "black")� ;

27 of 32

.attr("cx", function (d, i) {� return gradeScale( d["grade"] );�})�data = [� { "student": "1", "grade": 87 },� { "student": "2", "grade": 91 },� { "student": "3", "grade": 64 },� { "student": "4", "grade": 97 },� ...�}

First Pass: d = { "student": "1", "grade": 87 }

28 of 32

.attr("cx", function (d, i) {� return gradeScale( 87 );�})�data = [� { "student": "1", "grade": 87 },� { "student": "2", "grade": 91 },� { "student": "3", "grade": 64 },� { "student": "4", "grade": 97 },� ...�}

First Pass (i=0)

29 of 32

.attr("cx", function (d, i) {� return 756.9;�})�data = [� { "student": "1", "grade": 87 },� { "student": "2", "grade": 91 },� { "student": "3", "grade": 64 },� { "student": "4", "grade": 97 },� ...�}

First Pass (i=0)

30 of 32

.attr("cx", function (d, i) {� return gradeScale( 91 );�})�data = [� { "student": "1", "grade": 87 },� { "student": "2", "grade": 91 },� { "student": "3", "grade": 64 },� { "student": "4", "grade": 97 },� ...�}

Second Pass (i=1)

31 of 32

.attr("cx", function (d, i) {� return 791.7;�})�data = [� { "student": "1", "grade": 87 },� { "student": "2", "grade": 91 },� { "student": "3", "grade": 64 },� { "student": "4", "grade": 97 },� ...�}

Second Pass (i=1)

32 of 32

.attr("cx", function (d, i) {� return gradeScale( d["grade"] );�})�data = [� { "student": "1", "grade": 87 },� { "student": "2", "grade": 91 },� { "student": "3", "grade": 64 },� { "student": "4", "grade": 97 },� ...�}