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: 'Production Drilling',
  color: '#abc09c',
  money: 1457486,
  value: 4,
},
{
  name: 'Injection Drilling',
  color: '#ccddea',
  money: 2414972,
  value: 7,
},
{
  name: 'Plant Capital Assets',
  color: '#588EBB',
  
  money: 21086104,
  value: 60,
},
{
  name: 'Eng, Constr, Etc',
  color: '#8aafcf',
  money: 5235703,
  value: 15,
},
{
  name: 'Contingency',
  color: '#82a26d',
  money: 2605954,
  value: 7,
},
{
  name: 'Project, Land, Misc',
  color: '#d5dfcc',
  money: 1145310,
  value: 3,
},
{
  name: 'Pump Costs',
  color: '#,
  money: 600000,
  value: 2,
},
{
  name: 'Surface Equipment',
  color: 'd99a87,
  money: 500000,
  
  value: 1,
}];

bakeDonut(pieData);


function bakeDonut(d) {
const formatMoney = d3.format("$,");
  let activeSegment;
  const data = d.sort((a, b) => b['value'] - a['value']),
    viewWidth = 500,
    viewHeight = 300,
    svgWidth = viewHeight,
    svgHeight = viewHeight,
    thickness = 20,
    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')
   ...