Расположение событий в календаре.

Здесь Вы можете найти или обсудить множество различных алгоритмов, их описаний, реализаций на VB и других языках.
Sector
Новичок
Новичок
 
Сообщения: 44
Зарегистрирован: 26.10.2004 (Вт) 14:43

Расположение событий в календаре.

Сообщение Sector » 19.10.2010 (Вт) 18:56

Задача расположить события в календаре, так что бы они не перекрывали друг-друга, по принципу типичного представителя, такого как Outlook calendar.

У события есть "начало" "конец". Если в условном диапазоне дат есть одно событие, то оно занимает всю ширину поля показа. Если же в диапазоне дат два события, то если они пересекаются по датам, то каждый из них занимает половину поля показа. Если нет то события занимают всю ширину.

На картинке типичные события из outlook. Хотя "событие 6" могло бы и занять оставшееся место до конца поля.
Не могу сдвинутся с места.
Чуствую себя идиотом.

Calendarx.jpg
Calendarx.jpg (85.12 Кб) Просмотров: 3692

FireFenix
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1640
Зарегистрирован: 25.05.2007 (Пт) 10:24
Откуда: Mugen no Sora

Re: Расположение событий в календаре.

Сообщение FireFenix » 19.10.2010 (Вт) 20:04

Берём строку
Находим количество блоков в строке
Находим ширину блока = ширина окна / количество блоков
Отрисовываем блок с шириной посчитанной выше и смещением = номер_блока * ширину_блока [+ 2 * ширина_границы]
Следующая строка
Птицей Гермеса меня называют, свои крылья пожирая... сам себя я укрощаю
私はヘルメスの鳥 私は自らの羽根を喰らい 飼い慣らされる

Sector
Новичок
Новичок
 
Сообщения: 44
Зарегистрирован: 26.10.2004 (Вт) 14:43

Re: Расположение событий в календаре.

Сообщение Sector » 19.10.2010 (Вт) 22:55

Берём строку
Находим количество блоков в строке
Находим ширину блока = ширина окна / количество блоков
Отрисовываем блок с шириной посчитанной выше и смещением = номер_блока * ширину_блока [+ 2 * ширина_границы]
Следующая строка

Под строкой имеется ввиду строка на рисунке что-ли?
Событие характеризует начало и конец в котором есть и минуты. Перебирать по минутам - не гуд.
Ну и главное я ничего не понял:
Берём строку

Ну допусти между 6 и 7 часами.
Находим количество блоков в строке

В данном случае - один.
Ширина блока = вся ширина окна. - неверно. По-моему проблема была не понята.


Формулирую заново:
Есть массив (коллекция не принципиально), событий. У событий есть свойства - "начало" и - "конец". Надо отрисовать их так что бы они не перекрывали друг друга.


Пока что придумал следующее:
1. Сортируем события по их продолжительности. Самое длинное - первое.
2. Берем событие С и смотрим, если предыдущее C-1 по списку событие перекрывается в датах, тогда первое "место" занято, (введем в событие свойство "место"), повторяем для события с-2 и.т.д. Дойдя до первого события становится понятно, сколько "мест" "занято". Присваиваем свойству "место" - следующее свободное.
3. Отрисовка - ну тут все понятно. Количество мест вычисляем. И рисуем в любой последовательности согласно смещению сверху по датам. Шириной (ширина окна / количество мест) Отступ от края ширина * "место" события.

Результат будет как на рисунке, но хотелось бы вычислять свободные места. скажем "событие 6" на рисунке идеально довести до правой границы окна. Но с другой стороны: если микрософт этим не озаботился. Может и мне плюнуть.

FireFenix
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1640
Зарегистрирован: 25.05.2007 (Пт) 10:24
Откуда: Mugen no Sora

Re: Расположение событий в календаре.

Сообщение FireFenix » 19.10.2010 (Вт) 23:24

Sector писал(а):Событие характеризует начало и конец в котором есть и минуты. Перебирать по минутам - не гуд

В предыдущем примере по строкам, которые есть - часы

Имеем коллекцию Tasks (все не отсортированные события) причём событие Task имеет параметр Level as Integer = 0

Берём самое жирное событие из Tasks
Присваиваем Level = 1
Отрисовываем с позиции 0 и заданными размерами

Label : Берём следующее жирное событие из Tasks
Проверяем коллизию по времени с другими событиями из Tasks (при If Level > 0) и выбираем с самым большим Level'ом (если нет коллизий Level = 0)
Присваиваем найденный Level
Отрисовываем с позиции = Level * размер блока
Go To : Берём следующее жирное событие из Tasks
Птицей Гермеса меня называют, свои крылья пожирая... сам себя я укрощаю
私はヘルメスの鳥 私は自らの羽根を喰らい 飼い慣らされる

Sector
Новичок
Новичок
 
Сообщения: 44
Зарегистрирован: 26.10.2004 (Вт) 14:43

Re: Расположение событий в календаре.

Сообщение Sector » 20.10.2010 (Ср) 0:47

Не годный алгоритм.



Берём самое жирное событие из InProcess

пусть жирность этого task1 самая жирная :D
Присваиваем Task-1.Level = 1
Отрисовываем с позиции 0 и заданными размерами

с отрисовкой подождем

Label : Берём следующее из InProcess
Проверяем коллизию по времени с другими событиями из InProcess (при If Level > 0) и выбираем с самым большим Level'ом (если нет коллизий Level = 0)
Присваиваем найденный Level
Отрисовываем с позиции = Level * размер блока
Go To : Берём следующее из InProcess


Не понял а как ищутся пустые level до

Так берем следующие, например task2 - следующий. При проверке, коллизия только с task1 и task3 . Самый большой level у task1 "есстессно", так как task3.level=0 еще. Присваиваем task2.level=2
повторяем.
следующие, например task3 следует. При проверке, коллизия только с task2 и task4
так как task2.level = 2 увеличиваем на 1
task3.level=3
повторяем с task4 коллизия с task3.level=3


стало:
task1.level = 1
task2 level = 2
task3.level = 3
task3.level = 4
Лестница

в идеале надо

task1.level = 1
task2 level = 4
task3.level = 2
task3.level = 1

Верно я понял?
допустим в начале самый "жирный"

Код: Выделить всё
for each t as task in task_collection_InProgress
   
  for each other_t as task in task_collection_InProgress
   
    if t.collison(other_t) and other_t.level<>0 then ' сравниваем с другими task у которых level не ноль

           if t.level<=other_t.level then t.level=other_t.level+1

    end if


  next other_t



next t
Вложения
Calendar2X.jpg
Calendar2X.jpg (69.22 Кб) Просмотров: 3665


Вернуться в Алгоритмы

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 3

    TopList