Using D3 in a React component to transition elements. Alternative implementations only with D3 and using React's TransitionGroup addon.
This block is here.
Using D3 in a React component to transition elements. Alternative implementations only with D3 and using React's TransitionGroup addon.
This block is here.
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<style> | |
body { | |
background: #fff; | |
} | |
.item { | |
fill: none; | |
stroke-width: 1.5; | |
} | |
</style> | |
<body> | |
<div id="app"></div> | |
<script src="http://d3js.org/d3.v3.min.js"></script> | |
<script src="https://fb.me/react-0.14.7.js"></script> | |
<script src="https://fb.me/react-dom-0.14.7.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]); | |
class D3Circles extends React.Component { | |
render() { | |
return ( | |
React.createElement('svg', | |
{ width:width, | |
height: height, | |
ref: c => this.chart = c | |
}) | |
); | |
} | |
componentDidUpdate() { | |
var item = d3.select(this.chart).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') | |
.on('click', () => console.log('caught me')) | |
.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).ease('bounce') | |
.attr('cy', height) | |
.style('stroke', 'red') | |
.remove(); | |
} | |
} | |
function render() { | |
ReactDOM.render( | |
React.createElement(D3Circles, {items: data}), | |
document.getElementById('app') | |
); | |
} | |
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> | |
</body> |