JSFiddle - React, Tailwind, and code Playground

by Oleg Mikhailov

HTML

<div class="stats">
  <div class="back">
    <canvas height="150px" width="150px"></canvas>
  </div>
  <div class="calculation">
    <div>
      <div style="background-color: #ccc;"></div>
      <span>87.5%</span>
      <span>Не выполнено</span>
    </div>
    <div>
      <div style="background-color: #aaa;"></div>
      <span>12.5%</span>
      <span>Выполнено</span>
    </div>
  </div>
</div>

CSS

html {
	box-sizing: border-box;
}
*, *:before, *:after {
	box-sizing: inherit;
}
.stats {
  display: flex; align-items: flex-start;
}
.back {
  position: relative;
  height: 150px; width: 150px;
  border: 15px solid #ccc;
  border-radius: 50%;
}
canvas {
  position: absolute; top: -15px; left: -15px;
}
.calculation {
  margin-left: 30px;
}
.calculation > div {
  display: flex; align-items: center;
}
.calculation > div > div {
  height: 15px; width: 15px;
  border-radius: 50%;
}
.calculation > div {
  margin-top: 10px;
}
.calculation > div > *:not(:last-child) {
  margin-right: 10px;
}

JavaScript

var div = $('.border');
var canvas = $('canvas')[0];

function stats(options) {
	var total = options.data.reduce(function(prev, curr) {
  	return prev + curr.num;
  }, 0);
  if(!options.total) {
  	options.total = {
    	num: total,
      color: 'grey'
    };
  }
	if(total > options.total.num)
  	options.total.num = total;
  var context = canvas.getContext('2d');
  context.clearRect(0, 0, canvas.width, canvas.height);
	var start_angle = 0;
  options.data.forEach(function(item) {
 		context.beginPath();
    context.lineWidth = 15;
    context.strokeStyle = item.color;
    var end_angle = 2 * Math.PI * item.num / options.total.num + start_angle;
    context.arc(75, 75, 67.5, start_angle, end_angle);
    start_angle = end_angle;
    context.stroke();
  })
}
stats({
  format: false,
  total: {
    num: 1024,
    color: 'white',
    name: 'Не выполнено'
  },
  data: [
  {
    num: 200,
    color: 'red',
    name: 'Выполнено'
  },
  {
    num: 300,
    color: 'green',
    name: 'В процессе'
  },
  {
    num: 120,
    color: 'blue',
    name: 'Неудачно'
  },
  {
    num: 156,
    color: 'grey',
    name: 'Критично'
  },
  {
    num: 455,
    color: 'crimson',
    name: 'ЫВфыв'
  }
  ]
});