11 THINGS YOU

DIDN'T KNOW

ABOUT D3


LondonJS, 21/10/13
Slides: http://anna.ps/talks/londonjs

HELLO!

I'm a freelance web developer

Anna Powell-Smith
http://anna.ps
@darkgreener

11 THINGS I DIDN"T KNOW ABOUT d3...


...until I sat down and read the entire API docs

Photo by river2sea on Flickr

WHAT IS D3?


  • JavaScript library for data visualisation
  • One JavaScript file, 145KB minified, BSD licensed
  • Launched late 2010, now the 6th most-starred library on GitHub
  • Used in production by New York Times, GitHub, Square...

SHOWREEL

Source: Mike Bostock (click to start)

WHERE DID D3 COME FROM?


2005: Prefuse (Java, Heer, Berkeley)
|
2007: Flare (ActionScript, Heer, Berkeley)
|
2009: Protovis (JavaScript, Heer/Bostock, Stanford)
|
2011: D3 (JavaScript, Heer/Bostock, Stanford)

TLDR: very smart people thought very hard
about visualisation for a very long time

BEFORE d3

var data = google.visualization.arrayToDataTable([
  ['Year', 'Sales', 'Expenses'],
  ['2004',  1000,      400],
  ['2005',  1170,      460] ...
]);

var options = {
  title: 'Company Performance',
  vAxis: {title: 'Year',  titleTextStyle: {color: 'red'}}
};

var chart = new google.visualization.BarChart
  (document.getElementById('chart_div'));
chart.draw(data, options);

BEFORE d3

WITH D3

var dataset = [ 5, 10, 13, 19, 21, 25, ...];
var rectangles = 
    d3.select("svg").selectAll("rect").data(dataset)
rectangles.enter().append("rect")
 .attr("width", 24)
 .attr("height", function(d) {
    return d * 4;
  })
  .attr("y", function(d) {
    return 600 - (d * 4);
  })
  .attr("x", function(d, i) {
    return i * (300 / dataset.length);
  });

WITH D3

WITH D3: FULL CONTROL

rectangles.attr("fill", function(d) {
  return "rgb(0, 0, " + (d * 10) + ")";
});
			

WITH D3: Transitions

d3.select("body").on("click", function() {
    
  svg.selectAll("rect")
   .data(new_data)
   .transition()
   .duration(2000)
   .attr("y", function(d) {
     return h - (d*4);
   })
   .attr("height", function(d) {
     return d*4;
    })
    .attr("fill", function(d) {
     return "rgb(0, 0, " + (d * 10) + ")";
    });
});

WITH D3: Transitions

THIS CHANGES EVERYTHING

Source: Mike Bostock's streamgraph example
(click on the button to load new data)

OMG PARTICLES

Source: Mike Bostock's OMG Particles (try mousing over)

MAPS

Source: Mike Bostock's Chloropleth Map
(GeoJSON boundaries and CSV data)

GETTING STARTED


Scott Murray's O'Reilly book


Most tutorials cover: 

  • binding data (selections)
  • drawing elements (selections)
  • scales
  • transitions
  • layouts

D3 VISUALISED IN D3

Source: bl.ocks.org/annapowellsmith showing the D3 docs

1. SHOW XHR LOADING PROGRESS (PAINLESSLY)

d3.json("file.json")
  .on("progress", 
  function() {
  // some awesome d3 stuff
});

1. SHOW XHR LOADING PROGRESS (PAINLESSLY)

Source: Mike Bostock

2. PARSE DELIMITER-SEPARATED FILES
(ON THE FLY)


Year||Make||Model||Length
1997||Ford||E350||2.34
2000||Mercury||Cougar||2.38
var dsv = d3.dsv("||", "text/plain");
dsv('data.dsv', function(d) {
 d.Length = +d.Length; 
}, function(data) {
 // Use our data
};
And it's super-efficient

3. GROUP BY IN JAVASCRIPT

Year||Make||Model||Length
1997||Ford||E350||2.34
2000||Audi||A3||2.38
1997||Citroen||D5||2.40
var nest = d3.nest()
  .key(function(d) { return d.Year; })
  .entries(data);
[{key: 1997, values: [
  {Year: 1997, Make: "Ford", Model: "E350", Length: 2.34},
  {Year: 1997, Make: "Citroen", Model: "C5", Length: 2.40}
]},
{key: 2000, values: [
  {Year: 2000, Make: "Audi", Model: "A3", Length: 2.38}
]}}]

4. BETTER JAVASCRIPT OBJECTS

JavaScript objects can be problematic:
var myObj = {};	
("hasOwnProperty" in myObj);

ES6 has maps - you can use them already in D3:
var myObj = d3.map({});
(myObj.has("hasOwnProperty"));

5. BETTER JAVASCRIPT TIMERS

Source: Jason Davies, Animated Bezier Curves

5. BETTER JAVASCRIPT TIMERS

Automatically uses requestAnimationFrame if available
d3.timer(function, [delay, [time]])
Set a time and a delay
Pauses when window/tab not in focus

6. EFFICIENT MATRIX DECOMPOSITION

CSS3 transforms and matrix decomposition: Mike Bostock

7. PERCEPTUAL COLOUR CALCUATIONS


Source: Mike Bostock

7. PERCEPTUAL COLOUR CALCULATIONS


var lighter = d3.lab("steelblue").brighter();
var darker = d3.lab("steelblue").darker();

8. AWESOME TIME CALCULATIONS

Like Python's datetime module, in JavaScript

var start = new Date('2 May 1980');
Format dates
var format = d3.time.format("%A,%e %B %Y");
format(start);
How many Mondays have I been alive for?
d3.time.mondays(start, new Date());

8. AWESOME TIME CALCULATIONS


var death = new Date('2 May 2062');
How far am I through life (probably)?
var life = d3.time.scale().domain([start, death]).range([0,100]);
life(new Date());

9. D3 for BETTER MAP PROJECTIONS

Source: Mike Bostock

9. D3 for BETTER MAP PROJECTIONS


Doesn't show distances correctly at the edges, can't see US
Source: BBC news

9. D3 for better Map projections


Azimuthal equidistant - correct distances & both hemispheres
Source: Jason Davies, Distances from North Korea

9. D3 for BETTER MAP PROJECTIONS

Find a ship that is lost at sea!
Source: Two-Point Azimuthal, Jason Davies

10. D3 for MASSIVE TABLES

(anyone used SlickGrid, dataTables...?)

Source: bl.ocks.org/jasondavies

10. D3 for TABLES - Transitions

Source: New York Times

11. D3 for UX

Source: Michael Bauer / OKFN Labs

11. D3 for UX

Source: Mike Bostock

USING D3 with NODE


$  npm install -g d3
$  node

> var d3 = require('d3');
> d3.version;
'3.3.8'

WORKING WITH THE SOURCE

Journey to the Source

D3 custom builds


Use Mike Bostock's smash for custom builds:
$ npm install smash
$ cd d3/

Find the section that you want, and build:
$ smash src/start.js src/layout/treemap.js src/end.js 
  > d3.treemap.js

INSPIRATION

Mike Bostock's bl.ocks.org

THANKS FOR LISTENING