2009-11-26 7 views
1

Я создаю временную шкалу, где я хочу нарисовать тики с определенным временным интервалом.рисование клещей на масштабируемой временной шкале

Так что в зависимости от доступной ширины я хочу нарисовать как можно больше клещей. но они не должны быть слишком близко друг к другу. Они должны оставаться как минимум на несколько пикселей друг от друга.

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

Как я могу найти пространство между тиками в зависимости от масштаба и ширины?

+0

ли проблема с моим вторым ответом? –

+0

нет, у меня просто не было много времени в последние несколько дней, чтобы проверить его. Прости. на самом деле это не работает, потому что я не понимаю один параметр. я позабочусь об этом позже. благодаря! – clamp

ответ

1

Это немного грязный, но это просто и хорошо работает:

Сначала решите, что интервалы должны быть разрешены между клещами. Из-за сумасшествия системы времени (база 10? Base 60?, Как долго это месяц?) Нет никакого особого алгоритма для генерации этого списка - просто выберите естественные интервалы, которые люди знакомы и жестко закодируют в вашу программу:

...etc... 
every 0.1 second 
every 1 second 
every 5 seconds 
every 15 seconds 
every 1 minute 
every 5 minutes 
every 15 minutes 
every 1 hours 
every 2 hours 
every 4 hours 
every 8 hours 
every day, midnight 
every 7 days, midnight 
every month start 
every quarter start 
every year start 
every 10 years 
...etc... 

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

Это немного раздражает, но я не знаю лучшего способа, если вы не найдете какую-нибудь библиотеку, которая сделает это за вас. Я не знаю ни одной библиотеки, которая предлагает эту функцию, но должно быть много проектов с открытым исходным кодом, которые делают что-то похожее, чтобы вы могли получить код, если вы не хотите писать это самостоятельно.

+0

Спасибо за ваш ответ! ну, время абстрактно, не связано с секундами, минутами и т. д., поэтому база должна быть равна 10. – clamp

+0

. Тогда вы можете начать с 1 единицы времени и посмотреть, сколько тиков вы получите (numberOfTicks = total time/1) и как close они (distanceBetweenTicks = pixelsOnXAxis/numberOfTicks). Если distanceBetweenTicks порог, timeunit/= 10. Пока вы не приблизитесь ближе к порогу, остановитесь. –

+0

Извините за форматирование. Был ли мой ответ непонятен? –

3

После моего первого ответа ваши уточненные ваши характеристики и проблема оказались проще, чем я ожидал. Вы также хотели получить более простое решение, чем общее решение, которое я изложил ранее. Вместо редактирования моего исходного комментария я бы предпочел создать новый комментарий, потому что это совершенно другой подход.

Сначала определите интересные переменные:

minimumPixelsBetweenTicks = 5 
axisWidthPixels = 400 
axisRangeTime = 1000.0   # = axisMaximumTime - axisMinimumTime 
tickSeparationTime = 10 ** e # e is an unknown integer that we must find 

Тогда можно вычислить е непосредственно используя следующую формулу (вы не указали язык, поэтому я использую Python):

e = int(math.ceil(math.log(minimumPixelsBetweenTicks * axisRange/axisWidthPixels, 10)))