Как определить соответствующие выемки осей из существующего списка шагов

Мне нужен способ выровнять метки на двух отдельных осях, имея возможность контролировать значение «шага» (значение между метками), где обе оси начинаются с отметки 0 и заканчиваются другим максимальным значением.

Почему эта проблема:

Flot, в графическом пакете JS есть возможность выравнивать деления, но когда я это делаю, я не могу контролировать значение шага. Однако я могу напрямую управлять значением шага, но тогда я теряю возможность выравнивать деления. Однако я могу вернуться к определению своих собственных максимальных значений и значений шага, чтобы получить то, что мне нужно (выровнять деления при сохранении желаемого значения шага), но мне нужна помощь. уступив этот вопрос (подробности читайте дальше).

Пример

Пусть a будет максимальным значением по оси A, а b будет максимальным значением по оси B.

В этом примере пусть a = 30 и b = 82. Допустим, мне нужно 6 делений (не считая дополнительной деления в конце оси). На самом деле я угадал 6, попробовав несколько.

Когда у меня есть желаемое количество делений, я могу сделать что-то вроде этого:

  • 30 / 6 = 5 (я просто выбираю нужное значение шага для оси A)
  • Теперь нужно выяснить выравнивание галочки для оси B.
  • 82 / 6 = 13,67 (не очень хорошее значение, я предпочитаю что-то более округлое)
  • переместите максимальное значение B на 90 , где 90/6 = 15 (хорошо - я только что получил необходимое значение шага для оси B)

Конечный результат

Вход:

  • а_макс = 30, б_макс = 82
  • (на самом деле a_max может быть 28,5, 29,42, b_max может быть 84, 85,345 и т. д.)

Выход:

  • a_adjusted_max = 30, b_adjusted_max = 90,
  • а_шаг = 5, б_шаг = 15
  • количество тиков = 6 (+1, если считать конец)

Визуальный:

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

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

Сводка "Требования"

  • Нужно, чтобы step value для каждой оси было одним из 1, 2, 5, 10, 15, 20, 25, 50, 100 (в примере было 5 для A, 15 для B)
  • Нужно adjusted max value для каждой оси (в примере было 30 для A, 90 для B)
  • Нужно количество тиков до match для обеих осей
  • (необязательно) Количество тиков может варьироваться, но должно быть где-то от 4 до 12 в качестве оптимального значения.
  • скорректированное максимальное значение равно или превышает исходное максимальное значение и расположено в «округленном числе» (т.е. 90 предпочтительнее 82, как в моем примере выше)

Проблемы (вопрос)

  • Мне нужно удалить большую часть догадок и автоматизировать генерацию делений.
  • то есть сначала мне нужен лучший способ получить количество делений, потому что я угадал количество делений, которое хотел выше, потому что мне нужно хорошее значение "шага", которое может быть примерно 1, 2, 5, 10, 15, 20, 25, 50, 100. Максимальные значения начинаются с 4 и могут доходить до 100. В более редких случаях доходят до 500. В большинстве случаев максимальные значения остаются между 30-90.

Как я могу это сделать?


person Dennis    schedule 02.02.2015    source источник


Ответы (1)


Вот процедура, которую я придумал. Я предполагаю, что вам нужны только целые числа.

  • выберите количество тиков от 4 до 12
  • вычислить количество шагов, необходимых для осей A и B, используя это количество тиков
  • найти, насколько мы должны были бы расширить ось A и ось B, используя эти значения шага; сложите эти числа вместе и запомните результат
  • повторить с самого начала для следующего значения тика
  • мы выбираем количество тиков, которое дает минимальный балл; если есть ничья, мы выбираем меньшее количество тиков

Вот несколько примеров результатов:

a=30, b=82 дает 4 тика

 0    10    20    30
 0    28    56    84

a=8, b=5 дает 6 тиков

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

Вот псевдокод:

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))

Ось проходит от 0 по bestAstep до bestAstep*bestTick

Ось B идет от 0 на bestBstep до bestBstep*bestTick

person eigenchris    schedule 02.02.2015
comment
Спасибо, это помогло мне разработать собственный алгоритм :) Отлично сработало! - person Dennis; 23.02.2015