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: '#bf6950',
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')
...