Donut Charts with d4
Companion implementation of https://blog.usebutton.com/building-declarative-charts-with-d4-fbd5bdbbf213
HTML
<script src="https://fb.me/react-with-addons-15.1.0.js"></script>
<script src="https://fb.me/react-dom-15.1.0.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.7.3/d3.js"></script>
<title>Donut Charts</title>
<body>
<div class="flexbox">
<div id="chart1"></div>
<div id="chart2"></div>
<div id="chart3"></div>
</div>
</body>
CSS
.flexbox {
display: flex;
align-items: center;
}
.flexbox div {
margin-right: 20px;
}
Babel + JSX
class DonutChart extends React.Component {
render() {
const { data, arcWidth, width, padAngle } = this.props;
const radius = width / 2;
const colors = ['#7B6888', '#31C0DA', '#FFC107'];
const arcAngles = d3.pie()
.padAngle(padAngle)(data);
const arcGenerator = d3.arc()
.outerRadius(radius)
.innerRadius(radius - arcWidth);
const transformStyle = {
transform: `translate(${width / 2}px, ${width / 2}px)`
};
return (
<svg
width={width}
height={width}
className={this.props.className}>
<g style={transformStyle}>
{arcAngles.map((d, i) => (
<g className="arc" key={i}>
<path
d={arcGenerator(d)}
style={{ fill: colors[i % colors.length] }} />
</g>
))}
</g>
</svg>
);
}
}
DonutChart.propTypes = {
data: React.PropTypes.arrayOf(React.PropTypes.number.isRequired),
arcWidth: React.PropTypes.number.isRequired,
width: React.PropTypes.number.isRequired,
padAngle: React.PropTypes.number.isRequired,
className: React.PropTypes.string
};
DonutChart.defaultProps = {
arcWidth: 30,
width: 100,
padAngle: 0.05
};
ReactDOM.render(
<DonutChart data={[100, 80, 70]} width={150} arcWidth={20} />,
document.getElementById('chart1')
);
ReactDOM.render(
<DonutChart data={[100, 80]} width={120} arcWidth={40} padAngle={0.2} />,
document.getElementById('chart2')
);
ReactDOM.render(
<DonutChart data={[100]} width={50} arcWidth={20} />,
document.getElementById('chart3')
);