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: 67,
},
{
name: 'Not ITC Eligible',
color: '#8aafcf',
money: 11397154,
value: 33,
}];
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')
...