JSFiddle - React, Tailwind, and code Playground

by gdicerbo

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.12.2/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-format/1.2.2/d3-format.min.js"></script>
<div class="chart"></div>

CSS

html,
body {
  height: 100%;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
}

body {
  font-family: 'Roboto', sans-serif;
  font-weight: 300;
}

.pie {
  /* position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%); */
}

.data-path:hover {
  cursor: pointer;
}

.data-text {
  -webkit-transition: -webkit-transform .2s ease-in-out;
  transition: -webkit-transform .2s ease-in-out;
  transition: transform .2s ease-in-out;
  transition: transform .2s ease-in-out, -webkit-transform .2s ease-in-out;
  fill: #000;
  text-shadow: none;
}

.data-text__value {
  font-size: 24px;
  opacity: 0;
}

.data-text__name {
  font-size: 32px;
  opacity: 0;
}

.data-text__percent {
  font-size: 62px;
  opacity: 0;
}

.data-text--show {
  -webkit-transform: translateY(0);
  transform: translateY(0);
  -webkit-animation: fadeGraphTextIn 0.5s forwards;
  animation: fadeGraphTextIn 0.5s forwards;
}

.data-text:hover {
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}

.legend-text {
  fill: #fff;
}

@-webkit-keyframes fadeGraphTextIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes fadeGraphTextIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

JavaScript

const pieData = [
{
  name: 'ITC Eligible',
  color: '#588EBB',
  money: 23649252,
  value: 69.8,
},
{
  name: 'Not ITC Eligible',
  color: '#8aafcf',
  money: 10214692,
  value: 30.2,
}];

bakeDonut(pieData);


function bakeDonut(d) {
const formatMoney = d3.format("$,");
  let activeSegment;
  const data = d.sort((a, b) => b['value'] - a['value']),
    viewWidth = 500,
    viewHeight = 350,
    svgWidth = viewHeight,
    svgHeight = viewHeight,
    thickness = 30,
    colorArray = data.map(k => k.color),
    el = d3.select('.chart'),
    radius = Math.min(svgWidth, svgHeight) / 2,
    color = d3.scaleOrdinal()
    .range(colorArray);

  const max = d3.max(data, (maxData) => maxData.value);

  const svg = el.append('svg')
    .attr('viewBox', `0 0 ${viewWidth + thickness} ${viewHeight + thickness}`)
    .attr('class', 'pie')
    .attr('width', viewWidth)
    .attr('height', svgHeight);

  const g = svg.append('g')
    .attr('transform', `translate( ${ (svgWidth / 2) + (thickness / 2) }, ${ (svgHeight / 2) + (thickness / 2)})`);

  const arc = d3.arc()
    .innerRadius(radius - thickness)
    .outerRadius(radius);

  const arcHover = d3.arc()
    .innerRadius(radius - (thickness + 6))
    .outerRadius(radius + 4);

  const pie = d3.pie()
    .value(function(pieData) {
      return pieData.value;
    })
    .sort(null);

  const path = g.selectAll('path')
    .attr('class', 'data-path')
    .data(pie(data))
    .enter()
    .append('g')
    .attr('class', 'data-group')
    .each(function(pathData, i) {
      const group = d3.select(this)

      //Show name of section - Growth
      group.append('text')
        .text(`${pathData.data.name}`)
        .attr('class', 'data-text data-text__value')
        .attr('text-anchor', 'middle')
        .attr('dy', '-3rem')

      //Show name of section
      group.append('text')
        .text(`${pathData.data.value + '%'}`)
        .attr('class', 'data-text data-text__percent')
        .attr('text-anchor', 'middle')
       ...