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: '#9abbd6',
  money: 1457486,
  value: 3.8,
},
{
  name: 'Injection Drilling',
  color: '#79a4c8',
  money: 2414972,
  value: 6.3,
},
{
  name: 'Plant Capital Assets',
  color: '#588EBB',
  money: 21086104,
  value: 55.1,
},
{
  name: 'Eng, Constr, Etc',
  color: '#6899c1',
  money: 5235703,
  value: 13.6,
},
{
  name: 'Contingency',
  color: '#8aafcf',
  money: 2605954,
  value: 6.8,
},
{
  name: 'Project, Land, Misc',
  color: '#abc6dd',
  money: 1145310,
  value: 2.9,
},
{
  name: 'Pump Costs',
  color: '#bcd1e3',
  money: 600000,
  value: 1.5,
},
{
  name: 'Surface Equipment',
  color: '#ccddea',
  money: 500000,
  value: 1.3,
},
{
  name: 'Legal',
  color: '#afd769',
  money: 350000,
  value: .9,
},
{
  name: 'Aquisition Fee',
  color: '#99cd41',
  money: 2000000,
  value: 5,
},{
  name: 'Cash Fees & Interest',
  color: '#527e7e',
  money: 158803,
  value: .4,
},{
  name: 'Capitalized Fees & Interest',
  color: '#345050',
  money: 705549,
  value: 1.8,
}];

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 =...