Using D3 in a React component to transition elements. Alternative implementations only with D3 and using React's TransitionGroup addon.
forked from herrstucki's block: Transitions with React and D3 I
Using D3 in a React component to transition elements. Alternative implementations only with D3 and using React's TransitionGroup addon.
forked from herrstucki's block: Transitions with React and D3 I
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<style> | |
body { | |
background: #fff; | |
} | |
.item { | |
fill: none; | |
stroke-width: 1.5; | |
} | |
</style> | |
<body> | |
<div id="react-root"></div> | |
<script src="//d3js.org/d3.v3.min.js"></script> | |
<script src="https://fb.me/react-15.2.0.js"></script> | |
<script src="https://fb.me/react-dom-15.2.0.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 chart = React.createClass({ | |
render: function() { | |
return React.DOM.svg({ | |
width: width, | |
height: height | |
}); | |
}, | |
componentDidUpdate: function() { | |
var item = d3.select(ReactDOM.findDOMNode(this)).selectAll('circle') | |
.data(this.props.items, 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', '#81E797'); | |
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 Chart = React.createFactory(chart) | |
var rootEl = document.getElementById("react-root") | |
function render() { | |
ReactDOM.render( | |
Chart({items: data}), | |
rootEl | |
); | |
} | |
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, 15); | |
} | |
function remove() { | |
data = data.slice(1); | |
render(); | |
if (++circlesCreated === 1000) console.timeEnd('1000 circles'); | |
setTimeout(data.length > 0 ? remove : add, 15); | |
} | |
console.time('1000 circles'); | |
add(); | |
</script> |