React with D3
by ramnathv
HTML
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<script src="//fb.me/react-with-addons-0.14.0.js"></script>
<script src="//fb.me/react-dom-0.14.0.js"></script>
<script src="//d3js.org/d3.v3.min.js"></script>
<div id="mount"></div>
CSS
#mount{margin-top: 30px;}
Babel + JSX
const Page = (props) => {
return (
<div className='container-fluid'>
<div className='row'>
<div className='col-xs-12 col-md-6'>
<Panel heading="D3 with React">
{props.children}
</Panel>
</div>
</div>
</div>
)
}
const Panel = (props) => {
return (
<div className='panel panel-default'>
<div className="panel-heading">{props.heading}</div>
<div className='panel-body'>{props.children}</div>
</div>
)
}
const Svg = (props) => {
return (
<svg width={props.width} height={props.height}>
<g transform="translate(40, 40)">
{props.children}
</g>
</svg>
)
}
const Button = (props) => {
return(
<button className="btn btn-primary btn-sm" {...props}>
Update
</button>
)
}
const makeData = (N) => {
return d3.range(N).map((d, i) => {
return(
{x: Math.random(), y: Math.random(), r: Math.random()}
)
})
}
const computeAttrs = (props) => {
let S = {
x: d3.scale.linear().range([0, props.width]),
y: d3.scale.linear().range([props.height, 0]),
r: d3.scale.sqrt().range([1, 8])
}
let A = {
x: (d) => d.x,
y: (d) => d.y,
r: (d) => d.r
}
return({
cx: (d) => S.x(A.x(d)),
cy: (d) => S.y(A.y(d)),
r: (d) => S.r(A.r(d)),
fill: "steelblue"
})
}
const Circles1 = React.createClass({
render(){
let SA = computeAttrs(this.props)
let circles = this.props.data.map((d, i) => {
return(
<circle
cx={SA.cx(d)}
cy={SA.cy(d)}
r={SA.r(d)} key={i}
fill={SA.fill}
/>
)
})
return <g ref='points'>{circles}</g>
}
})
const Circles2 = React.createClass({
drawCircles(){
let SA = computeAttrs(this.props)
let el = d3.select(this.refs.points)
let circles = el.selectAll('circle').data(this.props.data)
circles.enter().append('circle').attr("r", 0)
circles.transition().attr(SA)
circles.exit().remove()
...