рисовать галочки на масштабируемой шкале времени - PullRequest
1 голос
/ 27 ноября 2009

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

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

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

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

Ответы [ 2 ]

3 голосов
/ 29 ноября 2009

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

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

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

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

e = int(math.ceil(math.log(minimumPixelsBetweenTicks * axisRange / axisWidthPixels, 10)))
1 голос
/ 27 ноября 2009

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

Сначала решите, какие интервалы должны быть разрешены между тиками. Из-за сумасшествия системы времени (основание 10, основание 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...

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

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

...