JavaScript
var data1 = [
{ 'name': 'LHR', 'position': 1, 'flights': [1,10,12,14,3] },
{ 'name': 'LAX', 'position': 2, 'flights': [3,6,12,6,3] },
{ 'name': 'SFO', 'position': 3, 'flights': [2,8,17,18,5] }
];
var data2 = [
{ 'name': 'CDG', 'position': 1, 'flights': [4,5,11,9,1] },
{ 'name': 'LHR', 'position': 2, 'flights': [2,9,11,12,5] },
{ 'name': 'SFO', 'position': 3, 'flights': [4,5,6,9,5] }
];
var h = 500;
var vis = d3.select("#viz").append("svg").attr("width", 300).attr("height", 500);
function update(data) {
console.log('update', data);
var g = vis.selectAll("g.airport").data(data, function(d) {
return d.name;
});
// Add new group elements to the enter selection.
var gEnter = g.enter().append("g")
.attr("class", function(d) {
return "airport " + d.name;
});
// Update the position of existing legends.
g.selectAll("text.legend")
.transition().duration(1000)
.attr("y", function(d,i, j) { return j * 20 + 20; });
// Append new legends to elements in the enter selection.
gEnter.append("text").attr("class", function(d) {
return d.name + ' legend';
})
.attr("x", 250)
.attr("y", 0)
.attr("dy", ".2em").text(function(d, i) {
return d.name;
})
.transition().duration(1000)
.attr("y", function(d,i) { return i * 20 + 20; });
// Bind data to existing circles.
var circle = g.selectAll("circle.flight")
.data(function(d, i) { return d.flights; });
// Transition circles in the update selection.
circle.transition().duration(1000)
.attr("cy", function(d,i) { return d*2 + 10 })
.attr("r", "3");
// Position circles in the enter selection.
circle.enter().append("circle").attr("class", 'flight')
.attr("cx", function(d,i) { return i * 20 + 20; })
.attr("cy", 0)
.attr("r", "3")
.transition().duration(1000)
.attr("cy", function(d,i) { return d*2 + 10 });
// Remove exited elements.
g.exit().transition()
...