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')
);