I am still new to SVG and its quite exciting whenever I come to know more about it. Recently, I did an experiment with stroke-dasharray
an SVG presentational attribute. It amazed me when I came to know how tricky and mysterious it can be.
Let me explain my requirement where I need a multi color donut chart, as shown in the below image:
Source: https://commons.wikimedia.org/wiki/File:Vega-piechart.png
From Lea’s article, I came to know how to create a basic donut chart using SVG’s stroke-dasharray
. So I decided to create a multi-coloured donut chart without using any library. I just need to build my own component based on Lea’s idea. To summarize lea’s article, it all comes down to coloring the required potion of circle’s circumference with specified color
So, in stroke-dasharray
, we will have two values, first will be the circumference in required percentage and the next will be the circumference itself. i.e
Now, if I have the following circle
:
<svg>
<circle cx="50" cy="50" r="50"></circle>
</svg>
As the radius for circle is 50
and assumed applied percentage is 60%, the stroke-dasharray
would look like:
As stroke-dasharray
is a presentational attribute, we can apply the above using css:
circle {
stroke-dasharray: calc(2 * 22 / 7 * 50), calc(2 * 22 / 7 * 50 * 60 / 100);
stroke-width: 10;
}
The circumference formula in above calculation needn’t to be executed on runtime. So, I will switch over to SCSS to precompile the calculation and make the code more readable (this step is not redundant but still who doesn’t love SCSS ? ).
circle {
$pi: 22/7;
$radius: 50;
$circumference: 2 * $pi * $radius;
stroke-dasharray: calc(#{$circumference} * 60 / 100), #{$circumference};
stroke-width: 10;
}
Again since the percentage value is dynamic, it is better to handle the stroke-dasharray
value using JavaScript (even the circumference calculations). But if you are fine with CSS Custom Variables then you can do as follows:
:root {
--percent: 0; // default value
}
circle {
$pi: 22 / 7;
$radius: 50;
$circumference: 2 * $pi * $radius;
stroke-dasharray: calc(#{$circumference} * var(--percent), #{$circumference};
stroke-width: 10;
}
The above explanation just covers the fundamentals to create a single pie in donut chart. Now to create another pie inside the donut chart, we need to create another circle inside SVG.
<svg>
<circle class="pie-one" cx="50" cy="50" r="50"></circle>
<circle class="pie-two" cx="50" cy="50" r="50"></circle>
</svg>
If we say the first pie holds 60% and the second 20%, then second pie would start from on top of the first pie’s stroke when it is rendered because the circle positions are same, hence the stroke color will be overlapping one on another. To make the second pie visible, we need to rotate it by 60% (i.e first pie’s percentage). i.e
Well if there is another pie, we need to rotate it by first pie's percentage + second pie's percentage
. Since all pie diagrams start with a 90o off, it is better to rotate all these circles
by -90o or 270o maybe through a parent element i.e a group
tag.
<svg>
<g class="circles">
<circle class="pie-one" cx="50" cy="50" r="50"></circle>
<circle class="pie-two" cx="50" cy="50" r="50"></circle>
<circle class="pie-three" cx="50" cy="50" r="50"></circle>
</g>
</svg>
.circles {
transform: rotate(-90deg);
}
As in the real scenario, the circles could be dynamic, it is better to generate the circles through JavaScript and pass the percentage values through an object. I got my donut chart by following the above steps, hope it will be helpful to you as well.
See the Pen Hollow pie chart by venkateshwar (@Mr_Green) on CodePen.
Recent Articles



I like this post.