Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 将碰撞元素彼此相邻放置_Php_Html - Fatal编程技术网

Php 将碰撞元素彼此相邻放置

Php 将碰撞元素彼此相邻放置,php,html,Php,Html,我正在创建某种日历/日程,显示某一天的活动。每个事件都显示为垂直小时网格中的HTML元素。同时可能有多个(“碰撞”)事件,在这些情况下,元素应水平相邻放置,并具有相等的宽度。例如,四个碰撞事件得到列值4,这样宽度为25% 棘手的部分是这些碰撞事件。我以为我解决了,但有些元素的列数不正确 可能有更好的方法来计算列数和位置-我愿意接受建议 当前(错误)结果的示例图像: 相关代码: <?php class Calendar { const ROW_HEIGHT = 24

我正在创建某种日历/日程,显示某一天的活动。每个事件都显示为垂直小时网格中的HTML元素。同时可能有多个(“碰撞”)事件,在这些情况下,元素应水平相邻放置,并具有相等的宽度。例如,四个碰撞事件得到列值4,这样宽度为25%

棘手的部分是这些碰撞事件。我以为我解决了,但有些元素的列数不正确

可能有更好的方法来计算列数和位置-我愿意接受建议

当前(错误)结果的示例图像:

相关代码:

<?php
    class Calendar {
        const ROW_HEIGHT = 24;

        public $events = array();
        public $blocks = array();


        public function calculate_blocks() {
            foreach($this->events as $event) {

                // Calculate the correct height and vertical placement
                $top = $this->time_to_pixels($event->_event_start_time);
                $bottom = $this->time_to_pixels($event->_event_end_time);
                $height = $bottom - $top;

                // Abort if there's no height
                if(!$height) continue;

                $this->blocks[] = array(
                    'id' => $event->ID,
                    'columns' => 1,
                    'placement' => 0, // Column order, 0 = first
                    'css' => array(
                        'top' => $top,
                        'bottom' => $bottom, // bottom = top + height
                        'height' => $height
                    )
                );
            }

            $done = array();

            // Compare all the blocks with each other
            foreach($this->blocks as &$block) {
                foreach($this->blocks as &$sub) {

                    // Only compare two blocks once, and never compare a block with itself
                    if($block['id'] == $sub['id'] || (isset($done[$block['id']]) && in_array($sub['id'], $done[$block['id']])) || (isset($done[$sub['id']]) && in_array($block['id'], $done[$sub['id']]))) continue;
                    $done[$block['id']][] = $sub['id'];

                    // If the blocks are colliding
                    if(($sub['css']['top'] >= $block['css']['top'] && $sub['css']['top'] < $block['css']['bottom'])
                    || ($sub['css']['bottom'] >= $block['css']['top'] && $sub['css']['bottom'] < $block['css']['bottom'])
                    || ($sub['css']['top'] <= $block['css']['top'] && $sub['css']['bottom'] >= $block['css']['bottom'])) {

                        // Increase both blocks' columns and sub-block's placement
                        $sub['columns'] = ++$block['columns'];
                        $sub['placement']++;
                    }
                }
            }
        }


        private function time_to_int($time) {

            // H:i:s (24-hour format)
            $hms = explode(':', $time);
            return ($hms[0] + ($hms[1] / 60) + ($hms[2] / 3600));
        }


        private function time_to_pixels($time) {
            $block = $this->time_to_int($time);

            return (int)round($block * self::ROW_HEIGHT * 2);
        }
    }
?>
试试这个:

public function calculate_blocks()
{
    $n          = count($events);
    $collumns   = array();
    $placements = array();

    // Set initial values.
    for ($i = 0; $i < $n; $i++)
    {
        $collumns[$i]   = 1;
        $placements[$i] = 0;
    }
    // Loop over all events.
    for ($i = 0; $i < $n; $i++)
    {
        $top1           = $this->time_to_pixels($events[$i]->_event_start_time);
        $bottom1        = $this->time_to_pixels($events[$i]->_event_end_time);

        // Check for collisions with events with higher indices.
        for ($j = $i + 1; $j < $n; $j++)
        {
            $top2     = $this->time_to_pixels($events[$k]->_event_start_time);
            $bottom2  = $this->time_to_pixels($events[$k]->_event_end_time);
            $collides = $top1 < $bottom2 && $top2 < $bottom1;

            // If there is a collision, increase the collumn count for both events and move the j'th event one place to the right.
            if ($collides)
            {
                $collumns[$i]++;
                $collumns[$j]++;
                $placements[$j]++;
            }
        }

        $this->blocks[] = array(
            'id'        => $events[$i]->ID,
            'columns'   => $collumns[$i],
            'placement' => $placements[$i],
            'css'       => array(
                'top'    => $top1,
                'bottom' => $bottom1,
                'height' => $bottom1 - $top1;
            )
        );
    }
}
公共函数计算\u块()
{
$n=计数($events);
$collumns=array();
$placements=array();
//设置初始值。
对于($i=0;$i<$n;$i++)
{
$collumns[$i]=1;
$placements[$i]=0;
}
//循环所有事件。
对于($i=0;$i<$n;$i++)
{
$top1=$this->time\u to\u像素($events[$i]->\u event\u start\u time);
$bottom1=$this->time\u to\u像素($events[$i]->\u event\u end\u time);
//检查是否与索引较高的事件发生冲突。
对于($j=$i+1;$j<$n;$j++)
{
$top2=$this->time\u to\u像素($events[$k]->\u event\u start\u time);
$bottom2=$this->time\u to\u像素($events[$k]->\u event\u end\u time);
$collides=$top1<$bottom2&&$top2<$bottom1;
//如果发生碰撞,增加两个事件的collumn计数,并将第j个事件向右移动一个位置。
如果($冲突)
{
$collumns[$i]++;
$collumns[$j]++;
$placements[$j]++;
}
}
$this->blocks[]=array(
'id'=>$events[$i]->id,
“列”=>$collumns[$i],
“placement”=>$placements[$i],
'css'=>数组(
“top”=>top1美元,
“底部”=>$bottom1,
“高度”=>$bottom1-$top1;
)
);
}
}
我无法实际测试它,但我认为它应该给您留下一个正确的块数组

编辑1:似乎没有产生所需的结果,请参见下面的评论


编辑2:我认为这是完全相同的问题:。有人用C#解决了这个问题,但将这个答案移植到PHP来解决您的问题应该相对容易。

我不认为这是PHP需要解决的问题。这就是它。在这种特殊情况下,它应该在服务器级别完成。无论如何,谢谢你。当你用$this->blocks创建这些嵌套的foreach时,光标不是被设置到了不同的位置吗?也许你应该检查一下。谢谢你的评论,@SenseException。我检查了每个循环的光标,没有问题。处理“嵌套循环”的最简单方法是使用“预读”和“while”循环,而不是“foreach”循环。问题是您需要在当前循环中的任何点读取“下一条记录”。“foreach”的问题是,他们只在循环结束时读取“下一条记录”。非常感谢您的努力,我将在明天进行测试,并返回结果。我想我知道发生了什么。我只是不知道如何修复它目前。如果你仔细观察,这些块确实得到了预期的数字,只是不正确。例如,事件#68与#426和#385重叠,因此大小为1/3。但是#385与#68、#383、#381和#63重叠,大小为1/5。因此,这些块确实根据它们重叠的事件数量获得了正确的大小/位置,但这最终看起来很奇怪。需要记住的是,A+B和B+C之间的重叠并不一定意味着A+C之间的重叠。也许这可以帮助你想出一些东西。是的,我昨天在试验时注意到了完全相同的事情。非常感谢你的链接,看起来确实是同样的问题。我将把它翻译成PHP,明天测试它-如果它能工作,我一定会在这里分享它。抱歉耽搁了。它以链接()提供的一些JavaScript结束。非常感谢你的帮助!