2010-11-22 5 views
0

Я делаю работу над таким приложением, как MS Outlook Calender, где пользователь может помещать события и т. Д. У меня возникла проблема с компоновкой объекта событий в соответствии с размером и т. Д., Так как пользователь может перетаскивать и изменять размер объекта события в календаре MS Outlook и размер объектов объектов событий автоматически.помощь, необходимая для создания календаря, такого как MS Outlook?

Мне нужен алгоритм для этого, я пишу свое, но есть несколько проблем, которые вам нужны.

Этот снимок экрана покажет размещение объекта события, которое является динамическим. alt text

+0

Что вы используете для создать приложение для календаря? (HTML + JS, WPF и т. Д.) – josh3736

+0

Я использую скрипт с гибким действием – Badr

+1

Может ли каждый описать алгоритм шаг за шагом. – Badr

ответ

1

вот анс

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

здесь прямоугольник упаковки algo

1

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

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

Вам нужно будет извлечь логику визуализации из FullCalendar и перевести ее в свой проект в Flex. Я знаю, что JavaScript и ActionScript очень похожи, но я никогда не использовал Flex — жаль, что я не могу больше помочь в этой области.

Репортер FullCalendar - here. В частности, похоже, что AgendaView.js - это самый интересный файл для вас.

+1

это не сработало для меня ................ – Badr

0

Я думаю, вы спрашиваете об общем алгоритме компоновки объектов , правильно?

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

Being NP-полные означает, что ваш лучший выстрел, вероятно, пытаясь все возможные меры:

  • найти кластеры в ваших объектах - в группы где у вас есть что-то делать, где интервалы перекрываются.
  • для каждого кластера сделать
    • пусть п быть число объектов в кластере
    • , если п слишком высока (например, 10 или 15), остановить и просто сделать перекрывающиеся объекты
    • генерируют все возможные заказы объектов в кластере (для n объектов, это n! возможных комбинаций, т.е. 6 объектов, 120 возможных порядков)
    • для каждого заказа выкладывайте объекты тривиально: проведите по элементам и поместите их в существующий столбец, если он подходит, запустите новый столбец, если он вам нужен.
    • сохранить макет с наименьшими столбцами
+0

Я сделал это раньше, но после некоторых итераций изменения размера он не смог разместить все поля событий по мере необходимости – Badr

0

Вот как я это сделал:

  1. События представляют собой пакет в столбцы переменных в день (или какое-либо другое правило)
  2. События в одном столбце, дополнительно разделены на колонки, до тех пор, пока существует непрерывное пересечение на Y-оси.
  3. События присваивают свое значение оси X (от 0 до 1) и их размер X (от 0 до 1)
  4. События рекурсивно расширены, пока последняя из каждой пересеченной группы (по оси Y и X) не попадает барьер столбца или другое событие, которое завершило расширение.

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

var physics = []; 
var step = 0.01; 

var PackEvents = function(columns){ 
    var n = columns.length; 
    for (var i = 0; i < n; i++) { 
     var col = columns[ i ]; 
     for (var j = 0; j < col.length; j++) 
     { 
      var bubble = col[j]; 
      bubble.w = 1/n; 
      bubble.x = i*bubble.w; 
     } 
    } 
}; 

var collidesWith = function(a,b){ 
    return b.y < a.y+a.h && b.y+b.h > a.y; 
}; 

var intersects = function(a,b){ 
    return b.x < a.x+a.w && b.x+b.w > a.x && 
      b.y < a.y+a.h && b.y+b.h > a.y; 
}; 

var getIntersections = function(box){ 
    var i = []; 
    Ext.each(physics,function(b){ 
     if(intersects(box,b) && b.x > box.x) 
      i.push(b); 
    }); 
    return i; 
}; 

var expand = function(box,off,exp){ 
    var newBox = { 
     x:box.x, 
     y:box.y, 
     w:box.w, 
     h:box.h, 
     collision:box.collision, 
     rec:box.rec 
    }; 
    newBox.x += off; 
    newBox.w += exp; 
    var i = getIntersections(newBox); 
    var collision = newBox.x + newBox.w > 1; 
    Ext.each(i,function(n){ 
     collision = collision || expand(n,off+step,step) || n.collision; 
    }); 
    if(!collision){ 
     box.x = newBox.x; 
     box.w = newBox.w; 
     box.rec.x = box.x; 
     box.rec.w = box.w; 
    }else{ 
     box.collision = true; 
    } 
    return collision; 
}; 

Ext.each(columns,function(column){ 
    var lastEventEnding = null; 
    var columns = []; 
    physics = []; 

    Ext.each(column,function(a){ 
     if (lastEventEnding !== null && a.y >= lastEventEnding) { 
      PackEvents(columns); 
      columns = []; 
      lastEventEnding = null; 
     } 
     var placed = false; 
     for (var i = 0; i < columns.length; i++) { 
      var col = columns[ i ]; 
      if (!collidesWith(col[col.length-1], a)) { 
       col.push(a); 
       placed = true; 
       break; 
      } 
     } 
     if (!placed) { 
      columns.push([a]); 
     } 
     if (lastEventEnding === null || a.y+a.h > lastEventEnding) { 
      lastEventEnding = a.y+a.h; 
     } 
    }); 
    if (columns.length > 0) { 
     PackEvents(columns); 
    } 

    Ext.each(column,function(a){ 
     a.box = { 
      x:a.x, 
      y:a.y, 
      w:a.w, 
      h:a.h, 
      collision:false, 
      rec:a 
     }; 
     physics.push(a.box); 
    }); 

    while(true){ 
     var box = null; 
     for(i = 0; i < physics.length; i++){ 
      if(!physics[i].collision){ 
       box = physics[i]; 
       break; 
      } 
     } 
     if(box === null) 
      break; 
     expand(box,0,step); 
    } 

}); 

Результат: http://imageshack.com/a/img913/9525/NbIqWK.jpg

Смежные вопросы