How to define matching axis notches from existing “step list”

匆匆过客 提交于 2019-12-24 02:09:30

问题


I need a way to align tick marks on two separate axis, while being able to control the "step" value (value between tick marks), where both axis start at mark 0 and end on a different maximum value.

Why this problem:

Flot, the JS charting package has an option to align tick marks, but when I do, I cannot control the step value. I can however control the step value directly, but then I lose the ability to align tick marks. I can however revert to defining my own max and step values, to get what I need (aligned tick marks while maintaining desired step value), but I need some help. yielding this question (read on for details).

Example

Let a be maximum value on axis A and b, be maximum value on axis B.

In this example, let a = 30, and b = 82. Let's say I want 6 tick marks (not counting the extra tick mark at end of axis). In reality I guessed at 6 after trying out a few.

Once I have a desired number of tick marks, I can do something like this:

  • 30 / 6 = 5 (I just go the needed step value for axis A)
  • Now need to figure out tick alignment for axis B
  • 82 / 6 = 13.67 (not a good value, I prefer something more rounded)
  • move max value of B to 90 , where 90 / 6 = 15 (good - I just got the needed step value for axis B)

End Result

Input:

  • a_max = 30, b_max = 82
  • (in reality a_max could be 28.5, 29.42, b_max could be 84, 85.345, etc)

Output:

  • a_adjusted_max = 30, b_adjusted_max = 90,
  • a_step = 5, b_step = 15
  • number of ticks = 6 (+1 if count the end)

Visual:

|---------|---------|---------|---------|---------|---------> A
0         5        10        15        20        25        30

|---------|---------|---------|---------|---------|---------> B
0        15        30        45        60        75        90

Summary of "Demands"

  • Need step value for each axis to be one of 1, 2, 5, 10, 15, 20, 25, 50, 100 (in example was 5 for A, 15 for B)
  • Need adjusted max value for each axis (in example was 30 for A, 90 for B)
  • Need number of ticks to match for both axis
  • (optional) Number of ticks is flexible but should be anywhere between 4 and 12 as a sweet spot
  • adjusted max value is at or greater than original max value, and is located at a "rounded number" (i.e. 90 is prefered over 82 as in my above example)

Problems (Question)

  • I need to remove most of the guessing and automate tick mark generation.
  • i.e. at first, I Need better way to get number of tick marks because I guessed at number of tick marks I wanted above, because I wanted a good "step" value, which can be something like 1, 2, 5, 10, 15, 20, 25, 50, 100. Max values start at 4, and can go up to 100. In rarer cases go up to 500. In most cases the max values stay between 30-90.

How can I do so?


回答1:


Here's a procedure I came up with. I'm assuming you only want integers.

  • choose a number of ticks from 4 to 12
  • calculate the number of steps needed for the A and B axes using this number of ticks
  • find how much we would have to extend axis A and axis B using these step values; add these numbers together and remember the result
  • repeat from the start for the next tick value
  • we choose the number of ticks that gives the minimal score; if there is a tie we choose the smaller number of ticks

Here are some example results:

a=30, b=82 gives 4 ticks

 0    10    20    30
 0    28    56    84

a=8, b=5 gives 6 ticks

 0     2     4     6     8    10
 0     1     2     3     4     5

Here's the pseudocode:

a = range of A axis
b = range of B axis

tickList[] = {4,5,6,7,8,9,10,11,12}

// calculate the scores for each number of ticks
for i from 0 to length(tickList)-1
    ticks = tickList[i]

    // find the number of steps we would use for this number of ticks
    Astep = ceiling(a/(ticks-1))
    Bstep = ceiling(b/(ticks-1))

    // how much we would need to extend the A axis
    if (a%Astep != 0)
        Aextend[i] = Astep - a%Astep
    else
        Aextend[i] = 0
    end

    // how much we would need to extend the B axis
    if (b%Bstep != 0)
        Bextend[i] = Bstep - b%Bstep
    else
        Bextend[i] = 0
    end

    // the score is the total extending we would need to do
    score[i] = Aextend[i] + Bextend[i]

end


// find the number of ticks that minimizes the score
bestIdx = 0
bestScore = 1000;

for i from 0 to length(tickList);
    if (score[i] < bestScore)
        bestIdx = i
        bestScore = score[i]
    end
end

bestTick = tickList[bestIdx]
bestAstep = ceiling(a/(bestTick-1))
bestBstep = ceiling(b/(bestTick-1))

A axis goes from 0 by bestAstep to bestAstep*bestTick

B axis goes from 0 by bestBstep to bestBstep*bestTick



来源:https://stackoverflow.com/questions/28285412/how-to-define-matching-axis-notches-from-existing-step-list

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!