Skip to content

Instantly share code, notes, and snippets.

@curran
Last active October 19, 2016 17:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save curran/9f5b38ca4fb8f7cf7af461973a1407c6 to your computer and use it in GitHub Desktop.
Save curran/9f5b38ca4fb8f7cf7af461973a1407c6 to your computer and use it in GitHub Desktop.
React + D3 Boilerplate
license: mit

Boilerplate D3 + React integration.

Features:

  • Uses D3 transitions
  • Responds to resize
  • Demonstrates complete lifecycle (mount, update, unmount)
  • Responds to dynamic data

Inspired by:

I'm new to React and I'm not sure if everything I've done here is "the react way". If you see something questionable please let me know on Twitter.

Many thanks to @DatMousse for this refactor proposal.

Built with blockbuilder.org

forked from curran's block: React Boilerplate

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello React + D3!</title>
<!-- React -->
<script src="//npmcdn.com/react@15.3.0/dist/react.min.js"></script>
<script src="//npmcdn.com/react-dom@15.3.0/dist/react-dom.min.js"></script>
<script src="//npmcdn.com/babel-core@5.8.38/browser.min.js"></script>
<!-- D3 -->
<script src="//d3js.org/d3.v4.min.js"></script>
<style>
/* Make the chart container fill the page using CSS. */
#chart {
position: fixed;
left: 0px;
right: 0px;
top: 0px;
bottom: 0px;
}
</style>
</head>
<body>
<div id="chart"></div>
<script type="text/babel">
var MyD3Vis = React.createClass({
render: function() {
return (
<div>
<svg width={this.props.width}
height={this.props.height}
ref="container">
</svg>
</div>
);
},
componentDidMount: function() {
this.container = d3.select(ReactDOM.findDOMNode(this.refs.container));
this.shouldComponentUpdate(this.props);
this.interval = setInterval(function (){
console.log("D3 graphic active at " + new Date());
}, 1000);
},
shouldComponentUpdate() {
this.renderCircles();
this.renderLines();
},
renderCircles: function (){
var circles = this.container
.selectAll("circle")
.data(this.props.data);
circles.exit().remove();
circles
.enter().append("circle")
.attr("r", 50)
.merge(circles)
.transition().duration(800)
.attr("cx", function (d){ return d.x; })
.attr("cy", function (d){ return d.y; });
},
renderLines: function (){
var {width, height} = this.props;
var lines = this.container.selectAll("line").data([
{x1: 0, y1: 0, x2: width, y2: height},
{x1: 0, y1: height, x2: width, y2: 0}
]);
lines.enter()
.append("line")
.style("stroke-width", 50)
.style("stroke-opacity", 0.4)
.style("stroke", "black")
.merge(lines)
.attr("x1", function (d) { return d.x1; })
.attr("y1", function (d) { return d.y1; })
.attr("x2", function (d) { return d.x2; })
.attr("y2", function (d) { return d.y2; });
},
componentWillUnmount: function (){
clearInterval(this.interval);
}
});
var width = 200,
height = 200,
data = [
{ x: 50, y: 50 },
{ x: 100, y: 100 }
],
show = true;
function render(){
var chartDiv = document.getElementById("chart");
width = chartDiv.clientWidth;
height = chartDiv.clientHeight;
if(show){
ReactDOM.render(
<MyD3Vis width={width} height={height} data={data} />,
chartDiv
);
} else {
ReactDOM.render(
<h1>Press any key to show graphic.</h1>,
chartDiv
);
}
}
render();
setInterval(function (){
data[0].x = Math.round(Date.now() / 50 % width);
data[0].y = Math.round(Date.now() / 10 % height);
data[1].x = Math.round(Date.now() / 60 % width);
data[1].y = Math.round(Date.now() / 70 % height);
render();
}, 1000);
window.addEventListener("resize", render);
window.addEventListener("keyup", function(){
show = !show;
render();
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment