Vertically align div's but keeping horizontal position intact

javascript, jquery, mysql, php

Solution

your question sounds very naive but it is actually include some complex elements if needed to be resolved in the most OPTIMISED way.

the quick answer of what I probably would do to generate your display -

- use the provided function that adds the row number to your table

use your PHP code to generate a DIV container with style="display:block" for every row

inside the row generate appropriate size DIV (end-start * scale) with style="display:inline-block; float:left; display:relative" and (EDIT:) add transparent DIV elements to compensate for the white spaces you need. (i.e. from 0 to start and from the end to the start of the next DIV)

add the name field inside the DIV element

`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 ;   

here is the table I used to check it -

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);

few words regarding optimisation (one of my favourite subjects :) - in this code there is no optimisation, it means that the task will be allocated to the first available line. in order to minimise the number of lines its possible (but will take some time) to create a function that uses Heuristic method to resolve this problem.

output:

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

Problem

From a database I'm pulling a kind of timeline of Div's with a certain starting point and certain end point. Some of them overlap, some of them can be fitted next to each other. Ultimately I want to slide them together so that it's as compact as possible like this: I'm doubting how to approach this challenge: through a server side (php) script or with some javascript floating script thingy. Or off course a completely different approach Could some one push me in the right direction? Edit:: It's important, as it's a timeline, that the horizontal position of the div's remain the same. So floating all the divs to the left or inline-block them is no option :) My database setup: ``` id | name | start | end 1 | a | 2 | 7 2 | b | 5 | 10 etc ```

Original source