|
<!DOCTYPE html> |
|
<html> |
|
<head> |
|
<script src="https://unpkg.com/[email protected]/babel.min.js" charset="utf-8"></script> |
|
<script src="https://unpkg.com/react@next/umd/react.production.min.js" charset="utf-8"></script> |
|
<script src="https://unpkg.com/react-dom@next/umd/react-dom.production.min.js" charset="utf-8"></script> |
|
<!-- <script src="fiber.js" charset="utf-8"></script> --> |
|
<script src="https://cdn.jsdelivr.net/npm/[email protected]/create-react-class.min.js" charset="utf-8"></script> |
|
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script> |
|
</head> |
|
|
|
<body> |
|
<div id="container"></div> |
|
|
|
<script type="text/babel"> |
|
var size = 1000; |
|
var height = 500; |
|
var width = 960; |
|
var charge = -0.3; |
|
|
|
var dataGlobal = d3.range(size).map(function() { |
|
return { r: Math.floor(Math.random() * 8 + 2) }; |
|
}); |
|
|
|
var start = new Date(); |
|
var time = 0; |
|
var ticks = 0; |
|
|
|
var force = d3.layout |
|
.force() |
|
.size([width, height]) |
|
.nodes(dataGlobal) |
|
.charge(function(d) { |
|
return d.r * d.r * charge; |
|
}) |
|
.start(); |
|
|
|
var BubbleChart = createReactClass({ |
|
displayName: "BubbleChart", |
|
render: function() { |
|
return ( |
|
<Chart width={this.props.width} height={this.props.height}> |
|
<DataSeries data={this.props.data} /> |
|
</Chart> |
|
); |
|
} |
|
}); |
|
|
|
var Chart = createReactClass({ |
|
displayName: "Chart", |
|
render: function() { |
|
return ( |
|
<svg width={this.props.width} height={this.props.height}> |
|
{this.props.children} |
|
</svg> |
|
); |
|
} |
|
}); |
|
|
|
class PureCircle extends React.PureComponent { |
|
render() { |
|
const { x, y, r } = this.props; |
|
return ( |
|
<circle |
|
cx={0} |
|
cy={0} |
|
r={r} |
|
fill="steelblue" |
|
style={{transform: `translate(${x}px, ${y}px)`}} |
|
/> |
|
); |
|
} |
|
} |
|
|
|
var DataSeries = createReactClass({ |
|
displayName: "DataSeries", |
|
getInitialState: function() { |
|
return { data: this.props.data }; |
|
}, |
|
|
|
componentDidMount: function() { |
|
var _self = this; |
|
force.on("tick", function() { |
|
var renderStart = new Date(); |
|
window.requestAnimationFrame(_self.tick); |
|
time += new Date() - renderStart; |
|
ticks++; |
|
}); |
|
}, |
|
|
|
tick: function() { |
|
this.setState({ data: dataGlobal }); |
|
}, |
|
|
|
render: function() { |
|
var circles = this.state.data.map(function(point, i) { |
|
return ( |
|
<PureCircle |
|
key={i} |
|
x={point.x} |
|
y={point.y} |
|
r={point.r} |
|
/> |
|
); |
|
}); |
|
|
|
return [...circles]; |
|
} |
|
}); |
|
|
|
|
|
var container = document.getElementById("container"); |
|
ReactDOM.render( |
|
<BubbleChart data={dataGlobal} height={height} width={width} />, |
|
container |
|
); |
|
|
|
force.on("end", function() { |
|
var totalTime = new Date() - start; |
|
console.log("Total Time:", totalTime); |
|
console.log("Render Time:", time); |
|
console.log("Ticks:", ticks); |
|
console.log("Average Time:", totalTime / ticks); |
|
}); |
|
</script> |
|
|
|
</html> |