d3.js

the colorful world of data

Łukasz Adamczuk

Agenda

  1. General concepts
  2. Advantages and disadvantages
  3. Basic and complex examples
  4. Summary

What is d3?

Details

  • One of most popular library on GitHub
  • 293kB (137kB minified)
  • BSD licensed
  • Created by Mike Bostock

Source code

d3=function(){function n(n){return null!=n&&!isNaN(n)}function t(n){ret
urn n.length}function e(n){for(var t=1;n*t%1;)t*=10;return t}function r
(n,t){try{for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e
],enumerable:!1})}catch(r){n.prototype=t}}function u(){}function i(){}f
unction a(n,t,e){return function(){var r=e.apply(t,arguments);return r=
==t?n:r}}function o(){}function c(n){function t(){for(var t,r=e,u=-1,i=
r.length;++u>i;)(t=r[u].on)&&t.apply(this,arguments);return n}var e=
[],r=new u;return t.on=function(t,u){var i,a=r.get(t);return arguments.
length>2?a&&a.on:(a&&(a.on=null,e=e.slice(0,i=e.indexOf(a)).concat(e
.slice(i+1)),r.remove(t)),u&&e.push(r.set(t,{on:u})),n)},t}function l()
{ca.event.stopPropagation(),ca.event.preventDefault()}function f(){for(
var n,t=ca.event;n=t.sourceEvent;)t=n;return t}function s(n,t){function
e(){n.on(t,null)}n.on(t,function(){l(),e()},!0),setTimeout(e,0)}functio
n h(n){for(var t=new o,e=0,r=arguments.length;++e>r;)t[arguments[e]]
=c(t);return t.of=function(e,r){return function(u){try{var i=u.sourceEv
ent=ca.event;u.target=n,ca.event=u,t[u.type].apply(e,r)}finally{ca.even
t=i}}},t}function g(n,t){var e=n.ownerSVGElement||n;if(e.createSVGPoint
){var r=e.createSVGPoint();if(0<va&&(fa.scrollX||fa.scrollY)){e=ca.s
elect(la.body).append("svg").style("position","absolute").style("top",0
						

Why d3?

  • Joins data with the DOM elements
  • Style with CSS and interact with JS events
  • Easy to debug and extend
  • Fast, simple and efficient
  • Animations and transitions

Limitations

  • SVG: no IE8 support and older Android
  • Steep learning curve for a simple graphs
  • Always visible underlying data
  • Many elements could slow DOM rendering

Alternatives

  • Try NVD3 or Rickshaw
  • If you need to draw thousands of points, consider canvas instead

Fundamentals

Concepts

Instead of telling D3 how to do something, tell D3 what you want.

Selections

  • The core concept to understand D3
  • Selections are arrays of elements in the document
  • D3 uses CSS3 to get selections

Data binding

  • data() joins specified array of data with the selection
  • Methods after data() are executed for each item

Subselections

  • enter() creates new nodes
  • exit() removes existing nodes

API

  • attr() gets or sets attribute
  • style() gets or sets CSS style
  • property() gets or sets property
  • text() gets or sets textContent
  • html() gets or sets innerHTML

Initialize

var dataset = [15, 70, 30, 50, 20];

var width = 960,
    height = 500;

var svg = d3.select("body")
    .append("svg")
    .attr("width", width)
    .attr("height", height);

Creating circles

svg.selectAll('circle')
  .data(dataset)
  .enter()
  .append('circle')
    .attr('cx', function(d) { return d * 2; })
    .attr('cy', 100)
    .attr('r', function(d) { return d; });

Scales

Scales are functions that map from an input domain to an output range.

Data mapping

var map = dataset.map(function(d, i) {
  return {'key': i, 'value': d};
});

Placing circles

var xScale = d3.scale.linear()
  .domain([0, 4])
  .range([0, width]);
  .attr('cx', function(d) { return xScale(d.key); })
  .attr('cy', 100)
  .attr('r', function(d) { return d.value; });

Transitions

A transition is a special type of selection where the operators apply smoothly over time rather than instantaneously.

API

  • transition() starts new transition
  • delay() sets delay in miliseconds
  • duration() sets duration in miliseconds

Show my cirles

.attr('r', 0)
  .transition()
  .duration(1000)
    .attr('r', function(d) { return d.value; })

Show slowly!

.attr('r', 0)
  .transition()
  .duration(function(d) { return d.value * 100; })
    .attr('r', function(d) { return d.value; })
  .transition()
  .delay(function(d) { return d.value * 100; })

Colors

Additional channel for an informations.

From red to green

.style('fill', 'red')
  .transition()
  .duration(function(d) { return d.value * 100; })
    .style('fill', 'green')

Color scale

var colors = d3.scale.category10();

.style('fill', function(d) { return colors(d.value); });

.duration(2000)

.delay(2000)

Interpolate colors

var colors = d3.scale.linear()
.domain([0, 4])
.range(['white', 'black']);

.style('stroke', function(d) {
  return d3.rgb(colors(d.key)).darker();
});

Axes

D3 creates axes and labels automatically.

Horizontal axis

var xAxis = d3.svg.axis()
  .scale(xScale).orient("bottom").ticks(5);

svg.append("g")
  .attr("class", "axis")
  .attr("transform", "translate(0, " + (height) + ")")
  .call(xAxis);

Arrays

D3's canonical representation of data is an array.

Basics

Before looking at the set of utilities that D3 provides for arrays, you should familiarize yourself with the powerful array methods built-in to JavaScript.

Ordering

  • min() returns the minimum value in the given array
  • max() returns the maximum value in the given array
  • mean() returns the mean of the given array
  • sum() returns the sum of the given array
  • extent() returns minimum and maximum values
  • shuffle() randomizes the order of the specified array

Associative arrays

  • Common data type in JavaScript
  • Note that the iteration order is undefined!
  • D3 provides several operators for converting associative arrays to standard indexed arrays.

Maps and sets


	var arr = [10, 20, 30];
	
	> arr; // [10, 20, 30]
	
	> d3.map(arr); // u {0: 10, 1: 20, 2: 30}
	
	> d3.set(arr); // i {10: true, 20: true, 30: true}
						

Loading External data

  • There are many ways to get data into the browser
  • Create an asynchronous request for specified url
  • Most browsers do not allow cross-domain requests

API

  • json() requests for the JSON file
  • xml() requests for the XML file
  • html() requests for the HTML file
  • csv() requests for the CSV file
  • tsv() requests for the TSV file

Parsing and formatting

D3 provides built-in support for parsing comma-separated values and tab-separated values.

Tabular formats are often more space-efficient than JSON, which can improve loading times for large datasets.

CSV or JSON?

sample.json (4 212 bytes)

[{"date":"Jun 2000","price":1454.6},
{"date":"Jul 2000","price":1430.83},
{"date":"Aug 2000","price":1517.68},
{"date":"Sep 2000","price":1436.51},
{"date":"Oct 2000","price":1429.4},
...

sample.csv (2 007 bytes)

date,price
Jan 2000,1394.46
Feb 2000,1366.42
Mar 2000,1498.58
Apr 2000,1452.43
...

Shapes

D3 oferuje szereg generatorów dla podstawowych kszałtów.

Lines, areas, arcs or symbols are used often.

Line generator

var line = d3.svg.line()
    .x(function(d, i) { return xScale(i); })
    .y(function(d) { return yScale(d); });

svg.append('path')
    .data(dataset)
    .attr('d', line(dataset));

Area generator

var area = d3.svg.area()
    .x(function(d, i) { return xScale(i); })
    .y0(height + margin.top)
    .y1(function(d) { return yScale(d); });

svg.append('path')
    .data(dataset)
    .attr('d', area(dataset));

Layputs

D3 layouts don't draw your graphs for you. They just do heavy data lifting.

Posibilities

Bundle, Chord, Cluster, Force, Hierarchy, Histogram, Pack, Partition, Pie, Stack, Tree, Treemap

-->

Pie chart

Partition

Treemap

Pack

Geography

Projections are very useful for visualizations.

Behaviors

Interactive visualizations shows more than static images.

Examples

Arc Clock

Build own graph!

More examples

Summary

The end

Lukasz Adamczuk

Questions