But first, let's discuss
principles
2. Be honest
The Lie factor
3. Don't make me think
Importing data
var data; // a global
d3.csv('path/to/file.csv', function(error, json) {
if (error) {
return console.warn(error);
}
data = json;
visualizeit();
});
Works for JSON, CSV, TSV, XML, HTML, text, etc.
See github.com/mbostock/d3/wiki/Requests
Format data before use
var rawData = [
{n: 'bunnies', c: 1},
{n: 'kittens', c: 2},
{n: 'puppies', c: 2},
{n: 'cows', c: 0}
];
var formattedData = data.map(function (d){
return {
name: d.n.toUpperCase() + '!!!',
cuteness: ['Not very cute', 'Cute', 'Very cute!!!'][d.c]
};
});
Selections
d3.select('ul').selectAll("li")
d3.select('ul')
.selectAll('li')
.data(['foo','bar','baz'])
.enter()
.append('li')
.text(function (d) {
return d;
});
↓
Exit, Enter, update
var rect = svg.selectAll('rect')
.data(data);
rect.exit()
.remove();
rect.enter()
.append('rect')
.attr('y', function(d) { return d.y; });
rect.attr('width', function(d) { return d.width; });
Transitions
d3.selectAll('rect')
.data(randomData)
.enter()
.append('rect')
.attr('width',0)
.transition()
.duration(600)
.delay(function (d,i){ return i * 200;})
.attr('width', function (d){ return x(d);});
Scales
are functions that map from an input domain to an output range
Input: Domain!
Output: Range!
Quantitative
var x = d3.scale.linear()
.domain([12, 24])
.range([0, 720]);
x(16); // 240
Ordinal
var x = d3.scale.ordinal()
.domain(['A', 'B', 'C', 'D'])
.range([0, 10, 20, 30]);
x('B'); // 10
Maps!
GeoJSON & TopoJSON
See Mike Bostock's Let's Make a Map
Use the force, Luke!
See mbostock.github.io/d3/talk/20110921
Making it responsive