私自身の解決策は、イベントの絶対配置と各行のコンテナーとして div を使用する 2.6kb (コメント付き) jQuery スクリプトです。
このスクリプトは、ランダムなサイズのバーを生成します。新しいバーはそれぞれ、各行のスペースを上から下にチェックします。パーセンテージを使用しているのは、時間に対するバーの位置の計算が簡単になるためです (100% / 24h)。
http://jsfiddle.net/cj23H/5/
機能し、十分に効率的ですが、かさばります。改善よろしくお願いします。
私のjsfiddleからのjQueryコード:
function rand() {
return Math.floor(Math.random() * 101);
}
function get_target_row(width, left) {
var i = 0;
var target_found = false;
// Loop through all the rows to see if there's space anywhere
while (target_found === false) {
// Define current row selector
var target_i = '.personnel#row' + i;
// Add row if none
if ($(target_i).length === 0) {
$('body').append('<div class="personnel" id="row' + i + '"></div>');
}
// See if there's space
if ($(target_i).children().length === 0) {
target_found = $(target_i);
} else {
var spaceFree = false;
// Check collision for each child
$(target_i).children().each(function () {
// Get left and right coordinates
var thisWidthPx = parseFloat($(this).css('width'), 10);
var thisWidthParentPx = parseFloat($(this).parent().css('width'), 10);
var thisWidth = (thisWidthPx / thisWidthParentPx * 100);
var thisLeftPx = parseFloat($(this).css('left'), 10);
var thisLeftParentPx = parseFloat($(this).parent().css('left'), 10);
var thisLeft = (thisLeftPx / thisWidthParentPx * 100);
var thisRight = thisLeft + thisWidth;
var right = left + width;
// Sexy way for checking collision
if ((right > thisLeft && right < thisRight) || (left < thisRight && left > thisLeft) || (thisLeft > left && thisLeft < right) || (thisRight < right && thisRight > left)) {
spaceFree = false;
return false;
} else {
spaceFree = true;
}
});
// If no children have collided break the loop
if (spaceFree === true) {
target_found = $(target_i);
}
}
i++;
}
// If after all the while loops target is still not found...
if (target_found === false) {
return false;
}
// Else, if target is found, return it.
return target_found;
}
// Generate random bars
for (var i = 0; i < 10; i++) {
var width = rand()/2;
var left = rand()/2;
var right = left + width;
var target = get_target_row(width, left);
target.append('<div class="block" style="width:' + width + '%;position:absolute;left:' + left + '%;background-color:rgba(' + rand() + ',' + rand() + ',' + rand() + ',0.4)" id="bar'+i+'">' + 'b' + i + '</div>');
}
CSS:
.block {
position: absolute;
background-color: rgba(200, 100, 100, 0.4);
height: 32px;
}
.personnel {
position: relative;
float: left;
width: 100%;
height: 33px;
}