doupi3874 2013-06-10 18:44
浏览 110
已采纳

确定与PHP重叠的时间

I have a PHP array of "Events", for only 1 day, with start & end times (not entered chronologically) as follows:

$events_list = array(
array(
    'name' => 'Event B',
    'start' => '5:00pm',
    'end' => '6:30pm',
    ),
array(
    'name' => 'Event C',
    'start' => '3:30pm',
    'end' => '5:00pm',
    ),
array(
    'name' => 'Event H',
    'start' => '1:15pm',
    'end' => '2:45pm',
    ),
array(
    'name' => 'Event I',
    'start' => '1:30pm',
    'end' => '4:00pm',
    ),
array(
    'name' => 'Event K',
    'start' => '4:30pm',
    'end' => '5:30pm',
    ),
array(
    'name' => 'Event L',
    'start' => '3:15pm',
    'end' => '5:00pm',
    ),
);

I am trying to visually output these events on a horizontal timeline, something like this:

[* Event H: 1:15pm-2:45pm *]    [* Event L: 3:15pm-5:00pm *][* Event B: 5:00pm-6:30pm *]
    [* Event I: 1:30pm-4:00pm *]        [* Event K: 4:30pm-5:30pm *]
                    [* Event C: 3:30pm-5:00pm *]

(Note that the above are definitely not "drawn to scale".)

As you can see, when an event has an overlapping start/end time, it needs to move to the next line below.

However, I'm having extreme difficulty coming up with a way to accomplish this, especially when an event's start/end times overlap 2 other events (For example, K's start overlaps "Event L", and K's end overlaps "Event B"), causing it to move down 2 lines instead of just 1.

This feels like quite a challenge. Any thoughts or suggestions are very much appreciated!

  • 写回答

1条回答 默认 最新

  • doujiabing1228 2013-06-10 20:03
    关注

    I have already done something like this. Here is a scaled down version of what we do. There is also a simple version of displaying the chart using divs with absolute position.

    <?php
    $events_list = array(
    array(
        'name' => 'Event B',
        'start' => '5:00pm',
        'end' => '6:30pm',
        ),
    array(
        'name' => 'Event C',
        'start' => '3:30pm',
        'end' => '5:00pm',
        ),
    array(
        'name' => 'Event H',
        'start' => '1:15pm',
        'end' => '2:45pm',
        ),
    array(
        'name' => 'Event I',
        'start' => '1:30pm',
        'end' => '4:00pm',
        ),
    array(
        'name' => 'Event K',
        'start' => '4:30pm',
        'end' => '5:30pm',
        ),
    array(
        'name' => 'Event L',
        'start' => '3:15pm',
        'end' => '5:00pm',
        ),
    );
    //easier to use timestamps, looping over all rows and overwriting time with timestamp
    foreach($events_list as $k=>$v){
        $events_list[$k]['start']=strtotime($v['start']);
        $events_list[$k]['end']=strtotime($v['end']);
    }
    
    //sort list by start time. Lowers the number of loops needed below
    function cmp($a,$b){
        if($a['start']==$b['start']){
            $aTS = $a['end'];
            $bTS = $b['end'];
        } else {
            $aTS = $a['start'];
            $bTS = $b['start'];
        }
        if($aTS == $bTS)return 0;
        return ($aTS < $bTS)?-1:1;
    }
    usort($events_list, 'cmp');
    
    //This is where the data will be saved
    $levels = array();
    
    //loop over all the events
    foreach($events_list as $event){
        //was this event placed in a level already?
        $placed = false;
        //loop through each level checking only the last event
        foreach($levels as $row=>$events){
            //we only need to check the last event if they are already sorted
            $last = end($events);
            //does the current event start after the end time of the last event in this level
            if($event['start'] >= $last['end']){
                //add to this level and break out of the inner loop
                $levels[$row][] = $event;
                $placed = true;
                break;
            }
        }
        //if not placed in another level, add a new level
        if(!$placed){
            $levels[] = array($event);
        }
    }
    
    //used for display purposes
    $minutesPerPixel = 2;
    ?>
    <html>
    <head>
    <style type="text/css">
    .level {
        background-color:#DDD;
        width:<?=floor(24*60/$minutesPerPixel)?>px;
        border:1px solid #999;
        position:relative;
        height:25px;
    }
    .event {
        position:absolute;
        overflow:hidden;
        height:19px;
        top:2px;
        background-color:#ACF;
        border:1px solid black;
        padding-left:3px;
        font:9px arial;
        line-height:9px;
    }
    </style>
    </head>
    <body>
    <?php
    //display
    foreach($levels as $level){
        echo "<div class='level'>
    ";
        foreach($level as $event){
            $left = floor((date('H',$event['start'])*60 + date('i', $event['start']))/$minutesPerPixel);
            $width = floor((($event['end']-$event['start'])/60)/$minutesPerPixel);
            echo "\t<div class='event' style='left:{$left}px;width:{$width}px'>{$event['name']}</div>
    ";
        }
        echo "</div>";
    }
    ?>
    </body>
    </html>
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 R语言Rstudio突然无法启动
  • ¥15 关于#matlab#的问题:提取2个图像的变量作为另外一个图像像元的移动量,计算新的位置创建新的图像并提取第二个图像的变量到新的图像
  • ¥15 改算法,照着压缩包里边,参考其他代码封装的格式 写到main函数里
  • ¥15 用windows做服务的同志有吗
  • ¥60 求一个简单的网页(标签-安全|关键词-上传)
  • ¥35 lstm时间序列共享单车预测,loss值优化,参数优化算法
  • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
  • ¥100 为什么这个恒流源电路不能恒流?
  • ¥15 有偿求跨组件数据流路径图
  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值