Skip to content

Instantly share code, notes, and snippets.

@jstcki
Last active August 29, 2015 13:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jstcki/9205238 to your computer and use it in GitHub Desktop.
Save jstcki/9205238 to your computer and use it in GitHub Desktop.
Transitions with D3

Avoid restarting running transitions by either starting one just on the .enter() selection or by using selection.filter() to only select elements which are not in transit yet.

Alternative implementations combining D3 with React and React TransitionGroup.

<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
background: #fff;
}
.item {
fill: none;
stroke-width: 1.5;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
var width = 960,
height = 500,
data = [];
var x = d3.scale.linear()
.domain([0, 1])
.range([0, width]);
var y = d3.scale.linear()
.domain([0, 1])
.range([150, height - 150]);
var r = d3.scale.sqrt()
.domain([0, 1])
.range([0, 30]);
function render() {
// Make sure the SVG element only gets created once.
var svg = d3.select('body').selectAll('svg').data([0]);
svg.enter().append('svg')
.attr('width', width)
.attr('height', height);
var item = svg.selectAll('circle')
.data(data, function(d) { return d.key; });
item.enter().append('circle')
.attr('class', 'item')
.attr('r', function(d) { return r(d.r); })
.attr('cx', function(d) { return x(d.x); })
.attr('cy', 0)
.style('stroke', '#3E6E9C')
.transition().duration(1000)
.attr('cy', function(d) { return y(d.y); })
.style('stroke', '#F288A5');
item.exit().filter(':not(.exiting)') // Don't select already exiting nodes
.classed('exiting', true)
.transition().duration(1000)
.attr('cy', height)
.style('stroke', '#3E6E9C')
.remove();
}
var circlesCreated = 0;
function add() {
data.push({key: Date.now(), x: Math.random(), y: Math.random(), r: Math.random()});
render();
setTimeout(data.length < 100 ? add : remove, 5);
}
function remove() {
data = data.slice(1);
render();
if (++circlesCreated === 1000) console.timeEnd('1000 circles');
setTimeout(data.length > 0 ? remove : add, 5);
}
console.time('1000 circles');
add();
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment