mheavers
mheavers

Reputation: 30158

raphael.js - converting pie graph to donut graph

I'm trying to use a raphael.js example located here:

http://raphaeljs.com/pie.html

but I want to convert the pie graph into a donut graph (have a hole in the middle of all the slices). Currently, each slice is being created with the following code:

function sector(cx, cy, r, startAngle, endAngle, params) {
        //console.log(params.fill);
        var x1 = cx + r * Math.cos(-startAngle * rad),
            x2 = cx + r * Math.cos(-endAngle * rad),
            y1 = cy + r * Math.sin(-startAngle * rad),
            y2 = cy + r * Math.sin(-endAngle * rad);
        return paper.path(["M", cx, cy, "L", x1, y1, "A", r, r, 0, +(endAngle - startAngle > 180), 0, x2, y2, "z"]).attr(params);
    }

How would I modify this so that a hole of a fixed radius was removed from the overall pie? I saw this post here, which helps, but I can't quite tell how or where to apply it to my code above:

How to achieve 'donut holes' with paths in Raphael

Upvotes: 4

Views: 3958

Answers (2)

Chris Ghenea
Chris Ghenea

Reputation: 12943

The way how one slice of the pie is created is like this:

  1. move to the center of the circle (cx,cy): "M", cx, cy
  2. draw a line until the edge, where the arc will start (x1,y1): "L", x1, y1
  3. draw an arc based on some mathematical calculations: "A", r, r, 0, +(endAngle - startAngle > 180), 0, x2, y2
  4. draw a line back to the middle of the circle: in this case "z" is used; it means move to origin(cx,cy)

and the slice(path) is ready.

In order to create the donut you need to modify how the path is composed. You need to have a path composed of 2 arcs(inside and outside) and 2 lines to complete it.

So first you need to find the starting point for the path, based on the radius of the imaginary empty circle that will be in the middle of the donut (with the radius rin). Lets call the coordinates of this point xx1 and yy1:

xx1 = cx + rin * Math.cos(-startAngle * rad)
yy1 = cy + rin * Math.sin(-startAngle * rad)

You start building the path from this point( "M", xx1, yy1 ); http://jsfiddle.net/EuMQ5/425/

Next step is to draw the line to the edge of the circle( "L", x1, y1 ). From there you will have to draw the outer arc( "A", r, r, 0, +(endAngle - startAngle > 180), 0, x2, y2 ) then one more line to the other edge of the inner arc( "L", xx2, yy2 ). To get the values for xx2 and yy2:

xx2 = cx + rin * Math.cos(-endAngle * rad)
yy2 = cy + rin * Math.sin(-endAngle * rad)  

and the last step is to complete the path by drawing the inner arc( "A", rin, rin, 0, +(endAngle - startAngle > 180), 1, xx1, yy1 ). And now you have a piece of a donut.

The fiddle is here.

**updated fiddle link

Upvotes: 20

lexx
lexx

Reputation: 141

Why dont you just draw a circle at the center of the pie chart?

paper.add([
    {
        type: "circle",
        cx: 250,
        cy: 250,
        r: 150,
        fill: "#ffffff"
    },
]);

Upvotes: 0

Related Questions