1

I want to make a pie chart in donut style with bent labels in the particular donut sectors, like this one:

enter image description here

In this mockup, the user has clicked on the "Raphael.js" sector. Now for the clicked sector there should also be an event handler which is responsible for display a new HTML Div below the pie chart and display some information. The perfect solutions would be, if the donut would rotate so that the clicked sector is at the bottom.

Can anybody help?

c0bra
  • 2,982
  • 23
  • 34
eff8691
  • 67
  • 7

1 Answers1

3

Here's some code to create text along a path. It's not perfect, but it will get you far enough along to specify for your own project.

var paper = Raphael(0, 0, '100%', '100%'),
    r = 200,
    path = paper.path("M100,50a" + r + "," + r + " 0 0,1 " + r + "," + r).attr({ stroke: "#000", 'stroke-width': '40px'}),
    message = "Raphael.js",
    message_length = 0,
    letters = [],
    places = [],
    ratio,
    fontsize,                                                
    letter,
    c = 0,
    p;


//since not every letter is the same width, get the placement for each letter along the length of the string
//however, Raphael appears to group the width of letters into intervals of 4px, so this won't be perfect        
for (; c < message.length; c += 1) {
    letter = paper.text(0, 0, message[c]).attr({"text-anchor" : "start"}).attr({fill: '#FFF'});
    letters.push(letter);
    places.push(message_length);
    //spaces get a width of 0, so set min at 4px
    message_length += Math.max(4, letter.getBBox().width);
}

ratio = path.getTotalLength() / message_length;
fontsize = 8 * ratio;

for (c = 0; c < letters.length; c += 1) {
    letters[c].attr("font-size", fontsize + "px"); 
    p = path.getPointAtLength(places[c] * ratio);
    //there does appear to be a bug in p.alpha around 180. Here's the fix
    letters[c].attr({ x: p.x, y: p.y, transform: 'r' + (p.alpha < 180 ? p.alpha + 180 : p.alpha)});
}

jsFiddle

As for the other stuff, you'll need to work on yourself first and pose specific questions if you hit a wall.

Chris Wilson
  • 6,599
  • 8
  • 35
  • 71