Once upon a time, a clever student loaded an entire library to create a simple pie chart. Well, it works, but a bloated library also slows the loading significantly. The next question is – Why load an entire library when we can literally create a simple pie chart with a few lines of code. Let Master Coffee show you how, let’s go.
CODE DOWNLOAD
I have released this under the MIT license, feel free to use it in your own project – Personal or commercial. Some form of credits will be nice though. 🙂
VIDEO TUTORIAL
1) PIE CHART WITH HTML CSS ONLY
1A) PIE CHART DEMO
1B) THE HTML & CSS
<style>
#demoA {
/* (PART A) RESPONSIVE CIRCLE */
max-width: 200px; height: auto;
aspect-ratio: 1/1; border-radius: 50%;
/* (PART B) PIE CHART SEGMENTS */
background: conic-gradient(
red 0deg 70deg,
green 70deg 240deg,
blue 240deg 360deg
);
}
</style>
<!-- (PART C) EMPTY DIV -->
<div id="demoA"></div>
Look no further, that’s all it takes to create a pie chart.
- (C) For the HTML, all we need is a
<div>
container. - (A) Turn the container into a responsive square with
max-width: 200px; height: auto; aspect-ratio: 1/1
, then into a circle withborder-radius: 50%
. - (B) Add the pie chart segments with
background: conic-gradient(SEGMENT, SEGMENT, ...)
. For those who do not know how a circle “works”:- A circle goes round 360 degrees.
- So for each
SEGMENT
, we defineCOLOR FROM-DEGREE TO-DEGREE
.
- (B) The bad part about this method is that it needs manual calculations. An example:
- Let’s say we have the values –
RED 3, GREEN 2, BLUE 5
. - The total sum will be
3 + 2 + 5 = 10
. RED
will take up3 ÷ 10 X 360 = 108deg
,GREEN
will take up2 ÷ 10 X 360 = 72deg
,BLUE
will take up5 ÷ 10 X 360 = 180deg
.- Draw the CSS segments –
red 0deg 108deg, green 108deg 180deg, blue 180deg 360deg
.
- Let’s say we have the values –
P.S. For the trolls who are thinking this is not responsive, maybe a variable width will be more obvious. Example – width: 20%
or width: 20vw
.
2) PIE CHART WITH JAVASCRIPT
2A) PIE CHART DEMO
2B) THE HTML
<!-- (PART A) LOAD CSS JS -->
<link rel="stylesheet" href="2-piechart.css">
<script src="2-piechart.js"></script>
<!-- (PART B) EMPTY CONTAINER -->
<div id="demoB"></div>
<!-- (PART C) CREATE PIECHART -->
<script>
window.addEventListener("load", () => {
pie (document.getElementById("demoB"), [
["Birb", 12.3, "red"],
["Cate", 23.4, "green"],
["Doge", 34.5, "blue"]
]);
});
</script>
The previous example works, but not for dynamic reports. So here it is, a Javascript variant if you need to generate the pie chart dynamically.
- Load the pie chart CSS and Javascript.
- The same, all we is a
<div>
container. - Lastly, call
pie(TARGET, SEGMENTS)
to generate the pie chart. TheSEGMENTS
is a nested array, in the format of[NAME, VALUE, COLOR]
.
2C) THE CSS
/* (PART A) PIECHART */
.pie {
max-width: 200px; height: auto;
aspect-ratio: 1/1; border-radius: 50%;
}
/* (PART B) LEGEND */
.legend { margin-top: 30px; }
.legend .row { display: flex; align-items: center; margin: 10px 0; }
.legend .color { width: 30px; height: 30px; border-radius: 50%; margin-right: 5px; }
- The CSS pretty much remains the same, except that we will generate the segments using Javascript instead.
- A small addition, we now add a legend to the pie chart.
Feel free to style the legend, change the size of the pie chart however you wish.
2C) THE JAVASCRIPT
function pie (target, segments) {
// (PART A) CREATE PIE CHART & LEGEND
let pie = document.createElement("div"),
legend = document.createElement("div");
pie.className = "pie";
legend.className = "legend";
target.appendChild(pie);
target.appendChild(legend);
// (PART B) TOTAL VALUE
let total = 0;
for (let s of segments) { total += s[1]; }
// (PART C) ADD PIE CHART & LEGEND SEGMENTS
let from = 0, to = 0, css = "";
for (let s of segments) {
// (C1) PIE CHART SEGMENT
to = from + Math.ceil(s[1] / total * 360);
if (to > 360) { to = 360; }
css += `${s[2]} ${from}deg ${to}deg,`;
from = to;
// (C2) LEGEND SEGMENT
let row = document.createElement("div");
row.className = "row";
row.innerHTML = `<div style='background:${s[2]}' class="color"></div> <div>${s[0]} (${s[1]})</div>`;
legend.append(row);
}
pie.style.cssText = `background: conic-gradient(
${css.substring(0, css.length-1)}
)`;
}
This can be seemingly intimidating to beginners, but read through, and it is actually very straightforward.
- Create an empty pie chart and legend –
<div class="pie"></div> <div class="legend"></div>
. - Loop through the segments, sum all the values together to get the total.
- Loop through the segments once again.
- (C1) Calculate and create the pie segments –
VALUE / TOTAL * 360
. - (C2) Create the legend segments.
- (C1) Calculate and create the pie segments –
THE END – ROUNDING ISSUES
That’s all for this short tutorial. One small note before we end, I am rounding up the calculations using Math.ceil()
in the above example. If you want “more precision”, feel free to change the rounding. Maybe to the nearest 2 decimal points.
CHEAT SHEET