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
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
Submitting a Form by Pressing Enter Without a Submit Button
How to Make Css3 Rounded Corners Hide Overflow in Chrome/Opera
How to Replicate Background-Attachment Fixed on Ios
Best Practices & Considerations When Writing HTML Emails
Html5 Canvas Drawimage: How to Apply Antialiasing
Data Protocol Url Size Limitations
How to Keep Origin in Center of Image in Scale Animation
How to Prevent Column Break Within an Element
Generate an HTML Response in a Java Servlet
Create HTML Table With SQL For Xml
Force Ie Compatibility Mode Off Using Tags
Why Are My Css3 Media Queries Not Working on Mobile Devices
Css Vertical Alignment of Inline/Inline-Block Elements
How to Create Download Link in Html
Equal Width Flex Items Even After They Wrap