How to find the middle point of an arc slice?

242 Views Asked by At

I need to find centre of different arc in the Pie Chart. I have following details -

Similar question is here - How to find the middle point of an arc slice?

here is the reference image from above post -

enter image description here

enter image description here

My Scenario. When I move to different slice I need to calculate centre of that slice. This is the piechart centre coordinates -

cx = 330.5;
cy = 140;

First (Green) slice details -

{
    "cx": 330.5,
    "cy": 140,
    "innerRadius": 0,
    "middleRadius": 54,
    "outerRadius": 108,
    "maxRadius": 352.3850876526985,
    "startAngle": 0,
    "endAngle": 17.358490566037737,
    "midAngle": 8.679245283018869,
    "paddingAngle": 0,
    "percent": 0.04821802935010482,
}

Second (Orange) slice details -

{
    "cx": 330.5,
    "cy": 140,
    "innerRadius": 0,
    "middleRadius": 54,
    "outerRadius": 108,
    "maxRadius": 352.3850876526985,
    "percent": 0.36547868623340324,
    "startAngle": 17.358490566037737,
    "midAngle": 83.14465408805033,
    "endAngle": 148.93081761006292,
    "paddingAngle": 0,
    "percent": 0.36547868623340324,
}

Third (Gray) slice details -

{
    "cx": 330.5,
    "cy": 140,
    "innerRadius": 0,
    "middleRadius": 54,
    "outerRadius": 108,
    "maxRadius": 352.3850876526985,
    "startAngle": 148.93081761006292,
    "midAngle": 254.46540880503147,
    "endAngle": 360,
    "paddingAngle": 0,
    "percent": 0.5863032844164919,
}

I tried following formula but it did not work and not getting the expected result -

x = cx + outerRadius * Math.cos(midAngle),
y = cy + outerRadius * Math.sin(midAngle),

Update

After changing the formula to

 x = cx + outerRadius * Math.cos(midAngle * 3.14159265358979323846 / 180.0);
 y = cy + outerRadius * Math.sin(midAngle * 3.14159265358979323846 / 180.0);

I am getting following output - Completed -

{x: 437.2632503544796, y: 156.29749593485772}

enter image description here In progress -

{x: 343.3912133107331, y: 247.2278723997505}

enter image description here Not started -

{x: 301.5754291795817, y: 35.9453547271694}

enter image description here

You can see in all above three images tooltip position is not correct.

2

There are 2 best solutions below

0
On BEST ANSWER

What seems to be the issue

enter image description here

To create the above image, I simply grabbed the descriptions at their calculated positions and superimposed them on top of the original pie chart. Then, I shaded the areas where it seems that the back-end thinks the positions are. As you can see, both description boxes are positioned at the midpoint of the (mirrored) shaded regions.

How to interpret the image

It seems that the calculated angle increases in the clockwise direction, while the shown slices somehow still increase in the anticlockwise direction. In other words, when you tell it to show something at midAngle = 8.679, it thinks it should position it at an angle of -8.679 or alternatively 351.321 degrees when using the conventions of the unit circle.

What to change

To get the angle right in your program, simply change every occurrence of midAngle to -midAngle. In the comments I said changing your code to 360 - midAngle could also work, but simply making it negative will result in the same thing.

Once you've got the angle, all you need to do is tweak how far along the radius (at said angle) the description box must appear. Currently you're using the full value of outerRadius to calculate the values of x and y, but as NickD says in his answer, you could use 0.5 * outerRadius to make the boxes appear halfway the pie chart's radius.

In other words, this should work:

x = cx + 0.5 * outerRadius * Math.cos(-midAngle * 3.14159265358979323846 / 180.0);
y = cy + 0.5 * outerRadius * Math.sin(-midAngle * 3.14159265358979323846 / 180.0);

Although using Math.cos(midAngle * ...) would work just as well as Math.cos(-midAngle * ...), because $cos(\theta)=cos(-\theta)$ for all values of $\theta$.

0
On

So you want the point on the midangle of the sector and halfway from the center to the circumference:

$$ x = x_c + \frac{1}{2}R\cos(\theta) $$ $$ y = y_c + \frac{1}{2}R\sin(\theta) $$ where $\theta$ is the midangle in radians. As the comments note, you convert the midangle in degrees (denoted by $\theta_{mid}^\circ$ below) to radians by dividing by 360 and multiplying by $2\pi$: $\theta = \frac{2\pi}{360}\theta_{mid}^\circ$.

In terms of your programming variables:

x = cx + 0.5 * outerRadius * Math.cos(midAngle * 3.14159265358979323846 / 180.0);
y = cy + 0.5 * outerRadius * Math.sin(midAngle * 3.14159265358979323846 / 180.0);

although I would at least define a constant PI instead of using 3.14.... in two places:

PI =  3.14159265358979323846
x = cx + 0.5 * outerRadius * Math.cos(midAngle * PI / 180.0)
y = cy + 0.5 * outerRadius * Math.sin(midAngle * PI / 180.0)

But as you can see the only difference with your formula is the halving of the radius.