|
TextBox for Angular Meter Labels |
Posted by Electron Shepherd on Nov-07-2016 20:16 |
|
I have an angular meter to which I've added labels with a call to setScale, having set the size with setLabelStyle.
The problem I have is that the overall range of the meter (the values from minimum to maximum) are user-defined, so the number of labels varies, since they have to be "sensible". For example, a range of 0 -> 1000 uses 0, 200, 400, 600, 800 and 1000 whereas a range of 1 -> 7 would use 1, 2, 3, 4, 5, 6 and 7. Also, the overall size of the meter can change as the user resizes the window that displays it, since the meter always fills the window as far as possible. I force a certain aspect ratio (ie the meter will always fill either the width or the height of the window).
What I would like to do is to make the labels as large as possible, but without any of them overlapping. My approach to this would be to set the label font size to something large, and work out the box for each label. If any two boxes overlapped, I would then decrease the label font size a bit, and try again, until I didn't have any overlapping boxes.
However, I can't find any method that gives me the size of the box for each label. I've found the getCoor function, but that only gives me the angle from the centre for the label, not its position or size.
How can I get the box position? I know the text of each label, so I can create a Box and get its size, but to detect overlaps, I also need its position as x and y coordinates.
I know the radius of the meter, and I can get the angular position. Is there a published function that tells me where one corner of the label box is, based on the meter radius and the angle? |
Re: TextBox for Angular Meter Labels |
Posted by Peter Kwan on Nov-08-2016 04:45 |
|
Hi Electron,
Unluckily, there is no API to determine the exact location of the label. The label positioning is non-trivial and is complicated. ChartDirector will compute the label position then draws it, but it will not keep track of the label position for later use.
For your case, one approach is as follows:
(a) Create a meter with labels that can scale with the meter size. See the "Neon Round Meters" sample code included in the ChartDirector distribution for an example.
(b) Based on a reference meter size (say 500 x 500), determine the font size for the cases that the labels contain 1, 2, 3 or even 4 digits. (If you look at real meters, it is rare to see a meter with more than 3 digits. Usually, the units are chosen so that the labels will be short.) Then by using (a), the layout will work for all meter sizes.
Since there are only 4 cases, you can use testing to determine the best size for the 4 cases. In my opinion, it is better than to using the "largest possible size without labels overlapping", as you can choose the font size that is visually the best.
If you want to allow the user to choose unusual scale (like a label with 10 digits), you may consider to also allow the user to manually set the font size.
Regards
Peter Kwan |
Re: TextBox for Angular Meter Labels |
Posted by Electron Shepherd on Nov-08-2016 06:05 |
|
Peter
Thank you for confirming that there isn't a way to get the location of each label - at least I can stop searching the documentation now!
The problem is that there are many more than four cases, since I also have to allow for a variable number of labels, which, in reality, could be anything from 2 to 50. I also have to support three different meter styles (those from the first four lines of images in http://www.advsofteng.com/gallery_meter.html and those from http://www.advsofteng.com/gallery_meter2.html), all of which have different spacings for their labels.
I think what I'll have to do is:
1) Work out the height and width of the largest label, and use the larger of those dimensions to make a square.
2) For each label, use the getCoor function to determine its angle from vertical.
3) Since I know the radius and angle, I can work out a point for each label, allowing for the fact that the label is "inside" the radius.
4) Centre a square on each of these points, and then see if any overlap.
It won't be perfect, but it will probably work well enough. |
|