D3: The Crash Course
Chad Stolper Georgia Tech
CSE 6242: Data and Visual Analytics
But first…
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 2
http://www.babynamewizard.com/voyager#prefix=&sw=both&exact=false 1/23/14 Chad Stolper
CSE 6242 Guest Lecture 3
D3: The Crash Course
Chad Stolper Georgia Tech
CSE 6242: Data and Visual Analytics
D3: Scratching the Surface
D3: Only the Beginning
Please do not be afraid to ask questions!
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 7
§ History § Website…
• Directory Structure • Development
§ Javascript 101-2 § SVG Basics § D3.js Crash Course
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 8
http://bl.ocks.org/mbostock/1256572
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 9
Mike Bostock and Jeff Heer @ Stanford
2009- Protovis
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 10
Mike Bostock and Jeff Heer @ Stanford
2009- Protovis 2011- D3.js
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 11
Who has some programming experience?
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 12
Who has some web development experience?
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 13
Website Directory Structure § (Replace “project” with a real name)
§ project/ • index.html
§ project/lib/ • d3.v3.js
§ project/js/ • project.js
§ project/css/ § project/img/
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 14
Chrome Inspector and Console
§ Open the webpage § Right-click on anything § Click inspect this element § Click on the >= button at the very
bottom to open the console as well • (2nd from the left)
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 15
Starting a Local Webserver
§ python -m SimpleHTTPServer 8000
§ http://localhost:8000
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 16
How many of you have experience with Javascript?
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 17
Javascript 101 § All variables are global unless declared using
var • x = 300 (global) vs. var x = 300 (local)
§ Semicolons are completely optional § “text” is the same as ‘text’ § JS arrays and objects are almost exactly the
same syntax as python’s lists and dicts § object.key is the same as object[‘key’] § Print to the console using console.log( )
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 18
Javascript 102: Functional Programming
§ Javascript is a functional language • Functions are themselves objects • Functions can be stored as variables • Functions can be passed as parameters
§ D3 uses these abilities extensively!
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 19
Javascript 102: Functional Programming
§ Javascript is a functional language • Functions are themselves objects • Functions can be stored as variables • Functions can be passed as parameters
§ D3 uses these abilities extensively!
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 20
Array.map( )
§ Used for applying a function to each element of an array
§ The function provided as a parameter takes one parameter itself: • d: a/each data point
§ https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 21
Array.map( )
§ var x = [{val:1},{val:2},{val:3},{val:4}] § var a = x.map(function(d){
return d.val; })
§ a : [1,2,3,4]
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 22
MDN
§ Mozilla Developer Network
§ https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference
§ (Easier: google “<command> mdn”) 1/23/14 Chad Stolper
CSE 6242 Guest Lecture 23
Method Chaining
§ Programming paradigm where each method returns the object that it was called on
§ Simply put: group.attr(“x”,5).attr(“y”,5) //returns group is the same as
group.attr(“x”,5) //returns group group.attr(“y”,5) //returns group
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 24
SVG BASICS
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 25
How many of you have experience with SVG?
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 26
How many have experience with 2D computer graphics (such as Java Swing)?
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 27
x
y (0,0)
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 28
SVG Basics
XML Vector Graphics
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 29
SVG Basics
§ XML Vector Graphics • Tags with Attributes • <circle r=5 fill=“green”></circle>
§ W3C Standard • http://www.w3.org/TR/SVG/
§ Supported by all the major browsers
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 30
SVG Basics
§ <svg> § <circle> § <rect> § <path> § <g>
§ 1/23/14 Chad Stolper
CSE 6242 Guest Lecture 31
SVG Basics
§ <svg> § <circle> § <rect> § <path> § <g>
§ <text> (after I’ve talked about D3) 1/23/14 Chad Stolper
CSE 6242 Guest Lecture 32
<svg> element
§ Overarching canvas
§ (optional) Attributes: • width • Height
§ Create with • d3.select(“#vis”).append(“svg:svg”)
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 33
<circle> element
§ Attributes: • cx (relative to the LEFT of the container) • cy (relative to the TOP of the container) • r (radius)
§ (optional) Attributes: • fill (color) • stroke (the width of the stroke) • stroke-fill (the color of the stroke)
§ Create with • .append(“svg:circle”)
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 34
<rect> element
§ Attributes: • x (relative to the LEFT of the container) • y (relative to the TOP of the container) • width (cannot be negative) • height (cannot be negative)
§ (optional) Attributes: • fill (color) • stroke (the width of the stroke) • stroke-fill (the color of the stroke)
§ Create with • .append(“svg:rect”)
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 35
x
y
width
height
(0,0) origin
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 36
Rather than positioning each element, what if we want to position all the
elements?
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 37
<g> element
§ Generic container (Group) element
§ Attributes • transform
§ Create with: • var group = vis.append(“svg:g”)
§ Add things to the group with: • group.append(“svg:circle”) • group.append(“svg:rect”) • group.append(“svg:text”)
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 38
Transform Property
“transform”, “translate(x,y)”
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 39
.attr(“transform”,“translate(x,y)”)
translate(30,20) 30
20
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 40
AND NOW D3…
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 41
D3 § Grand Reductionist Statements
§ Loading Data § Enter-Update-Exit Paradigm § Scales § Axes § Layouts § Transitions and Interaction § Where to go from here
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 42
D3 is a really powerful for-loop with a ton of useful helper functions
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 43
D3
§ Declarative, domain-specific specification language for visualization
§ i.e. • Define a template for each type of element • D3 draws one element for each data point
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 44
Importing D3
<html > <head> <meta charset="UTF-8”> <script src='lib/d3.v3.js'></script> <script src='js/project.js'></script>
</head> <body> <div id=“vis”></div>
</body> </html>
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 45
Assigning the Canvas to a Variable
vis = d3.select(“#vis”) .append(“svg:svg”)
<body> <div id=“vis”><svg></svg></div>
</body>
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 46
Loading Data
§ d3.csv(fileloc,callback) § d3.json(fileloc,callback)
§ fileloc: string file location • “data/datafile.csv”
§ callback: function(rawdata){ } 1/23/14 Chad Stolper
CSE 6242 Guest Lecture 47
rawdata from a CSV file name school age Adam GT 18 Barbara Emory 22 Calvin GSU 30
[ {
‘name’: ‘Adam’,
‘school’: ‘GT’,
‘age’: ‘18’
},
{
‘name’: ‘Barbara’,
‘school’: ‘Emory’,
‘age’: ’22’
},
{
‘name’: ‘Calvin’,
‘school’: ‘GSU’,
‘age’: ‘30’
}
]
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 48
Problem rawdata: [ { ‘name’: ‘Adam’, ‘school’: ‘GT’, ‘age’: ‘18’ }, { ‘name’: ‘Barbara’, ‘school’: ‘Emory’, ‘age’: ’22’ }, { ‘name’: ‘Calvin’, ‘school’: ‘GSU’, ‘age’: ‘30’ } ]
§ Ages are Strings, not ints. § We can fix that: for(var d: rawdata){
d = rawdata[d] d.age = +d.age
}
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 49
rawdata from a JSON file name school age Adam GT 18 Barbara Emory 22 Calvin GSU 30
[ {
‘name’: ‘Adam’,
‘school’: ‘GT’,
‘age’: 18
},
{
‘name’: ‘Barbara’,
‘school’: ‘Emory’,
‘age’: 22
},
{
‘name’: ‘Calvin’,
‘school’: ‘GSU’,
‘age’: 30
}
]
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 50
Enter-Update-Exit § The most critical facet of how D3 works
§ If you remember nothing else from today, remember this...
§ “Enter-Update-Exit” § “Enter-Update-Exit” § “Enter-Update-Exit”
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 51
Enter-Update-Exit § The most critical facet of how D3 works
§ If you remember nothing else from today, remember this...
§ “Enter-Update-Exit” § “Enter-Update-Exit” § “Enter-Update-Exit”
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 52
Enter-Update-Exit
§ Pattern: • Select a “group” of “elements” • Assign data to the group • Enter: Create new elements for data points
that don’t have them yet • Update: Set the attributes of all the
elements based on the data • Exit: Remove elements that don’t have
data anymore 1/23/14 Chad Stolper
CSE 6242 Guest Lecture 53
Can be hard to grok: You can select groups of elements that
DON’T EXIST YET
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 54
.enter( ) and .exit( )
§ .enter( ) • New data points
§ .exit( ) • Old data points
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 55
.enter( ) and .exit( )
§ .data( [1,2,3,4] ) § .data ( [1,2,3,4,5,6] ) § .data ( [1,2,3] ) //4,5,6
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 56
Data Key Functions
§ .data(rawdata) defaults to assuming that the index of the point is the key
§ .data(rawdata, function(d,i){ }) allows you to set a key functions
§ e.g. • .data(rawdata, function(d,i){ return d.id; }) • .data(rawdata, function(d,i){ return d.name; })
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 57
E-U-E Pattern Template
var group = vis.selectAll(“rect”) .data(rawdata) //rawdata must be an array!
group.enter( ).append(“svg:rect”) //ENTER! .attr( ) .attr( )
group //UPDATE! .attr( ) .attr( )
group.exit( ).remove( ) //EXIT! 1/23/14 Chad Stolper
CSE 6242 Guest Lecture 58
.attr( )
§ The Attribute Method § Sets attributes such as x, y, width,
height, and fill
§ Technical details: • rect.attr(“x”, 5) • <rect x=“5”></rect>
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 59
.attr( ) and Functional Programming
§ [ {size: 10}, {size: 8}, {size: 12.2} ]
§ .attr(“height”, function(d,i){ return d.size }) • d: the data point
§ .attr(“x”, function(d,i){ return (i+1)*5; }) • i: the index of the data point
<rect height=“10” x=“5”></rect> <rect height=“8” x=“10”></rect> <rect height=“12.2” x=“15”></rect>
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 60
<text> elements
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 61
<text> elements
§ I’m going to apologize in advance here for the lousy job the w3c did with the <text> definition.
§ You’re going to have to just either memorize these things or keep referring back to http://www.w3c.org/TR/SVG/text.html (first Google hit for “svg text”) like I do.
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 62
<text> elements
§ Extra Method in D3 • .text(“Your Text Goes Here”) • <tag>Your Text Goes Here</tag>
§ Attributes • x • y
§ Styles • text-anchor: start, middle, end • dominant-baseline: [nothing], hanging, middle
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 63
text-anchor style
This is my line of text. start end middle
Where is (0,0)?
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 64
dominant-baseline style
This is my line of text. hanging
default middle
Where is (0,0)?
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 65
<text> example group.append(“svg:text”)
.text(function(d){return d.name}) .attr(“x”, function(d,i){return i*5}) .attr(“y”, function(d,i){return height;}) .style(“dominant-baseline”,“hanging”) .style(“text-anchor”, “middle”)
.style(“prop1”,“val1”) .style(“prop2”,“val2”) <ele style=“prop1: val1; prop2: val2;”>
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 66
What if you have two different types of circles?
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 67
Classing § CSS Classes
• Any number of classes per element • Select using “.classname”
red = vis.selectAll(“circle.redcircle”)
.data(reddata, function(d){return d.id;}) red.enter( ).append(“svg:circle”)
.classed(“redcircle”,“true”) blue = vis.selectAll(“circle.bluecircle”)
.data(bluedata, function(d){return d.id;}) blue.enter( ).append(“svg:circle”)
.classed(“bluecircle”, “true”) vis.selectAll(“.bluecircle”).attr(“fill”,“blue”) red.attr(“fill”,“red”)
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 68
§ .attr(“height”, 5) is boring § .attr(“height”, function(d,i){ return i*5; })
only works for fixed values § .attr(“height”, function(d){ return d; }) can
blow up really quickly…
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 69
Scales
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 70
Scales
§ D3 has many types of scales § I am only going to cover two:
• Linear Scales • Ordinal Scales
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 71
Linear Scales
§ var xscale = d3.scale.linear( ) • .domain( [min, max] ) • .range( [minOut, maxOut] )
§ group.attr(“x”, function(d,i){ • return xscale(d.size); })
§ y = mx+b 1/23/14 Chad Stolper
CSE 6242 Guest Lecture 72
Min and Max
But how do you figure out the min and max for the domain?
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 73
D3
A really powerful for-loop with a ton of useful helper functions
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 74
Min and Max
§ d3.min( [ ] ) à number § d3.max( [ ] ) à number § d3.extent( [ ] ) à [number,number]
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 75
Min and Max
§ d3.min( [ ] ) à number § d3.max( [ ] ) à number § d3.extent( [ ] ) à [number,number]
§ All can be combined with • .map( function(d){ } ), which returns an [ ]
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 76
d3.min( data.map( function(d){ return d.age; })
) // returns the minimum age
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 77
Linear Scales
§ You can even keep the same scale, and just update the domain and/or range as necessary
§ Note: This will not update the graphics all on its own
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 78
Ordinal Scales
§ D3 has built-in color scales! • (And they’re easy!)
§ var colorscale = d3.scale.category10( )
§ Also available are: • category20( ) • category20b( ) • category20c( ) • (and even a few more)
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 79
Ordinal Nominal Scales
§ D3 has built-in color scales! • (And they’re easy!)
§ var colorscale = d3.scale.category10( )
§ Also available are: • category20( ) • category20b( ) • category20c( ) • (and even a few more)
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 80
Ordinal Nominal Scales
§ [ {type:‘Bird’},{type:‘Rodent’},{type:‘Bird’} ]
§ var colorscale = d3.scale.category10( ) § .attr(“fill”,function(d,i){
• return colorscale(d.type) } • <rect fill=“blue”></rect> • <rect fill=“orange”></rect> • <rect fill=“blue”></rect>
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 81
Axes
D3 also has visual helper-functions
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 82
Axes
§ yaxisglyph = chart.append(“g”)
yaxis = d3.svg.axis( ) .scale( yscale ) //must be a numerical scale .orient( ‘left’ ) //or ‘right’ or ‘top’ or ‘bottom’ .ticks( 6 ) //number of ticks, default is 10
yaxisglyph.call(yaxis) 1/23/14 Chad Stolper
CSE 6242 Guest Lecture 83
D3 even has some entire techniques built in…
http://bl.ocks.org/mbostock/4062045
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 84
What if the data is changing?
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 85
E-U-E Pattern Template
var group = vis.selectAll(“rect”) .data(rawdata) //rawdata must be an array!
group.enter( ).append(“svg:rect”) //ENTER! .attr( ) .attr( )
group //UPDATE! .attr( ) .attr( )
group.exit( ).remove( ) //EXIT! 1/23/14 Chad Stolper
CSE 6242 Guest Lecture 86
E-U-E Pattern Template
function redraw(rawdata){ var group = vis.selectAll(“rect”)
.data(rawdata) //rawdata must be an array! group.enter( ).append(“svg:rect”) //ENTER!
.attr( ) .attr( )
group //UPDATE! .attr( ) .attr( )
group.exit( ).remove( ) //EXIT!
}
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 87
E-U-E Pattern Template
function redraw(rawdata){ var group = vis.selectAll(“rect”)
.data(rawdata) //rawdata must be an array! group.enter( ).append(“svg:rect”) //ENTER!
.attr( ) .attr( )
group.transition() //UPDATE! .attr( ) .attr( )
group.exit( ).remove( ) //EXIT!
} 1/23/14 Chad Stolper
CSE 6242 Guest Lecture 88
Transitions
§ CSS3 transitions with D3 are magical!
§ D3 interpolates values for you…
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 89
Transitions
rect.attr(“height”, 0) rect.transition( )
.delay( 500 ) //can be a function of data .duration(200) //can be a function of data .attr(“height”, 5)
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 90
So they’re no longer static… But they’re not really interactive…
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 91
Interaction
The on( ) Method
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 92
.on( )
rect.on (“click”, function(d){ d.color = “blue”; redraw( )
}) HTML Events
• click • mouseover • mouseenter • mouseout • etc.
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 93
Where to get learn more…
§ http://d3js.org/ • Tons of examples and basics.
§ https://github.com/mbostock/d3/wiki/API-Reference • Official D3 documentation. Extremely well done.
§ https://github.com/mbostock/d3/wiki/Tutorials • List of seemingly ALL the tutorials online
§ The Google/StackOverflow combination • (my personal favorite)
1/23/14 Chad Stolper
CSE 6242 Guest Lecture 94