D3: The Crash Course
1
aka: D3: The Early Sticking Points aka: D3: Only the Beginning
Chad Stolper Google
(graduated from Georgia Tech CS PhD)
Chad Stolper CSE 4242 Guest Lecture
D3: The Crash Course aka: D3: The Early Sticking Points aka: D3: Only - - PowerPoint PPT Presentation
D3: The Crash Course aka: D3: The Early Sticking Points aka: D3: Only the Beginning Chad Stolper Google (graduated from Georgia Tech CS PhD) Chad Stolper CSE 4242 Guest Lecture 1 https://vimeo.com/29862153 Chad Stolper CSE 4242 Guest
D3: The Crash Course
1
aka: D3: The Early Sticking Points aka: D3: Only the Beginning
Chad Stolper Google
(graduated from Georgia Tech CS PhD)
Chad Stolper CSE 4242 Guest Lecture
https://vimeo.com/29862153
Chad Stolper CSE 4242 Guest Lecture 2
3
https://vimeo.com/276140430
Chad Stolper CSE 4242 Guest Lecture
http://www.bloomberg.com/graphics/2015-auto-sales/
Chad Stolper CSE 4242 Guest Lecture 4
Why should you learn D3???
Chad Stolper CSE 4242 Guest Lecture 5
If you visualization/system/tool will benefit from interactivity. Otherwise, use anything you want
(e.g., tableau, excel, python:seaborn, R:ggplot2, etc.)
Chad Stolper CSE 4242 Guest Lecture 6
More online discussion: https://news.ycombinator.com/item?id=11995332
Chad Stolper CSE 4242 Guest Lecture 7
This lecture is about D3 v3
https://keithpblog.wordpress.com/2016/07/31/upgrading-d3-from-v3-to-v4/
Chad Stolper CSE 4242 Guest Lecture 8
Chrome Inspector and Console
error messages
Chad Stolper CSE 4242 Guest Lecture 9
Starting a Local Web Server
Necessary for Chrome, not for Safari or Firefox
(This is a security measure: to prevent reading from your file systems)
python -m SimpleHTTPServer 8000
python –m http.server 8000
Chad Stolper CSE 4242 Guest Lecture 10
https://github.com/d3/d3/wiki
If you’re new to JavaScript…
Chad Stolper CSE 4242 Guest Lecture 11
prepare for a lot of… confusion (wat??) and hair pulling I’m serious.
https://siouxfallsradioadvertisingdotcom.files.wordpress.com/2011/11/mad-man-pulling-hair-out.jpgIf you’re new to Javascript…
https://www.destroyallsoftware.com/talks/wat (starting 1:20)
Chad Stolper CSE 4242 Guest Lecture 12
Javascript 101
using var
x = 300 (global) var x = 300 (local)
same syntax as python’s lists [ ] and dicts { }
Chad Stolper CSE 4242 Guest Lecture 13
Javascript 102: Functional Programming
Functions are themselves objects Functions can be stored as variables Functions can be passed as parameters
Chad Stolper CSE 4242 Guest Lecture 14
Some people say javascript is a “multi-paradigm” programming language. http://stackoverflow.com/questions/3962604/is-javascript-a-functional- programming-language
What does that mean?
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map Chad Stolper CSE 4242 Guest Lecture 15
Passing Math.sqrt (a function) as a parameter
MDN – the BEST Javascript reference
US/docs/Web/JavaScript/Reference
Chad Stolper CSE 4242 Guest Lecture 17
Method Chaining
method returns the object that it was called on
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
Chad Stolper CSE 4242 Guest Lecture 18
SVG SVG BAS BASICS ICS
SVG = Scalable Vector Graphics
Chad Stolper CSE 4242 Guest Lecture 19 https://en.wikipedia.org/wiki/Scalable_Vector_Graphics
x y
(0,0)
http://smg.photobucket.com/user/Pavan2099/m edia/RvB/Descart-weeping.png.htmlChad Stolper CSE 4242 Guest Lecture 21
SVG Basics
SVG -> XML Vector Graphics (Scalable Vector Graphics)
Chad Stolper CSE 4242 Guest Lecture 22
SVG Basics
Tags with Attributes
<circle r=5 fill="green"></circle>
http://www.w3.org/TR/SVG/
Chad Stolper CSE 4242 Guest Lecture 23
SVG Basics
<path>
Chad Stolper CSE 4242 Guest Lecture 25
<svg> element
width height
d3.select("#vis").append("svg")
<body> <div id="vis"> <svg></svg> </div> </body>
Chad Stolper CSE 4242 Guest Lecture 27
<circle> element
cx (relative to the LEFT of the container) cy (relative to the TOP of the container) r (radius)
fill (color) stroke (the color of the stroke) stroke-width (the width of the stroke)
.append(“circle”)
Chad Stolper CSE 4242 Guest Lecture 28
<rect> element
x (relative to the LEFT of the container) y (relative to the TOP of the container) width (cannot be negative) height (cannot be negative)
fill (color) stroke (the color of the stroke) stroke-width (the width of the stroke)
.append(“rect”)
Chad Stolper CSE 4242 Guest Lecture 29
x y width height (0,0)
Chad Stolper CSE 4242 Guest Lecture 30
Rather than positioning each element, what if we want to position (or style) a group of elements?
Chad Stolper CSE 4242 Guest Lecture 31
<g> element
transform (fill,stroke,etc.)
var group = vis.append(“g”)
group.append(“circle”) group.append(“rect”) group.append(“text”)
Chad Stolper CSE 4242 Guest Lecture 32
CSS Selectors Reference
Chad Stolper CSE 4242 Guest Lecture 33
http://www.w3schools.com/cssref/css_selectors.asp
AND
circle.canary <circle class=“canary”>
OR
circle, .canary <circle> <circle class=“canary”> <tag class=“canary”>
AND NOW D3…
Chad Stolper CSE 4242 Guest Lecture 34
Mike Bostock and Jeff Heer @ Stanford 2009- Protovis
Chad Stolper CSE 4242 Guest Lecture 35
Mike Bostock and Jeff Heer @ Stanford 2009- Protovis
Chad Stolper CSE 4242 Guest Lecture 36
Mike Bostock and Jeff Heer @ Stanford 2009- Protovis 2011- D3.js
Chad Stolper CSE 4242 Guest Lecture 37
Mike Bostock and Jeff Heer @ Stanford 2009- Protovis 2011- D3.js
Chad Stolper CSE 4242 Guest Lecture 38
Mike Bostock and Jeff Heer @ Stanford 2009- Protovis 2011- D3.js
New York Times
Chad Stolper CSE 4242 Guest Lecture 39
D3
Chad Stolper CSE 4242 Guest Lecture 40
D3.js in a Nutshell
D3 is a really powerful for-loop with a ton of useful helper functions
Chad Stolper CSE 4242 Guest Lecture 41
D3
Declarative, domain-specific specification language for manipulating the DOM
Define a template for each type of element D3 draws one element for each data point
Chad Stolper CSE 4242 Guest Lecture 42
Importing D3
<html > <head> <script src='lib/d3.js’ charset=‘utf-8’></script> <script src='js/project.js'></script> </head> <body> <div id=“vis”></div> </body> </html>
Chad Stolper CSE 4242 Guest Lecture 43
Importing D3
<html > <head> <script src='lib/d3.js’ charset=‘utf-8’></script> <script src='js/project.js'></script> </head> <body> <div id=“vis”></div> </body> </html>
Chad Stolper CSE 4242 Guest Lecture 44
Importing D3
<html > <head> <script src='lib/d3.js’ charset=‘utf-8’></script> <script src='js/project.js'></script> </head> <body> <div id=“vis”></div> </body> </html>
Chad Stolper CSE 4242 Guest Lecture 45
Importing D3
<html > <head> <script src='lib/d3.js’ charset=‘utf-8’></script> <script src='js/project.js'></script> </head> <body> <div id=“vis”></div> </body> </html>
Chad Stolper CSE 4242 Guest Lecture 46
Assigning the Canvas to a Variable var vis = d3.select(“#vis”) .append(“svg”)
Chad Stolper CSE 4242 Guest Lecture 47
<body> <div id=“vis”><svg></svg></div> </body>
Loading Data
“data/datafile.csv”
Chad Stolper CSE 4242 Guest Lecture 48
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’ } ]
Chad Stolper CSE 4242 Guest Lecture 49
Problem
for(var d: data){
d = data[d] d.age = +d.age
}
[ { ‘name’: ‘Adam’, ‘school’: ‘GT’, ‘age’: ‘18’ }, { ‘name’: ‘Barbara’, ‘school’: ‘Emory’, ‘age’: ‘22’ }, { ‘name’: ‘Calvin’, ‘school’: ‘GSU’, ‘age’: ‘30’ } ]
Chad Stolper CSE 4242 Guest Lecture 50
Problem
for(var d: data){
d = data[d] d.age = +d.age
}
[ { ‘name’: ‘Adam’, ‘school’: ‘GT’, ‘age’: ‘18’ }, { ‘name’: ‘Barbara’, ‘school’: ‘Emory’, ‘age’: ‘22’ }, { ‘name’: ‘Calvin’, ‘school’: ‘GSU’, ‘age’: ‘30’ } ]
Chad Stolper CSE 4242 Guest Lecture 51 http://stackoverflow.com/questions/24473733/importing-a-csv-into-d3-cant-convert-strings-to-numbers
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 } ]
Chad Stolper CSE 4242 Guest Lecture 52
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 } ]
Ok, so let’s map this data to visual elements!
Chad Stolper CSE 4242 Guest Lecture 53
D3
Declarative, domain-specific specification language for manipulating the DOM
Define a template for each element D3 draws one element for each data point
Chad Stolper CSE 4242 Guest Lecture 56
Enter-Update-Exit
remember this...
Chad Stolper CSE 4242 Guest Lecture 57
Enter-Update-Exit
Pattern:
associated with any elements yet (and set constant or initial attribute values)
the data
Chad Stolper CSE 4242 Guest Lecture 58
.enter( ) and .exit( )
Enter: [1,2,3,4] Update: [1,2,3,4] Exit: [ ]
Enter: [5,6] Update: [1,2,3,4,5,6] Exit: [ ]
Enter: [ ] Update: ??? Exit: [4,5,6] New Data Old Elements Enter Exit Update
Chad Stolper CSE 4242 Guest Lecture 59
.enter( ) and .exit( )
Enter: [1,2,3,4] Update: [1,2,3,4] Exit: [ ]
Enter: [5,6] Update: [1,2,3,4,5,6] Exit: [ ]
Enter: [ ] Update: [1,2,3,4,5,6] Exit: [4,5,6] New Data Old Elements Enter Exit Update
Chad Stolper CSE 4242 Guest Lecture 60
.enter( ) and .exit( )
New data points
Elements to be removed
has been called
New Data Old Elements Enter Exit Update
Chad Stolper CSE 4242 Guest Lecture 61
Can be hard to grok: You can select groups of elements that DON’T EXIST YET
http://bost.ocks.org/mike/join/
Chad Stolper CSE 4242 Guest Lecture 62
Still confused?
Chad Stolper CSE 4242 Guest Lecture 63
Excellent interactive demo to explain enter-update-exit:
https://rawgit.com/niceone/d3-introduction/master/index.html
Full tutorial:
https://medium.com/@c_behrens/enter-update-exit-6cafc6014c36#.dqwkermdb
Data Key Functions
index of the point is the key
set a key functions
.data(rawdata, function(d,i){ return d.id; }) .data(rawdata, function(d,i){ return d.name; })
Chad Stolper CSE 4242 Guest Lecture 64
E-U-E Pattern Template
var group = vis.selectAll(“rect”) .data(rawdata) //rawdata must be an array! group.enter( ).append(“rect”) //ENTER! .attr( ) .style( ) group //UPDATE! .attr( ) .style( ) group.exit( ).remove( ) //EXIT!
Chad Stolper CSE 4242 Guest Lecture 65
Chad Stolper CSE 4242 Guest Lecture 66
E-U-E Pattern Template
var group = vis.selectAll(“rect”) .data(rawdata) //rawdata must be an array! group.enter( ).append(“rect”) //ENTER! .attr( ) .style( ) group //UPDATE! .attr( ) .style( ) group.exit( ).remove( ) //EXIT!
Many online examples
Chad Stolper CSE 4242 Guest Lecture 67
E-U-E Pattern Template
var group = vis.selectAll(“rect”) .data(rawdata) //rawdata must be an array! group.enter( ).append(“rect”) //ENTER! .attr( ) .style( ) group //UPDATE! .attr( ) .style( ) group.exit( ).remove( ) //EXIT!
Many online examples drop the variable name before .enter()
Chad Stolper CSE 4242 Guest Lecture 68
E-U-E Pattern Template
var group = vis.selectAll(“rect”) .data(rawdata) //rawdata must be an array! group.enter( ).append(“rect”) //ENTER! .attr( ) .style( ) group //UPDATE! .attr( ) .style( ) group.exit( ).remove( ) //EXIT!
Many online examples drop the variable name before .enter() I highly recommend you don’t!
Chad Stolper CSE 4242 Guest Lecture 69
.attr( )
and fill
group.attr(“x”, 5) <rect x=“5”></rect>
Chad Stolper CSE 4242 Guest Lecture 70
.attr( ) and Functional Programming Input
[ {size: 10}, {size: 8}, {size: 12.2} ]
We want 3 rectangles:
<rect height=“10” x=“5”></rect> <rect height=“8” x=“10”></rect> <rect height=“12.2” x=“15”></rect>
.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
Chad Stolper CSE 4242 Guest Lecture 71
<text> elements
the lousy job the W3C did with the <text> definition.
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.
Chad Stolper CSE 4242 Guest Lecture 72
<text> elements
.text(“Your Text Goes Here”) <tag>Your Text Goes Here</tag>
x y
text-anchor: start, middle, end dominant-baseline: [nothing], hanging, middle
Chad Stolper CSE 4242 Guest Lecture 73
text-anchor style
start end middle
Where is (0,0)?
Chad Stolper CSE 4242 Guest Lecture 74
dominant-baseline style
This is my line of text.
hanging default middle
Where is (0,0)?
Chad Stolper CSE 4242 Guest Lecture 75
<text> example
Chad Stolper CSE 4242 Guest Lecture 76
http://tutorials.jenkov.com/svg/text-element.html
The .style() Function
Like attr, but for the style attribute
.style(“prop1”,“val1”) .style(“prop2”,“val2”) .style(“prop3”, function(d,i){ }) <ele style=“prop1: val1; prop2: val2;”>
Chad Stolper CSE 4242 Guest Lecture 77
<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”)
Chad Stolper CSE 4242 Guest Lecture 78
Need to remember what to use .style and when to use .attr
What if you have two different types of circles?
Chad Stolper CSE 4242 Guest Lecture 79
Classing
Chad Stolper CSE 4242 Guest Lecture 80
Any number of classes per element Select using “.classname”
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”)
(e.g., sizing a circle based on data value)
Chad Stolper CSE 4242 Guest Lecture 81
.attr(“height”, function(d){ return d; }) can blow up really quickly…
Chad Stolper CSE 4242 Guest Lecture 82
Scales
Linear Scales Ordinal Scales
Chad Stolper CSE 4242 Guest Lecture 83
Linear Scales
var xscale = d3.scale.linear( ) .domain( [min, max] ) .range( [minOut, maxOut] ) group.attr(“x”, function(d,i){ return xscale(d.size); })
Chad Stolper CSE 4242 Guest Lecture 84
Min and Max
But how do you figure out the min and max for the domain?
Chad Stolper CSE 4242 Guest Lecture 85
D3
A really powerful for-loop with a ton of useful helper functions
Chad Stolper CSE 4242 Guest Lecture 86
Min and Max
Chad Stolper CSE 4242 Guest Lecture 87
Domain & Range
Chad Stolper CSE 4242 Guest Lecture 88
http://image.slidesharecdn.com/d3-140708145630-phpapp02/95/d3-17-638.jpg?cb=1404831405
An optional accessor function may be specified, which is equivalent to calling array.map(accessor) before computing the maximum value. d3.max( data.map( function(d){ return d.age; }) ) // returns the maximum age
Chad Stolper CSE 4242 Guest Lecture 89
https://github.com/d3/d3-3.x-api-reference/blob/master/Arrays.md
var maxAge = d3.max( data.map( function(d){ return d.age; }) ) // returns the maximum age var yscale = d3.scale.linear( ) .domain( [0, maxAge] ) .range( [0, 100] )
Chad Stolper CSE 4242 Guest Lecture 90
Linear Scales
just update the domain and/or range as necessary
all on its own
Chad Stolper CSE 4242 Guest Lecture 91
Ordinal Scales
(And they’re easy!)
category20( ) category20b( ) category20c( ) (and even a few more)
Chad Stolper CSE 4242 Guest Lecture 92
Ordinal Categorical Scales
(And they’re easy!)
category20( ) category20b( ) category20c( ) (and even a few more)
Chad Stolper CSE 4242 Guest Lecture 93
Think carefully before using a rainbow palette for ordinal data!
http://www.mathworks.com/tagteam/81137_92 238v00_RainbowColorMap_57312.pdf
Ordinal Categorical Scales
Chad Stolper CSE 4242 Guest Lecture 94
return colorscale(d.type) }
Bird Rodent
D3 also has visual helper-functions
Chad Stolper CSE 4242 Guest Lecture 95
Axes
Chad Stolper CSE 4242 Guest Lecture 96
yaxisglyph = vis.append("g") yaxis = d3.svg.axis( ) .scale( yscale ) // must be a numerical scale .orient( 'left' ) // or 'right', 'top', or 'bottom' .ticks( 6 ) // number of ticks, default is 10 yaxisglyph.call(yaxis)
What if the data is changing?
Chad Stolper CSE 4242 Guest Lecture 98
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! }
Chad Stolper CSE 4242 Guest Lecture 100
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! }
Chad Stolper CSE 4242 Guest Lecture 101
Transitions
Chad Stolper CSE 4242 Guest Lecture 102
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) //can be a function of data .style(“fill”,”green”) //can be a function of data
Chad Stolper CSE 4242 Guest Lecture 103
So transitions allow a vis to be dynamic… But they’re not really interactive…
Chad Stolper CSE 4242 Guest Lecture 104
Interaction
The on( ) Method
Chad Stolper CSE 4242 Guest Lecture 105
.on( )
rect.on (“click”, function(d){
d.color = “blue”; redraw( rawdata )
}) HTML Events
click mouseover mouseenter mouseout etc. d is the data point backing the element clicked on
Chad Stolper CSE 4242 Guest Lecture 107
Where to get learn more…
Tons of examples and basics.
Reference
Official D3 documentation. Extremely well done.
List of seemingly ALL the tutorials online
(my personal favorite)
Chad Stolper CSE 4242 Guest Lecture 108