制作像MS Outlook这样的日历需要帮助吗?

时间:2010-11-22 13:36:34

标签: layout calendar

我正在使用像MS Outlook Calender这样的应用程序,用户可以在其中放置事件等。 我根据大小等对事件对象布局有问题,因为用户可以在MS Outlook日历中拖动和重新调整事件对象的大小,并自动设置事件对象的大小。

我需要这样做的算法我已经编写了自己的算法,但有几个问题需要帮助。

此屏幕截图将显示动态的事件对象排列。alt text

4 个答案:

答案 0 :(得分:1)

由于您使用的是Flex,这不是您问题的直接答案,但它有望让您走上正确的道路。

尝试查看FullCalendar的周日视图如何实现此功能。 FullCalendar是一个jQuery插件,可以呈现一个完全符合您要求的日历。

您必须从FullCalendar中提取渲染逻辑并将其转换为Flex中的项目。我知道JavaScript和ActionScript非常相似,但我从未使用过Flex - 对不起,我在这方面无法提供更多帮助。

FullCalendar的回购是here。具体来说,看起来AgendaView.js是最有趣的文件供您查看。

答案 1 :(得分:1)

这是ans

你可以选择矩形打包算法,但请记住,事件应该按时间和日期排序,只有横向打包才能适合你

这里是矩形包装algo

答案 2 :(得分:0)

我认为你问的是一般的对象布局算法,对吗?

我很确定这是一个NP完全问题:如果间隔安排一个集合,每个由开始结束定义尽可能少的

成为NP完全意味着,你最好的镜头可能会尝试所有可能的安排:

  • 在您的对象中找到群集 - 群组您要做的事情,其中​​间隔重叠。
  • 为每个群集做
    • n 成为群集中的对象数量
    • 如果 n 太高(如10或15),请停止并只绘制重叠的对象
    • 生成群集中所有可能的顺序对象(对于 n 对象,这些是 n!可能的组合,即6个对象, 120种可能的排序)
    • 对于每个排序以简单的方式布置对象:循环遍历元素并将它们放在现有列中(如果它适合那里),如果需要,则启动一个新列。
    • 使用最少的列保持布局

答案 3 :(得分:0)

我是这样做的:

  1. 事件是按天(或其他一些规则)变量的数据包
  2. 只要在Y轴上有连续的交叉点,一列中的事件将进一步分为列。
  3. 为事件分配X轴值(0到1)及其X尺寸(0到1)
  4. 事件以递归方式展开,直到每个交叉组的最后一个(按Y和X轴)命中列障碍或另一个已完成扩展的事件。
  5. 基本上它是一种蛮力,但工作得相当快,因为​​没有太多事件需要进一步扩展到第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