woland woland - 1 month ago 10
Javascript Question

how to position label inside a pie chart slice

I'm creating a pie chart and stumbled upon a though:

how do i place a slice label inside the slice?

I want the label to be in the middle of the slice and fit inside the slice entirely.

Currently I'm computing the position for the label by

center.y - sliceStartPoint.y / 2
and
sliceStartPoint.x + 10


but it has poor results.

How to compute label bounds effectively?

The calculation should work for any slice, wide or thin.

Answer

Well, in a Pie chart, you most likely would like to place the label in the middle.

where in the circle is no much of a problem:
so if your slice is from 0.1[rad] to 0.3[rad] then you should place it along the avarage radious (0.1[rad] + 0.3[rad])/2 = 0.2[rad] radius.

the tricky part is where along the radius:
your triangle is 'isosceles' so given height from it's TOP, the width between it's polygonals is easy to determine,
tg(alpha/2) = (w/2) / h
h = w/2 / tg(alpha / 2)

= edit start =
image presenting the calculation of W

Build Aid: height through middle
Build Aid: line AB parallel to Triangle Base

  1. OMB = 90 = 1/4rad (height of the Triangle)
  2. AM = BM (isosceles)
  3. MOB = Aplha / 2 (isosceles)
  4. tg(MOB) = MB/OM
    tg(alpha/2)= (w/2) / h
    h tg(alpha/2) = w/2
    2h tg(alpha/2) = w

tg(a) is a mathematical shorthand for tan(a).
which is a trigonometric function (easy explanation of Sin, Cos & Tan here)

JS has Tan() built in (see this link)

= edit end =

so determine the width(w) you need for your label, and calculate h

if h is larger than your PIE-Chart radius, you are placing the label outside the Chart, you should consider a constant R for that with a nice looking line.

cheers.

-- Edit 2 -- Note, there are two things to consider :

  1. when your slice is larger than pi[rad] = 180 deg, the above calculation will fail, but in this situation the label should fit nicely.

  2. you should specify at what minimum distance from the center along the radius you want your label, and if h comes lesser then, just use the minimum. (i'd say about 0.7r is a good value, but make it configurable.

Comments