Data donuts
by ajthomascouk
HTML
<div class="dataDonut" data-total="5024" data-used="1106">
<div class="dataDonut__half dataDonut__half--first">
<div>
</div>
</div>
<div class="dataDonut__half dataDonut__half--second">
<div>
</div>
</div>
<div class="dataDonut__content">
<div>
<p>Data left: <span>3.9GB</span></p>
</div>
</div>
</div>
<div class="dataDonut" data-total="1024" data-used="806">
<div class="dataDonut__half dataDonut__half--first">
<div>
</div>
</div>
<div class="dataDonut__half dataDonut__half--second">
<div>
</div>
</div>
<div class="dataDonut__content">
<div>
<p>Data left: <span>218MB</span></p>
</div>
</div>
</div>
<div class="dataDonut" data-total="11024" data-used="6806">
<div class="dataDonut__half dataDonut__half--first">
<div>
</div>
</div>
<div class="dataDonut__half dataDonut__half--second">
<div>
</div>
</div>
<div class="dataDonut__content">
<div>
<p>Data left: <span>4.2GB</span></p>
</div>
</div>
</div>
SCSS
$base-color: #079;
$full: 200px;
$half: calc(#{$full} / 2);
html {
font-size:16px;
}
@keyframes animate-bar {
0% { transform: rotate(0); }
}
@keyframes second-bar-opacity {
100% { opacity:1; }
}
.dataDonut {
height: $full;
width: $full;
margin-left: 30px;
position: relative;
float: left;
margin-right:1rem;
&__half {
position: absolute;
width: 100%;
height: 100%;
border-radius: $half;
clip: rect(0px, $full, $full, $half);
background-color: white;
div {
background-color: $base-color;
transition: all 1s;
position: absolute;
width: 100%;
height: 100%;
border-radius: $half;
clip: rect(0px, $half, $full, 0px);
z-index:0;
&:after {
width: calc(100% - 1rem);
height: calc(100% - 1rem);
content: "";
position: absolute;
bottom: .5rem;
left: .5rem;
background-color: white;
border-radius: 50%;
}
}
&--first {
transform: rotate(0deg);
div {
transform: rotate(0deg);
animation: animate-bar 1s;
animation-timing-function: linear;
}
}
&--second {
transform: rotate(180deg);
div {
transform: rotate(0deg);
opacity:0;
animation: second-bar-opacity 0s, animate-bar 1s;
animation-delay: 1s;
animation-fill-mode: forwards;
}
}
}
&__content {
background-color: white;
width: calc(100% - 1rem);
height: calc(100% -1rem);
top: .5rem;
left: .5rem;
position: relative;
border-radius: 50%;
div {
position: absolute;
display: block;
width: 100%;
top: 0px;
text-align: center;
background-color:transparent;
}
}
}
JavaScript
let firstSize;
let secondSize;
let donuts = document.getElementsByClassName("dataDonut");
var i;
for (i = 0; i < donuts.length; i++) {
let total = donuts[i].dataset.total;
let used = donuts[i].dataset.used;
let percUsed = ((used/total) * 100).toFixed(0);
if (percUsed >= 50){
firstSize = 180
percUsed = percUsed - 50;
secondSize = 360 * percUsed/100;
}
else {
firstSize = 360 * percUsed/100;
}
donuts[i].getElementsByClassName("dataDonut__half")[0].firstElementChild.setAttribute("style", "transform: rotate("+firstSize+"deg);");
donuts[i].getElementsByClassName("dataDonut__half")[1].firstElementChild.setAttribute("style", "transform: rotate("+secondSize+"deg);");
}