我正在使用像MS Outlook Calender这样的应用程序,用户可以在其中放置事件等。 我根据大小等对事件对象布局有问题,因为用户可以在MS Outlook日历中拖动和重新调整事件对象的大小,并自动设置事件对象的大小。
我需要这样做的算法我已经编写了自己的算法,但有几个问题需要帮助。
此屏幕截图将显示动态的事件对象排列。
答案 0 :(得分:1)
由于您使用的是Flex,这不是您问题的直接答案,但它有望让您走上正确的道路。
尝试查看FullCalendar的周日视图如何实现此功能。 FullCalendar是一个jQuery插件,可以呈现一个完全符合您要求的日历。
您必须从FullCalendar中提取渲染逻辑并将其转换为Flex中的项目。我知道JavaScript和ActionScript非常相似,但我从未使用过Flex - 对不起,我在这方面无法提供更多帮助。
FullCalendar的回购是here。具体来说,看起来AgendaView.js是最有趣的文件供您查看。
答案 1 :(得分:1)
答案 2 :(得分:0)
我认为你问的是一般的对象布局算法,对吗?
我很确定这是一个NP完全问题:如果间隔安排一个集合,每个由开始和结束定义尽可能少的列。
成为NP完全意味着,你最好的镜头可能会尝试所有可能的安排:
答案 3 :(得分:0)
我是这样做的:
基本上它是一种蛮力,但工作得相当快,因为没有太多事件需要进一步扩展到第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);
}
});