An Introduciton to D3.JS

Thomas Parslow

Hit space to advance slides and automatically run code
Most code blocks are live, edit and hit ▶ to run

Coming up

Most code blocks are live, edit and hit ▶ to run
Hit space to advance slides and automatically run code

What is D3.JS?

  • Data Driven Documents
  • JavaScript library for building interactive visualizations
  • Not a charting library, lower level than that

Why should you care?

  • You have data
  • The web is the place to show it
  • URLs are great
  • To have complete control you need to use JavaScript

Options for showing data

  • Python charting libraries (eg Matplotlib)
  • Python charting libraries that output HTML/JavaScript (eg Bokeh)
  • JavaScript charting libraries (eg Highcharts)
  • Custom JavaScript

A possible workflow

  • Scrape data with Scrapy
  • Clean data with Pandas
  • Explore your data with Matplotlib
  • Serve your data with Flask
  • Display your data with D3

What can D3 do?

nyti.ms/WhmfT7

nyti.ms/12UowUi

r2d3.us/visual-intro-to-machine-learning-part-1/

polygraph.cool/history/

almostobsolete.net/demos/ilo/

Many More D3 Examples at

d3js.org/

A tour of D3

A tour of D3

DOM Manipulation


<div class="hello">
  <p>Hi PyData</p>
</div>

<svg>
  <circle r="10" cx="100" cy="100" fill="red">
</svg> 

A tour of D3

Data Binding


[{"name": "Hydrogen", "atomic_number": 1},
 {"name": "Helium",   "atomic_number": 2},
 ...]
From data to corresponding elements

<ul>
  <li> Hydrogen <b>1</b> </li>
  <li> Helium <b>2</b> </li>
  ...
</ul>

A tour of D3

Transitions

A tour of D3

Scales

A tour of D3

Layouts

bl.ocks.org/mbostock/1021953

A tour of D3

Mapping

https://bl.ocks.org/mbostock/ba63c55dd2dbc3ab0127

A tour of D3

Utilities

  • Array utilties
  • String utilties
  • Time utiltiies
  • Reading in JSON, CSV or XML data
  • Lots more

Detour:

DOM: Document Object Model


<html>
  <body>
    <h1>Hello Paris</h1>
    <p>So nice to be here</p>
  </body>
</html>

Detour:

SVG: Scalable Vector Graphics

SVG: Scalable Vector Graphics


<svg width="300" height="250">
  <circle fill="blue" cx="200" cy="100" r="50"/>
</svg>

SVG: Scalable Vector Graphics


<svg width="300" height="250">
  <line stroke="green"
        stroke-width="4"
        x1="200"
        y1="100"
        x2="300"
        y2="200" />
</svg>

SVG: Scalable Vector Graphics


<svg width="300" height="250">
  <path stroke="purple"
        stroke-width="4"
        fill="none"
        d="M10 80 C 40 10, 65 10, 95 80 S 150 150, 180 80"/>
</svg>

SVG: Scalable Vector Graphics


<svg width="300" height="250">
  <circle fill="blue" cx="200" cy="100" r="50"/>
  <line stroke="green" stroke-width="4" x1="200" y1="100"
          x2="300" y2="200" />
  <path stroke="purple" stroke-width="4" fill="none"
          d="M10 80 C 40 10, 65 10, 95 80 S 150 150, 180 80"/>
  <circle fill="red" cx="180" cy="200" r="50"/>
</svg>

How to use D3

Hello D3

Hello D3


d3.select('#container')
  .append('div')
  .text('Hello world');

Selections

  • The core of D3 is selecting items in the DOM and changing/removing/adding them
  • Selections are what allow this using CSS selector syntax

Selections

d3.select('.myCircle').attr('r', 100);
d3.select('line').attr('stroke', 'pink');
d3.selectAll('circle').attr('fill', 'yellow');

Transitions

  • Make changes as before, but with smooth transitions

Transitions

d3.select('.myCircle')
  .transition().duration(1000)
  .attr('r', 100);
d3.selectAll('circle')
  .transition().duration(3000)
  .attr('fill', 'pink');

Data Binding

  • Bind data and DOM elements together

Data Binding


var data = [{myvalue: 20},{myvalue: 5},{myvalue: 40},{myvalue: 10}];
var selection = d3.select('.circles') .selectAll('circle') .data(data);
selection.attr('r', function (d,i) { return d.myvalue; });
window.selection = selection

selection.attr('fill', function (d,i) {
  return (i % 2) ? 'blue' : 'yellow';
})

selection.transition().duration(5000)
         .attr('cy', function (d,i) { return 40 + d.myvalue * 3; })

Enter and Exit Selections

  • We've seen how to bind data existing elements
  • But what about when we have more data then elements (or vice versa)
  • Enter selections allow us to create addtional elements
  • Exit selections allow us to remove superfluous elements
  • Both support transitions

Enter Selections

Without Enter Selections


var data = [10, 20, 40, 50];
var selection = d3.select('.circles') .selectAll('circle') .data(data);
selection.attr('r', function (d,i) { return d; });

Enter Selections


var data = [10, 20, 40, 50];
var selection = d3.select('.circles') .selectAll('circle') .data(data);
var enter = selection.enter();
window.enter = enter; window.selection = selection;

enter.append('circle')
  .attr('r', 5).attr('cy', 100).attr('fill', 'blue')
  .attr('cx', function (d,i) { return 50 + i * 60; });

selection.attr('r', function (d,i) { return d; });

No Existing Elements


var data = [10, 20, 40, 50];
var selection = d3.select('.circles') .selectAll('circle') .data(data);
var enter = selection.enter(); window.enter = enter; window.selection = selection;

enter.append('circle')
  .attr('r', 5).attr('cy', 100).attr('fill', 'blue')
  .attr('cx', function (d,i) { return 50 + i * 60;});

selection.attr('r', function (d,i) {return d; });

Exit Selections

Without Exit Selections


var data = [20, 30];
var selection = d3.select('.circles') .selectAll('circle') .data(data);
selection.attr('r', function (d,i) { return d; });

Exit Selections


var data = [20, 30];
var selection = d3.select('.circles') .selectAll('circle') .data(data);
var exit = selection.exit();
window.exit = exit; window.selection = selection;

exit.remove();

selection.attr('r', function (d,i) { return d; });

Exit Selection Transitions


var data = [20, 30];
var selection = d3.select('.circles') .selectAll('circle') .data(data);
var exit = selection.exit();
window.exit = exit; window.selection = selection;

exit.transition().duration(5000)
                 .attr('cy', -20)
                 .style('opacity', 0)
                 .remove();

The Update Pattern

  • A common pattern to create and update elements
  • Uses enter and exit selections
  • Plays nicely with transitions

The Update Pattern


window.update = function update(data) {
  var selection = d3.select('.circles')
                    .selectAll('circle')
                    .data(data);

  selection.enter().append('circle')
    .attr('fill', 'red').attr('cy', 150)
    .attr('cx', 0).attr('r', 0)

  selection.exit().transition().duration(2000).attr('r', 0)
    .remove();

  selection.transition().duration(2000)
    .attr('r', function (d) { return d; })
    .attr('cx', function (d,i) { return 50 + i * 60; }); 
} 

update([1, 1, 2, 3, 5, 8, 13]) 

update([1,15,30,45]) 

update([30,20,10,20,30]) 

update([]) 

Conclusion

  • Learn the update pattern, it's the core of D3
  • Look at examples at d3js.org and bl.ocks.org
  • New book coming out soon by Kyran Dale
Book Cover: Data Visualisation With Python & JavaScript

Thanks for listening!

Thomas Parslow