Skip to content

Instantly share code, notes, and snippets.

@jonahwilliams
Created January 28, 2016 23:53
Show Gist options
  • Save jonahwilliams/24c2fcf0cd0176fd2046 to your computer and use it in GitHub Desktop.
Save jonahwilliams/24c2fcf0cd0176fd2046 to your computer and use it in GitHub Desktop.
D3 Chart with React / d3-shape
<!doctype html>
<html>
<head>
<title> D3 Shape Test</title>
<style type="text/css">
path {
stroke: black;
fill: none;
stroke-width: 0.5px;
shape-rendering: optimizeQuality;
}
</style>
</head>
<body>
<div id="app"></div>
</body>
<script src="index.js"></script>
</html>
import React from 'react';
import ReactDOM from 'react-dom';
import d3 from 'd3-shape';
// Recieves { data = [1, 2, 3, ...], width = height }
class PieHolder extends React.Component {
constructor(props) {
super(props);
this.makePie = this.makePie.bind(this);
this.onMouseOut = this.onMouseOut.bind(this);
this.onMouseOver = this.onMouseOver.bind(this);
this.colors = ['#e41a1c','#377eb8','#4daf4a','#984ea3','#ff7f00','#ffff33','#a65628'];
// minimal ui state - only effects this component and children
this.state = {
// currently selected (if any) element - the data not the dom
selected : null
};
}
// This method takes our data from props, and computes each pathstring
makePie() {
const width = this.props.width;
return d3
.pie()(this.props.data)
.map(d => d3.arc()(
{
startAngle: d.startAngle,
endAngle: d.endAngle,
innerRadius: 100,
outerRadius: width / 2 - 10,
padAngle: 0.03
}));
}
// define event handlers on the parent holder component
onMouseOver(e) {
this.setState({
selected: this.props.data[+e.target.id]
});
}
onMouseOut(e) {
this.setState({ selected : null });
}
render() {
const paths = this.makePie().map((d, i) => {
return (
<path key={i}
d={d}
id={i}
onMouseOut={this.onMouseOut}
onMouseOver={this.onMouseOver}
style={{fill: this.colors[i], opacity: "0.8"}}/>);
});
const label = (<text x={-25} y={0}>{ this.state.selected !== null ? "Datum " + this.state.selected : "" }</text>)
return (
<div>
<svg height={this.props.height}
width={this.props.width}>
<g transform={`translate(${this.props.width / 2},${this.props.width / 2})`}>
{ label }
{ paths }
</g>
</svg>
</div>
);
}
}
ReactDOM.render(
<PieHolder width={400} height={400} data={[1, 2, 3, 2, 9]}/>,
document.getElementById('app')
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment