Creating a multi-sliced SVG Pie Chart

Hello. I am trying to learn how to create a pie chart using SVG.

The key is that the solution needs to handle multiple slices. (There are lots of tutorials on how to do a simple CSS pie chart with just two halves, but that isn’t what I need.)

I have spent the last couple of weeks reading up on SVG, but there aren’t any really good tutorials/solutions on this particular problem…


Here is a link to a solution that looks promising, but I don’t completely understand the code, and it doesn’t seem like it has any math behind it. (These pie charts are for a business, so “hacking” things until they look “close” won’t do!)

https://codepen.io/hari2609/full/LmEzOm

image


How does the following code work…

<circle r="25%" cx="50%" cy="50%" style="stroke-dasharray: 75.3 100"></circle>


Here is what I think is going on…

  • You create a ViewBox starting at 0, 0 and which has a grid of 64 x 64.

  • You resize the final results to 300px X 300px using CSS

  • You give the SVG a border-radius of 50% making it a circle. (Not sure why this is needed as you have a <circle> below?)

  • You create an SVG <circle> centered in the middle of the grid

  • It has a radius of 25% which makes a circle that is 1/2 the width and height of the parent SVG canvas. (The “circle” is more like a “ring”.)

  • You give the <circle> a stroke-width of 32 which adds a border to the aforementioned circle that is so wide that the circle “ring” becomes a filled circle that has a radius of 32 units.

  • The gold stroke makes it a gold filled circle.


Now for the part that escapes me…

  • You add a stroke-array: 75.3 100


Questions:

Q1.) How does stroke-array: 75.3 100 end up drawing a pie-chart SLICE that is roughly three-quarters of the entire pie?

Q2.) And how does the modified code of stroke-array: 50.3 100 yield a SLICE that is roughly one-half that of the entire pie?

Q3.) Is there a way to create slices using a more mathematical/geometric methd?

Again, I need pie slices that accurately display precise percentages (e.g. 47.5%, 25%, 12.5%, 8.4%, 6.6%) and that ultimately visually add up to a whole pie (i.e. 100%).

Thanks.


P.S. It is also important to come up with an SVG solution that can be programmed in PHP on the server. So, even though I could draw the Statue of Liberty using SVG paths, that isn’t practical to program! The hope is that i can query MySQL, build a result-set that is basically a table of Category-Value pairs, and then use those values to drive how big each pie-slice is. (If I can figure out the code above, it seems like a simple enough way to program in PHP.)

<svg  
   xmlns="http://www.w3.org/2000/svg" 
   viewBox="0 0 254 254">
   <path d="M 120 120, 120 20 A 100 100 0 0 1 170 33z" fill="#f00" stroke-width="1" stroke="#000"/>
   <text x="142" y="18">30&deg;</text>
 </svg>

svg arc creator

1 Like

The circle has a radius of 25% which is 16 viewBox user units. Its circumference 2πr is therefore 100.53 viewBox user units (ignoring stroke width).

The CSS stroke-dasharray: 75.3 100 creates a stroke along the circumference of the circle of length 75.3 user units. The 100 creates a gap in the stroke which is more than sufficient to complete the path around the circumference.

Just use 100.53 as the circumference of the circle.

The choice of viewBox dimensions is quite arbitrary. I doubt the 64x64 was chosen to give a circumference close to 100.

1 Like

2 Likes

@improbabilis
I had wondered about creating the sectors using paths with the ‘A’ or ‘a’ arc command but I think the method demonstrated in the original post is better because it avoids you having to work out the x-y coordinate positions of the corners of each sector (excluding the corners at the centre of the pie chart).

On the other hand, your method allows great animation.

1 Like

@improbabilis,

Sorry, for the late response, but an emergency came up.

It looks like drawing each slice is a better way to go, huh?

As mentioned, I have been away for a while dealing with an emergency, so my head is has lost track of all of this.

@Archibald, I was able to figure out reading online a few weeks ago, that you can turn the stroke-dasharray to refer to length versus be a ratio.

And if you make it so that your circle’s circumference is exactly 100, then you can make the first number a simple percentage, as in, stroke-dasharray: 75 100 would mean 75% for a circle where the radius leads to a circumference of 100 units.

That is understandable enough, but where things get weird is when you try and create a pie chart with multiple slices like @Improbabilis showed below.

I don’t have my test code handy - nor is my brain into it at the moment - but I didn’t follow how the sample I posted works with multiple slices, and when I played around with the code from CodePen it didn’t make much sense how the end result was happening.

To your point, I like the “precision” of @Improbabilis’s code, but fear that is too hard to automate with code.

Yet I also question how viable the CodePen sample I posted in my OP is also.

@Improbabilis, can you explain more how your code works?

From the little I have learned, M 120 120 would move the cursor to x=120, y=120, and then from there it’s fuzzy…

(I wish you could use the FireFox Dev Tools to hover over and click on SVG’s the way you can with HTML elements so you can learn by clicking…)

Thanks!

I was wondering was @Improbabilis’s name wasn’t auto-completing, and now I see this “new” member was a previously “suspended” member.

Snap!!

Just when I was making progress! :frowning:

Can someone please step in and try to answer my questions above about @Improbabilis’s code?

Thanks.

Note in the CodePen in your original post that stroke-dashoffset is used to control where each colour of stroke (i.e slice) starts.

So make the radius 15.9155 viewBox user units and the stroke width 31.83.