Data Visualization for the Web with D3.js

Chafic Najjar

Front-End Developer

JavaScript, JavaScript Everywhere

What is D3?

  • D3 is a JavaScript library used to create dynamic and interactive visualizations in the browser.
  • 4th most starred repository on Github.
  • 2nd most starred open-source project on Github.
  • D3 4.0 was recently released. I use version 3.5 here.

What D3 is not

  • D3 is not a charting library like Google Charts or Chart.js.
  • D3 is not a library for interactive maps like Leaflet.
  • D3 is not a graphics layer. All the pretty graphics = SVG.

Most active members on the #general channel

This chart shows the number of messages per user for the last 100 messages on the #general channel of the MENA Devs Slack group (August 5, 2016).

Data source: MENA Devs Slack Data Collector

Legislators of Lebanon

Graph linking legislators in Lebanon to their corresponding political parties. A colored node represents a political party, with the radius being proportional to its number of members.

Data source: Lebanese Parliament API (nouwweb)

Syntax

D3 compared to jQuery

jQuery Logo jQuery Logo
jQuery

$('.chart')
    .addClass('active')
    .attr('data-type', 'foo')
    .css('background', 'black')
    .on('click', function() {})
    .append('<span></span>');
                                
D3

d3.selectAll('.chart')
    .classed('active', true)
    .attr('data-type', 'foo')
    .style('background', 'black')
    .on('click', function() {})
    .append('span');
                                
HTML

<div class='chart active' data-type='foo' style='background: black;'>
    <span></span>
</div>
                            
jQuery

$.getJSON('http://url-to-resource.json', function(data) {});
$.ajax({
    url: 'http://url-to-resource.txt',
    dataType: 'text',
    type: 'GET',
    success: function(data) {}
});
                            
D3

d3.json('http://url-to-resource.json', function(data) {});
d3.text('http://url-to-resource.txt', function(data) {});
                            

Examples

Example #1: Rectangle


var height = 60,
    width = 100,
    x = 50,
    y = 50;

d3.select('.svg-rect')
    .append('svg')
    .append('rect')
    .attr('fill', '#fc0')
    .attr('width', width)
    .attr('height', height)
    .attr('x', x)
    .attr('y', y);
                            

<div class='svg-rect'>
  <svg>
    <rect x='50' y='80' width='80' height='30' fill='#fc0'></rect>
  </svg>
</div>
                        

Example #2: Bar Chart


var height = 15, gap = 10;
var data = [2, 4, 5, 3, 9, 1, 2, 7, 8, 6, 5, 1, 8, 5];
var svg = d3.select('.bar-chart')
  .append('svg')
  .attr('height', height * data.length+1)

svg.selectAll('.bar')
  .data(data)
 .enter().append('rect')
  .attr('class', 'bar')
  .attr('fill', '#fc0')
  .attr('x', 20)
  .attr('y', function(d, i) { return i*(height+gap); })
  .attr('width', function(d) { return d*30; })
  .attr('height', height);
                        

Example #3: Map


d3.json("data/geodata.json", function(error, data) {
  var projection  = d3.geo.mercator().center([0, 50]).scale(120)
                      .rotate([-11, 0]).translate([960/2, 600/2]);
  var path        = d3.geo.path().projection(projection);
  var svg         = d3.selectAll('.map').append('svg')
                      .attr({ 'width': 960, 'height': 600 });

  svg.selectAll('.subunit')
    .data( topojson.feature(data, data.objects.subunits).features )
   .enter().append('path')
    .attr('d', path)
    .attr({ 'class': 'subunit', 'stroke': '#222', 'fill': '#fc0' })
    .on('mouseover', function() { d3.select(this).attr('fill', '#777'); })
    .on('mouseout', function() { d3.select(this).attr('fill', '#fc0'); });
});
                            
I have no idea what I'm doing

Algorithms

Radial Reingold–Tilford Tree

"The tree layout implements the Reingold-Tilford algorithm for efficient, tidy arrangement of layered nodes. The depth of nodes is computed by distance from the root, leading to a ragged appearance."

d3.layout.tree() + d3.svg.diagonal.radial()

Source: Radial Reingold–Tilford Tree

Sunburst Partition

"A sunburst is similar to the treemap, except it uses a radial layout. The root node of the tree is at the center, with leaves on the circumference. The area (or angle, depending on implementation) of each arc corresponds to its value."

d3.layout.partition() + d3.svg.arc()

Source: Sunburst Partition

Streamgraph

"For continuous data such as time series, a streamgraph can be used in place of stacked bars. This example also demonstrates path transitions to interpolate between different layouts."

d3.layout.stack() + d3.svg.area()

Source: Streamgraph

Why D3?

  1. Make interactive visualizations using web technologies you're already familiar with (HTML, CSS, SVG, JavaScript).
  2. Recruiters will think you're a JS rockstar/ninja/whatever.
  3. Unleash your creativity: make awesome visualizations.
Misleading pie chart during the Macworld 2008 keynote
Misleading pie chart during the Macworld 2008 keynote
(note: don't be evil like Steve Jobs)
شكراً

Questions?

Data Visualization for the Web with D3.js • MENA Devs Meetup #3 • Chafic Najjar / @ChaficNajjar