Percent Pie Chart With CSS Only

Percent pie chart with css only

New answer 2021

With some modern techniques we can improve the code. You can have rounded edges and also consider animation:

@property --p{
syntax: '<number>';
inherits: true;
initial-value: 1;
}

.pie {
--p:20; /* the percentage */
--b:22px; /* the thickness */
--c:darkred; /* the color */
--w:150px; /* the size*/

width:var(--w);
aspect-ratio:1/1;
position:relative;
display:inline-grid;
margin:5px;
place-content:center;
font-size:25px;
font-weight:bold;
font-family:sans-serif;
}
.pie:before,
.pie:after {
content:"";
position:absolute;
border-radius:50%;
}
.pie:before {
inset:0;
background:
radial-gradient(farthest-side,var(--c) 98%,#0000) top/var(--b) var(--b) no-repeat,
conic-gradient(var(--c) calc(var(--p)*1%),#0000 0);
-webkit-mask:radial-gradient(farthest-side,#0000 calc(99% - var(--b)),#000 calc(100% - var(--b)));
mask:radial-gradient(farthest-side,#0000 calc(99% - var(--b)),#000 calc(100% - var(--b)));
}
.pie:after {
inset:calc(50% - var(--b)/2);
background:var(--c);
transform:rotate(calc(var(--p)*3.6deg - 90deg)) translate(calc(var(--w)/2 - 50%));
}
.animate {
animation:p 1s .5s both;
}
.no-round:before {
background-size:0 0,auto;
}
.no-round:after {
content:none;
}
@keyframes p{
from{--p:0;}
}

body {
background:#ddd;
}
<div class="pie" style="--p:20"> 20%</div>
<div class="pie" style="--p:40;--c:darkblue;--b:10px"> 40%</div>
<div class="pie no-round" style="--p:60;--c:purple;--b:15px"> 60%</div>
<div class="pie animate" style="--p:80;--c:orange;"> 80%</div>
<div class="pie animate no-round" style="--p:90;--c:lightgreen"> 90%</div>

Creating a static pie chart with CSS

Here is an idea based on this previous answer

.box {
/* percentage to degree
--s:0 for [0% 50%]
--s:1 for [50% 100%]
*/
--v:calc( ((18/5) * var(--p) - 90)*1deg);

width:100px;
height:100px;
display:inline-block;
border-radius:50%;
background:
linear-gradient(var(--v), yellowgreen 50%,transparent 0) 0 /calc((1 - var(--s))*100%),
linear-gradient(var(--v), transparent 50%,#655 0) 0 /calc(var(--s)*100%),
linear-gradient(to right, yellowgreen 50%,#655 0);
}
<div class="box" style="--p:5;--s:0"></div>
<div class="box" style="--p:20;--s:0"></div>
<div class="box" style="--p:50;--s:0"></div>
<div class="box" style="--p:70;--s:1"></div>
<div class="box" style="--p:95;--s:1"></div>

CSS pie chart animation from 40% to 60%

The method you're using is perfect for static pie charts, but will never be nicely animating between the 50% mark. I personally prefer to go the SVG route.

Lea Verou wrote a good piece about how to handle something like this:
https://www.smashingmagazine.com/2015/07/designing-simple-pie-charts-with-css/

It basically comes down to creating a <circle> applying a stroke as wide as the circle itself and manipulate the stroke-dasharray property with CSS.

HTML

<svg width="100" height="100" class="svg">
<circle r="50" cx="50" cy="50" class="circle"/>
<circle id="pie" r="22.5" cx="50" cy="50" class="circle percent-10"/>
</svg>

SCSS

// circumference = 2π * radius
// so in this case circumference = 2π × 22.5 ≈ 141):
$circumference: 141;

.svg {

/* Appearance */
transform: rotate(-90deg);
}

.circle {

/* Appearance */
fill: #fdded9;
}

#pie {

/* Appearance */
stroke: #ff4081;
stroke-dasharray: 0 $circumference;
stroke-width: 45;
transition: stroke-dasharray .2s linear;

&.percent-10 { stroke-dasharray: ($circumference * 0.1) $circumference; }
&.percent-20 { stroke-dasharray: ($circumference * 0.2) $circumference; }
&.percent-30 { stroke-dasharray: ($circumference * 0.3) $circumference; }
&.percent-40 { stroke-dasharray: ($circumference * 0.4) $circumference; }
&.percent-50 { stroke-dasharray: ($circumference * 0.5) $circumference; }
&.percent-60 { stroke-dasharray: ($circumference * 0.6) $circumference; }
&.percent-70 { stroke-dasharray: ($circumference * 0.7) $circumference; }
&.percent-80 { stroke-dasharray: ($circumference * 0.8) $circumference; }
&.percent-90 { stroke-dasharray: ($circumference * 0.9) $circumference; }
&.percent-100 { stroke-dasharray: ($circumference * 1) $circumference; }
}

My only concern for your code now is that this is not very scalable. I think it might be a better approach to set the stroke-dasharray dynamically with JavaScript based on the data-attribute.

JavaScript

$('button').on('click', function(){

var CIRCUMFERENCE = 141,
percentage = Number($(this).data('value')),
factor = percentage / 100,
strokeDashArray = (CIRCUMFERENCE * factor) + ' ' + CIRCUMFERENCE);

$pie.css('stroke-dasharray', strokeDashArray;
});

And here's a CodePen based on your original code so you can see it in action:
http://codepen.io/rvmook/pen/LNLGoE

How to return only value in pie on apexcharts.js won't convert percent

The formatter property needs to be nested inside dataLabels property. Like this:

    var options = {
chart: {
width: 650,
type: 'pie',
},
labels: ['Date formation',
'Date formation 1',
'Date formation 2',
'Date formation 3',
'Nombre de jours restant ',
'Nombre de formations restantes'
],
series: [202, 80, 62, 250, 52, 30],
dataLabels: {
formatter: function (val, opts) {
return opts.w.config.series[opts.seriesIndex]
},
},
}

var chart = new ApexCharts(
document.querySelector("#chart"),
options);
chart.render();

You will be able to get the default values of the series in the 2nd param (opts) of formatter function. You can use that param and get the original value instead of percentage.

svg pie chart with percentages inside

You may consider text element and adjust their position:

svg {
width: 200px;
border-radius: 50%;
background: #3f51b5;
transform: rotate(-90deg);
}
svg text {
transform: rotate(90deg);
font-size:5px;
}

circle {
fill: none;
stroke-width: 32;
r: 16;
cx: 16;
cy: 16;
}

circle.first {
stroke: #00bcd4;

}
circle.second {
stroke: #ffeb3b;
}

circle.third {
stroke: purple;
}
<svg viewBox="0 0 32 32">
<circle class='first' stroke-dasharray="34 100"></circle>
<circle class='second' stroke-dasharray="36 100"></circle>
<circle class='third' stroke-dasharray="3 100"></circle>
<text x="5" y="-11" fill="#fff">65%</text>
<text x="15" y="-26" fill="#fff">5%</text>
<text x="18" y="-17" fill="#fff">35%</text>
</svg>

Calculating the percentage for a SVG pie chart

You don't have to calculate any percentage (unless you want the percentage value)

Let SVG do the work with pathLength

With slice values: blue:10 , gold:20 , red:30 that makes: pathLength="60"

and you only have to calculate the stroke-dasharray gap (second value = 60 - value)

and stroke-dashoffset accumulative value : 10 , 30 , 60

Sample Image

More advanced use in: https://pie-meister.github.io

<style>
svg {
width:180px;
}
</style>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<path stroke-dasharray="10 50" stroke-dashoffset="10" stroke="blue"
pathLength="60"
stroke-width="50" d="M75 50a1 1 90 10-50 0a1 1 90 10 50 0" fill="none"></path>

<path stroke-dasharray="20 40" stroke-dashoffset="30" stroke="gold"
pathLength="60"
stroke-width="50" d="M75 50a1 1 90 10-50 0a1 1 90 10 50 0" fill="none"></path>

<path stroke-dasharray="30 30" stroke-dashoffset="60" stroke="red"
pathLength="60"
stroke-width="50" d="M75 50a1 1 90 10-50 0a1 1 90 10 50 0" fill="none"></path>
</svg>

CSS3 pie chart with variable percentage

If you are referring to this tutorial, the "Hold" and "pieSlice1" are just the names of the class & ID.

You could predefine a a degree then use jQuery and change the CSS depending on what you get from the database. Check out this post for some more information.

.css({ WebkitTransform: 'rotate(' + degree + 'deg)'});

http://jsfiddle.net/t7zLP/1/



Related Topics



Leave a reply



Submit