|
<!DOCTYPE html> |
|
<html> |
|
<head> |
|
<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="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> |
|
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 React.createElement( |
|
Chart, |
|
{ |
|
width: this.props.width, |
|
height: this.props.height |
|
}, |
|
React.createElement( |
|
DataSeries, |
|
{ |
|
data: this.props.data |
|
}, |
|
null |
|
) |
|
); |
|
} |
|
}); |
|
|
|
var Chart = createReactClass({ |
|
displayName: "Chart", |
|
render: function() { |
|
return React.createElement( |
|
"svg", |
|
{ |
|
width: this.props.width, |
|
height: this.props.height |
|
}, |
|
this.props.children |
|
); |
|
} |
|
}); |
|
|
|
var DataSeries = createReactClass({ |
|
displayName: "DataSeries", |
|
getInitialState: function() { |
|
return { |
|
data: this.props.data, |
|
shouldRender: true |
|
}; |
|
}, |
|
|
|
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: this.props.data, |
|
shouldRender: !this.state.shouldRender |
|
}); |
|
}, |
|
|
|
shouldComponentUpdate() { |
|
return this.state.shouldRender; |
|
}, |
|
|
|
render: function() { |
|
var circles = this.state.data.map(function(point, i) { |
|
return React.createElement( |
|
"circle", |
|
{ |
|
key: i, |
|
cx: 0, |
|
cy: 0, |
|
r: point.r, |
|
fill: "steelblue", |
|
style: { transform: `translate(${point.x}px, ${point.y}px)` } |
|
}, |
|
null |
|
); |
|
}); |
|
|
|
return React.createElement("g", null, circles); |
|
} |
|
}); |
|
|
|
var container = document.getElementById("container"); |
|
ReactDOM.render( |
|
React.createElement( |
|
BubbleChart, |
|
{ |
|
data: dataGlobal, |
|
width: width, |
|
height: height |
|
}, |
|
null |
|
), |
|
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> |