Algorithm for determining Y-axis labels and positions?
Given an array of y-values, like [-3400, -1000, 500, 1200, 3790]
, 开发者_开发技巧how do I determine "good" Y-axis labels and positions them on a grid?
^
---(6,000)-|---
|
---(4,000)-|---
|
---(2,000)-|---
|
<------(0)-+---------------------------------------->
|
--(-2,000)-|---
|
--(-4,000)-|---
V
You could do it along the following lines:
- Figure out the number of labels you want to have (
n
). The result may not have exactly this many labels, but it will be close. I'm going to haven = 6
. - Decide, what numbers do you consider “pretty”. Do you only want to see steps like 1, 2, 5, 10, 20, 50, … (in this case, pretty numbers are 1, 2 and 5) or are steps like 1, 2, 4, 5, 6, 8, 10, … good too? I'm going to consider only 1, 2 and 5.
- Find out the minimum (
min
) and maximum (max
) of the sequence, the rest of the numbers don't matter. (min = -3400
,max = 3790
) - Calculate the ideal, but ugly step between labels as
uglyStep = (max - min) / (n - 2)
. We subtract two for the label at the bottom and at the top. (uglyStep = 1797
) - Calculate the order of magnitude of the
uglyStep
asmagnitude = 10 ^ floor(log10(uglyStep))
. (magnitude = 1000
) - Pick the best pretty step, by multiplying magnitude by all pretty numbers and by ten. Then choose the number with lowest difference between it and
uglyStep
. This will beprettyStep
. (prettyStep = 2000
) - Compute the positions of the bottom and top label as
bottom = floor(min / prettyStep) * prettyStep
andtop = ceil(max / prettyStep) * prettyStep
. Note that/
denotes normal mathematical division, not C-like integer division. (bottom = -4000
,top = 4000
) - Every number between
bottom
andtop
that is divisible byprettyStep
is going to have a label. (-4000, -2000, 0, 2000, 4000
)
This might need some modifications if you don't want min
and max
to be very close to bottom
and top
.
Also, it sometimes behaves somewhat oddly, e.g. for min = 0
and max = 3002
, it chooses 0, 500, 1000, 1500, 2000, 2500, 3000, 3500
, but for max = 3005
, it uses 0, 1000, 2000, 3000, 4000
.
精彩评论