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