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);"); 
}