JSFiddle - React, Tailwind, and code Playground

by Dug Sohn

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.6/Chart.bundle.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<br/>
<div class="container">
  <div class="row">
    <div class="col-sm-4">
      <div id="understandingMyBill" class="chart"></div>
    </div>
    <div class="col-sm-8">
      <div class="row">
        <div class="col-sm-6">
          <h2>Understand Your Bill</h2>
        </div>
        <div class="col-sm-3 text-right">
          <p>
            Invoice 8675309
          </p>
          <p>
            August 1,2017
          </p>
        </div>
        <div class="col-sm-3">
          <button class="btn btn-success btn-block">
            <i class="fa fa-file-o"></i> Download
          </button>
        </div>
      </div>
<br/>
      <div class="row gexa-row">
        <div class="col-sm-8">
          Gexa Charges
        </div>
        <div class="col-xs-2">
          $65.00
        </div>
        <div class="col-xs-2">
          <i class="fa fa-plus gexa-detail pull-right"></i>
        </div>
      </div>
      <div class="row details">
        <div class="col-xs-8">
          Residential Energy Charge [email protected]
        </div>
        <div class="col-xs-4">
          $60.00
        </div>
        <div class="col-xs-8">
          Late Fee
        </div>
        <div class="col-xs-4">
          $5.00
        </div>
      </div>
      <div class="row oncor-row">
        <div class="col-sm-8">
          ONCOR Charges
        </div>
        <div class="col-xs-2">
          $35.00
        </div>
        <div class="col-xs-2">
          <i class="fa fa-plus oncor-detail pull-right"></i>
        </div>
      </div>
      <div class="row details">
        <div class="col-sm-8"> TRANSITION CHARGE 5 </div>
        <div class="col-xs-2"> $5.00 </div>
        <div...

SCSS

@import url(//fonts.googleapis.com/css?family=Oswald:400);
@import url('https://fonts.googleapis.com/css?family=Open+Sans:400,700,800');
body {
  background: rgb(212, 237, 201);
  font-family: "Open Sans", sans-serif;
  color: #555
}
hr {
  margin:10px 3px;
  border-color:#fff
}
h2 {margin-top:0}
.chart {
  margin: 0 auto;
  width: 250px;
  height: 250px;
  position: relative;
  font-family: "Oswald", sans-serif;
}
p { margin-bottom:0; font-size:12px}

.doughnutTip {
  position: absolute;
  float: left;
  min-width: 30px;
  max-width: 300px;
  padding: 5px 15px;
  border-radius: 1px;
  background: rgba(0, 0, 0, .8);
  color: #ddd;
  font-size: 17px;
  text-shadow: 0 1px 0 #000;
  text-transform: uppercase;
  text-align: center;
  line-height: 1.3;
  letter-spacing: .06em;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
  transform: all .3s;
  pointer-events: none;
  font-family: "Oswald", sans-serif;
}

.doughnutTip:after {
  position: absolute;
  left: 50%;
  bottom: -6px;
  content: "";
  height: 0;
  margin: 0 0 0 -6px;
  border-right: 5px solid transparent;
  border-left: 5px solid transparent;
  border-top: 6px solid rgba(0, 0, 0, .7);
  line-height: 0;
}

.doughnutSummary {
  position: absolute;
  top: 45%;
  left: 50%;
  color: #d5d5d5;
  text-align: center;
  cursor: default;
  text-transform: uppercase;
  font-family: "Oswald", sans-serif;
}

.doughnutSummaryTitle {
  position: absolute;
  top: 85%;
  width: 100%;
  font-size: 13px;
  letter-spacing: .06em;
  line-height: 16px;
  color: #000;
  letter-spacing: 1px;
  font-family: "Oswald", sans-serif;
}

.doughnutTypeTitle {
  position: absolute;
  top: 50%;
  width: 100%;
  font-size: 22px;
  letter-spacing: .06em;
  line-height: 22px;
}

.doughnutSummaryNumber {
  position: absolute;
  top: 10%;
  width: 100%;
  margin-top: -3%;
  font-size: 65px;
  left: -15px;
  color: rgb(43, 166, 40);
  letter-spacing: -2px;
  font-family: "Oswald", sans-serif;
}

.doughnutSummaryNumber:before {
  content: '$';
 ...

JavaScript

;
(function($, undefined) {
  $.fn.drawDoughnutChart = function(data, options) {
    var $this = this,
      W = $this.width(),
      H = $this.height(),
      centerX = W / 2,
      centerY = H / 2,
      cos = Math.cos,
      sin = Math.sin,
      PI = Math.PI,
      settings = $.extend({
        segmentShowStroke: true,
        segmentStrokeColor: "#0C1013",
        segmentStrokeWidth: 0,
        baseColor: "rgba(255,255,255,1)",
        baseOffset: 0,
        edgeOffset: 10, //offset from edge of $this
        percentageInnerCutout: 75,
        animation: true,
        animationSteps: 90,
        animationEasing: "easeInOutExpo",
        animateRotate: true,
        tipOffsetX: -8,
        tipOffsetY: -45,
        tipClass: "doughnutTip",
        summaryClass: "doughnutSummary",
        summaryTitle: "Contract Time Remaining:",
        summaryTitleClass: "doughnutSummaryTitle",
        summaryTypeClass: "doughnutTypeTitle",
        summaryNumberClass: "doughnutSummaryNumber",
        beforeDraw: function() {},
        afterDrawed: function() {},
        onPathEnter: function(e, data) {},
        onPathLeave: function(e, data) {}
      }, options),
      animationOptions = {
        linear: function(t) {
          return t;
        },
        easeInOutExpo: function(t) {
          var v = t < .5 ? 8 * t * t * t * t : 1 - 8 * (--t) * t * t * t;
          return (v > 1) ? 1 : v;
        }
      };
    var requestAnimFrame = function() {
      return window.requestAnimationFrame ||
        window.webkitRequestAnimationFrame ||
        window.mozRequestAnimationFrame ||
        window.oRequestAnimationFrame ||
        window.msRequestAnimationFrame ||
        function(callback) {
          window.setTimeout(callback, 1000 / 60);
        };
    }();

    settings.beforeDraw.call($this);

    var $svg = $('<svg width="' + W + '" height="' + H + '" viewBox="0 0 ' + W + ' ' + H + '" xmlns="http://www.w3.org/2000/svg"...