我从数据库中提取了一种具有特定起点和终点的Div时间表。其中一些重叠,一些可以彼此相邻安装。

最终,我想将它们滑动到一起,以使其尽可能紧凑,如下所示:

我在怀疑如何应对这一挑战:通过服务器端(php)脚本还是使用一些JavaScript float 脚本。或者偏离路线,这是完全不同的方法

有人可以将我推向正确的方向吗?

编辑::
重要的是,作为时间轴,div的水平位置必须保持不变。因此,将所有div float 到左侧或内联阻止它们是没有选择的:)


我的数据库设置:

id | name | start | end
1  | a    | 2     | 7
2  | b    | 5     | 10
etc

最佳答案

您的问题听起来很幼稚,但是如果需要以最优化的方式解决,它实际上包含一些复杂的元素。

我可能会怎么做来生成您的显示的快速答案-

  • 使用提供的函数将行号添加到表中
  • 使用您的PHP代码生成具有以下内容的DIV容器:
    每行style =“display:block”
  • 该行内的
  • 生成适当的大小DIV(结束起始*比例)
    与style =“display:inline-block; float:left; display:relative”和(编辑:) 添加透明DIV元素以补偿所需的空白。 (即从0开始,从下一个DIV的结尾到开头)
  • 在DIV元素
  • 内添加名称字段
    use mySchema;drop procedure if exists tileItems;
    DELIMITER $$
    CREATE PROCEDURE tileItems ()
    BEGIN
    DECLARE p_id, p_start, p_end, p_row int;
    DECLARE done INT DEFAULT FALSE;
    DECLARE cur1 CURSOR FOR SELECT id, start, end FROM tasks order by start, id;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
    
    drop temporary table if exists tiles;
    
    create temporary table tiles (
    row int(11) NOT NULL,
    id int(11) NOT NULL,
    end int(11) NOT NULL
    );
    -- row field will indicates the row number the task should apear
    OPEN cur1;
    next_task: LOOP
    
    FETCH cur1 into p_id, p_start, p_end;
      IF (done) THEN
        LEAVE next_task;
      END IF;
    select min(row) from (select row, max(end) me from tiles t2 group by row) t1
      where me < p_start
      into p_row;
    
    
    -- take care of row numbering
    IF (p_row IS NULL) then
      select max(row) from tiles
        into p_row;
        IF (p_row IS NULL) then
          SET p_row = 0;
        END IF;
        SET p_row=p_row+1;
    END IF;
    
    insert into tiles (id, row, end)
      values (p_id,p_row,p_end);
    
    END LOOP;
    
    -- CLOSE cur1;
    -- here is your output, on the PHP/.Net code you should loop on the row
    select tasks.*, tiles.row from tasks
    inner join tiles
     on tasks.id = tiles.id
    order by tiles.row, tasks.start;
    
    
    END $$
    DELIMITER ;
    

    这是我用来检查的表格-
    CREATE TABLE `tasks` (
      `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
      `name` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
      `start` int(11) NOT NULL,
      `end` int(11) NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=11 ;
    
    
    INSERT INTO `tasks` (`id`, `name`, `start`, `end`) VALUES
    (1, 'A', 2, 6),
    (2, 'B', 5, 7),
    (3, 'C', 8, 10),
    (4, 'D', 1, 5),
    (5, 'E', 6, 7);
    

    关于优化的几句话(我最喜欢的主题之一:)-
    在此代码中没有优化,这意味着任务将分配给第一行。
    为了最大程度地减少行数,可以(但需要一些时间)创建一个使用Heuristic方法解决此问题的函数。

    输出:
    id  name    start   end row
    4   D   1   5   1
    5   E   6   7   1
    3   C   8   10  1
    1   A   2   6   2
    2   B   5   7   3
    

    10-07 16:16
    查看更多