Created
September 12, 2013 15:52
-
-
Save jgoodall/6539804 to your computer and use it in GitHub Desktop.
intro to d3: scatterplot with transitions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<style> | |
.circle { | |
fill: steelblue; | |
stroke: '#fff'; | |
} | |
.label { | |
fill: #777; | |
} | |
</style> | |
<body> | |
<script src="http://d3js.org/d3.v3.min.js"></script> | |
<script> | |
var width = 400 | |
, height = 400 | |
, margin = {top: 25, right: 50, bottom: 40, left: 50} | |
, uid = 0 | |
, datasetSize = 10; | |
// [0] is uid | |
// [1] will be plotted on the x axis | |
// [2] will be plotted on the y axis | |
// [3] will be used as the radius | |
var dataset = []; | |
for (var i = 0 ; i < datasetSize ; i++) { | |
dataset.push(generateDatum()); | |
} | |
// set up the scales | |
var xScale = d3.scale.linear() | |
.range([0, width]) | |
.domain([0, 100]) | |
.nice(); | |
var yScale = d3.scale.linear() | |
.range([height, 0]) | |
.domain([0, 100]) | |
.nice(); | |
// set the axes | |
var xAxis = d3.svg.axis() | |
.scale(xScale) | |
.orient('bottom') | |
.outerTickSize(1); | |
var yAxis = d3.svg.axis() | |
.scale(yScale) | |
.orient('left') | |
.outerTickSize(1); | |
// append the svg to the body of the page and set the width and height | |
// append a 'g' element to group the circles together and 'translate' | |
var svg = d3.select("body").append("svg") | |
.attr("width", width + margin.left + margin.right) | |
.attr("height", height + margin.top + margin.bottom) | |
.append("g") | |
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | |
// draw the axes | |
var svgXaxis = svg.append('g') | |
.attr({ | |
'class': 'axis label' | |
, 'transform': 'translate(0,' + height + ')' | |
}) | |
.call(xAxis); | |
svgXaxis.append('text') | |
.attr({ | |
'class': 'label' | |
, 'x': width / 2 | |
, 'y': margin.bottom - 4 | |
, 'text-anchor': 'middle' | |
}) | |
.text('first set of numbers'); | |
// draw Y axis | |
var svgYaxis = svg.append('g') | |
.attr({ | |
'class': 'axis label' | |
}) | |
.call(yAxis); | |
svgYaxis.append('text') | |
.attr({ | |
'class': 'label' | |
, 'transform': 'translate(-290,320)rotate(-90)' | |
, 'x': margin.left | |
, 'y': height / 2 | |
, 'text-anchor': 'middle' | |
}) | |
.text('more numbers'); | |
// draw initial display | |
update(); | |
// add new data | |
var count = 0; | |
var interval = setInterval(function() { | |
// remove a datum on odd loops | |
if (count % 2 === 1) { | |
var indexToRemove = parseInt((Math.random() * dataset.length)); | |
console.log('Removing point ' + indexToRemove + ': ' + dataset[indexToRemove]); | |
dataset.splice(indexToRemove, 1) | |
} | |
// add a new datum | |
var d = generateDatum(); | |
console.log('Adding new point ' + d); | |
dataset.push(d); | |
update(); | |
count++; | |
if (count >= 50) { | |
clearInterval(interval); | |
console.log('Added ' + count + ' points. Done.'); | |
} | |
}, 1200); | |
function update () { | |
// update the scales' domain | |
xScale.domain([0, d3.max(dataset, function(d) { return d[1]; })]); | |
yScale.domain([0, d3.max(dataset, function(d) { return d[2]; })]); | |
// data-join | |
var dot = svg.selectAll("circle") | |
.data(dataset, function(d) {return d[0]}); | |
// udpate | |
dot.transition() | |
.duration(750) | |
.attr({ | |
"cx": function(d) { return xScale(d[1]); } | |
, "cy": function(d) { return yScale(d[2]); } | |
, "r": function(d) { return d[3] / 2; } | |
}); | |
// enter | |
dot.enter().append("circle") | |
.attr({ | |
"class": "circle" | |
, "cx": function(d) { return xScale(d[1]); } | |
, "cy": function(d) { return yScale(d[2]); } | |
, "r": function(d) { return d[3] / 2; } | |
}) | |
.style('opacity', 1e-6) | |
.transition() | |
.style('fill', 'green') | |
.style('opacity', 1) | |
.transition() | |
.duration(700) | |
.style('fill', null); | |
dot.exit().transition() | |
.style('fill', 'red') | |
.transition() | |
.duration(700) | |
.style('opacity', 1e-6) | |
.remove(); | |
// update axes | |
svgXaxis.transition() | |
.call(xAxis); | |
svgYaxis.transition() | |
.call(yAxis); | |
} | |
function generateDatum () { | |
return [ | |
uid++ | |
, parseInt(Math.random() * 400) | |
, parseInt(Math.random() * 400) | |
, parseInt((Math.random() * 10) + 10) | |
]; | |
} | |
</script> | |
</body> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment