Skip to content

Instantly share code, notes, and snippets.

@jstcki
Last active April 12, 2017 13:24
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save jstcki/9205264 to your computer and use it in GitHub Desktop.
Save jstcki/9205264 to your computer and use it in GitHub Desktop.
Transitions with React and D3 II

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.9.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