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: 'ЫВфыв'
}
]
});