0

予定表を作っています。イベントは水平ブロックです (Google Cal には垂直ブロックがあります)。また、1 つの日付にたくさんのイベントがあるため、次のように、スペースを無駄にすることなく、イベントを互いに積み重ねたいと考えています。 これは私が欲しいものです

プラグインを見つけました:
http://masonry.desandro.com/
http://isotope.metafizzy.co/
http://packery.metafizzy.co/
しかし、これを行うためだけに 30kb プラグインを使用することに熱心ではありません。簡単なこと。

明確にするために: これはタイムラインであるため、div イベントは左右に移動できませんが、他の div イベントの中で垂直に収まる必要があります。

4

1 に答える 1

0

私自身の解決策は、イベントの絶対配置と各行のコンテナーとして 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;
}
于 2013-11-09T11:42:35.233 に答える