Raphael Pie Chart Part 1

So awhile back I created a pie chart in raphael without the use of the SVG arc command. So, my old pie chart works, but it has lots of vector points – it’s all done with moveTo and lineTo. Rather than use the pie chart example from Raphael, I wanted to see if I could create my own from scratch. I got 80% there but then had to peak at how this (http://raphaeljs.com/growing-pie.html) example works. Here are a few arcs put together:

And here is the source code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title></title>
    <script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
    <script src="raphael-min.js"></script>
    <script>
      $(function(){
 
        var p = new Raphael(0,0,"100%","100%");
 
        p.path(arc(200,200,150,0,2) +
               arc(200,200,150,2,3) + 
               arc(200,200,150,3,4.5) + 
               arc(200,200,150,4.5,5) + 
               arc(200,200,150,5,Math.PI*2)).attr("stroke", "white");
 
        function arc(x, y, radius, start, end){
          var f = ((end - start) > Math.PI) ? 1 : 0;
 
          var sx = radius * Math.cos(start);
          var sy = radius * Math.sin(start);
          var ex = x + radius * Math.cos(end);
          var ey = y + radius * Math.sin(end);
 
          var path = "M " + x + " " + y + " l " 
              + sx + " " + sy + " A " + radius 
              + " " + radius + " 0 " + f + " 1 " 
              + ex + " " + ey + " z";
          return path;
        }
 
      });
    </script>
    <style>
      body,html{
        background-color : #333;
      }
    </style>
  </head>
  <body>
 
  </body>
</html>

SVG arc commands are pretty confusing. I had a few problems making this. The first was that I used “L” instead of “l”. Turns out “l” is relative positioning. Another problem was the large-arc-flag and the sweep-flag. I’m still not sure I fully grasp these.

Unlike the one in the example from raphaeljs.com I wanted my arc function to use radians. Over the years I’ve just gotten used to working in radians instead of degrees. I also prefer building a large string rather than using a series of arrays to define a path. Here is what the arc segment function looks like from raphaeljs.com:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
r.customAttributes.segment = function(x, y, r, a1, a2) {
  var flag = (a2 - a1) > 180,
      clr = (a2 - a1) / 360;
  a1 = (a1 % 360) * Math.PI / 180;
  a2 = (a2 % 360) * Math.PI / 180;
  return {
    path: [
      ["M", x, y],
      ["l", r * Math.cos(a1), r * Math.sin(a1)],
      ["A", r, r, 0, +flag, 1, x + r * Math.cos(a2), y + r * Math.sin(a2)],
      ["z"]
    ],
    fill: "hsb(" + clr + ", .75, .8)"
  };
};

I formatted this a bit for readability.



 
 
 

Leave a Reply

Spam protection by WP Captcha-Free