Graph axis labelling
Here's a reasonably interesting requirement for an algorithm - well I think so anyway.
Given any arbitrary range of numbers that represent plottable points along a graph axis, display suitable labelled grid divisions along the axis with "human meaningful" amounts on the labels. The graph axis should display as many evenly spaced labelled divisions as will comfortably fit on the screen taking into account the size of the text labels (which are to be displayed parallel to the axis rather than perpendicular to it).
For example - the graph axis has to represent numbers in the range 502 - 179,457. The graph axis is 500 pixels long, and therefore depending on the exact length of digits of the division labels (at say 10 point font), approximately 10 labels will fit comfortably along the axis.
Now by "making the labels human meaningful", what I am saying is that there are some rules of thumb that would probably apply, such as:
500 is better than 501 (rounding)
150 is better than 140 (half vs odd fraction)
120 is better than 110 (even vs odd last significant digit)
5K is better than 5000 (short text)
One of the main issues I feel is how to handle small numbers and large numbers on the same graph axis like in the example above where strictly even divisions are likely to be values like:
502; 20,452; 40,401; 60,350; 80,300; 100,249; ... 179,457.
These amounts are obviously not "human meaningful" as graph labels, and I would expect that the divisions would be laid out more like:
20,000; 40,000; ... 160,000 (or even 20K; 40K; 60K; etc)
Obviously the 20,000 division will not be at the beginning of the axis in this case.
I think I can see what needs to be done...
1. Work out approximately how many divisions will phisically fit along the axis taking into account font size and likely printed number size (i.e. 50 vs 250,300).
2. Calculate the logical size of a division based on the ratio of logical graph span vs physical space in pixels.
3. Look for "round" logical values near to the calculated size.
4. Retry steps 2 and 3 with maybe +/- one whole division for the axis. Hopefully from this a "round" logical division length can be found.
5. Determine the nearest multiple of the logical division >= the axis start value.
6. Lay out the divisions physically across the graph axis using the ratio of logical to physical division size for each division drawn (this will reduce positional rounding errors).
7. Display each division label in "human meaningful terms" - use K for large numbers unless the logical divisions are small - and this is the hard bit in some ways because the graph may be trying to represent 200,000 to 200,500 in 10 divisions, so you couldn't shorten to 200K because the second division would be 200,050. Or the axis could be representing 1000 to 10,000 in which case 1K; 2K; 3K would be fine.
I'm sure this has been solved before, but it seems to me that there are a few curly ones in all this that make it an interesting challenge.
Regards,
Tim

