I am using Raphaël for the first time with little svg experience and I need someone who is really knowledgeable with these two to help me.
I have created a pie chart with dynamic sectors. The sectors can be resized by dragging on the round buttons. See this fiddle. I have only tested in Chrome and Safari which are the only required browsers.
The pie chart is not yet complete. The sectors can overlap. Please ignore this for now.
I was faced with problems, when the starting angle of a sector was greater than the ending angle. This is the case when the ending angle goes past the 0/360° mark. To solve this I made use of the path-rotation-parameter. I moved the sector forward while moving the angles back, until the end angle is at 360. You can see this in the fiddle in this function:
function sector_update(cx, cy, r, startAngle, endAngle, sec) {
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);
var rotation = 0;
// This is the part that I have the feeling could be improved.
// Remove the entire if-clause and let "rotation" equal 0 to see what happens
if (startAngle > endAngle) {
rotation = endAngle;
startAngle = startAngle - endAngle;
endAngle = 360;
}
sec.attr('path', ["M", cx, cy, "L", x1, y1, "A", r, r, rotation,
+(endAngle - startAngle > 180), 0, x2, y2, "z"]);
}
Although it works nicely, I’m a bit skeptical. Can this be solved without the rotation of the path? I appreciate any help or pointers.
Can this be solved without the rotation of the path?Answer: Yes, it can. You don’t have to change the rotation of the path at all. Unless I’m missing something, the following code seems to work the same as what you have in the fiddle:
Explanation: For my explanation, I will use the SVG terminology in the
W3 Spec and Raphael Reference Library. That is, while you use
cx,cy, androtation, these userx,ry, andx-axis-rotationrespectively.In short, whenever
rxequalsry, thenx-axis-rotationis meaningless.Look at this SVG. Use your browser’s development tools, or save the SVG to your computer and use a file editor to edit it. Specifically, look at the last
pathelement, which has four arcs in it. Try modifying thex-axis-rotationvalue on each arc. You will notice that the first arc (whererxandryare both “25”) never changes when you updatex-axis-rotationvalue.Why? This is because you have a circular arc. No matter how much you rotate a circle, it will still be the same circle. For example, hold up a glass in front of you so that the glass is horizontal to the ground, and you are looking directly down the glass. Now rotate/twist the glass with your wrist. Do you see how the circular shape you see stays in the same circular shape? Now set the glass on the table normally (so it is vertical and could hold a liquid). Now tip the glass over. You can see the obvious perspective change; it was pointing up, but now it is laying flat. That is what
x-axis-rotationdoes.Perhaps a better example is to just play around with the aforementioned SVG file. Play with
x-axis-rotationon the arcs in the finalpathelement. You will see the arcs being rotated around. That is whatx-axis-rotationdoes.Back to your code: Because you are dealing only with circular objects, the
x-axis-rotationwill make no difference on the final output. So long as you are only dealing with circular objects, you can hard-code it’s value to zero without any worries. All you really needed to do is modify the angles, which you had done correctly.Performance: I tried using JavaScript to time your
sector_updatefunction both with and without modifying thex-axis-rotationvariable. The result? I saw no difference in performance. The majority of the time spent is on actually drawing the SVG, not on the math that determines it’s values. In fact, all you are really doing in JavaScript is updating the code to set the value in thepathelement. At that point in time, the browser takes over with it’s rendering engine to actually draw the SVG object. I suppose then it’s a per-browser issue, as each browser has different rendering performance. But as for whether or not thex-axis-rotationvalue has any effect, my guess is no. If there is a performance hit (because the browser may have to do an additional floating-point operation), it is so incredibly moot because the overwhelming majority of the time is spent drawing the object, not calculating it’s values. So I would say not to worry about it.I hope that helps, let me know if I missed something or didn’t explain something well enough.