Skip to content

Instantly share code, notes, and snippets.

@esbullington
Forked from jstcki/README.md
Last active August 29, 2015 14:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save esbullington/c1c072c5d919111f451c to your computer and use it in GitHub Desktop.
Save esbullington/c1c072c5d919111f451c to your computer and use it in GitHub Desktop.

Using D3 in a React TransitionGroup to transition elements. D3 is used purely for transitions, not for data joins. The distinction between entering and exiting elements is handled by the TransitionGroup component. See the React documentation for further information.

Alternative implementations only with D3 and using React without addons.

Note: This implementation is around 30% slower in processing 1000 circles than the other two.

<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
background: #fff;
}
.item {
fill: #333;
stroke-width: 1.5;
}
.item--transitioning {
fill: none;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://fb.me/react-with-addons-0.12.0.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]);
var circle = React.createClass({
componentDidMount: function() {
d3.select(this.getDOMNode())
.classed('item--transitioning', true)
.style('stroke', '#3E6E9C')
.transition().duration(1000)
.style('stroke', '#D8E467')
.attr('cy', y(this.props.y));
},
componentWillLeave: function(done) {
d3.select(this.getDOMNode())
.transition().duration(1000)
.style('stroke', '#3E6E9C')
.attr('cy', height)
.each('end', done);
},
render: function() {
return React.DOM.circle({
className: 'item',
cx: x(this.props.x),
cy: 0,
r: r(this.props.r)
});
}
});
function render() {
React.renderComponent(
React.addons.TransitionGroup(
{
transitionName: 'circles',
component: React.DOM.svg,
width: width,
height: height
},
data.map(circle)
),
document.body
);
}
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