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:

Hollow Pie chart representation

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

stroke-dasharray:

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 , the stroke-dasharray would look like:

stroke-dasharray:

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 and the second , 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 (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 off, it is better to rotate all these circles by or 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.