/** test wether two div overlap from http://stackoverflow.com/questions/5930020 */ function testOverlap(a, b) { var aPos = a.position(); var bPos = b.position(); var aLeft = aPos.left; var aRight = aPos.left + a.width(); var aTop = aPos.top; var aBottom = aPos.top + a.height(); var bLeft = bPos.left; var bRight = bPos.left + b.width(); var bTop = bPos.top; var bBottom = bPos.top + b.height(); return !(bLeft > aRight || bRight < aLeft || bTop > aBottom || bBottom < aTop); } /** just parse a year, returns a floating number */ function parseOneDate(t) { if (t.lenth == 0) return null; var x = parseInt(t) * 1.0; return x; } /** returns the start/end years of an event */ function parseDates(div) { var span = div.find("span[class=start]"); if (span.length === 0) return null; var start = parseOneDate(span.text()); if (start == null) return null; span = div.find("span[class=end]"); if (span.length == 0) return { "start": start * 1.0, "end": (start + 1) * 1.0 }; var end = parseOneDate(span.text()); if (end == null || end < start) return null; return { "start": start * 1.0, "end": end * 1.0 }; } $(function () { var minDate = null, maxDate = null, i, events = $("#t1").children(); /** get min/max date, hide div having no date */ for (i = 0; i < events.length; i++) { var evt = events[i]; var r = parseDates($(evt)); if (r == null) { $(evt).css("display", "none"); continue; } if (minDate == null || r.start < minDate) minDate = r.start; if (maxDate == null || r.end > maxDate) maxDate = r.end; } events = $("#t1").children(); /** sort by date */ events.sort(function (a, b) { var t1 = parseDates($(a)); var t2 = parseDates($(b)); if (t1 == null) return (t2 == null ? 0 : -1); if (t2 == null) return 1; var i = t1.start - t2.start; if (i != 0) return i; return t1.end - t2.end; }); var ul = $("#t1"); $.each(events, function (i, li) { ul.append(li); }); /** set the left/width of each event */ var w = $("#t1").width(); for (i = 0; i < events.length; i++) { var evt = events[i]; var r = parseDates($(evt)); if (r == null) continue; var h = 64; var W = ((r.end - r.start) / (maxDate - minDate)) * w; var X = ((r.start - minDate) / (maxDate - minDate)) * w; while (W < 300) { W++; } $(evt).css({ "position": "absolute", "top": 0, "height": h, "left": X, "width": W }); /* adjust height */ while ($(evt)[0].scrollHeight > $(evt).height()) { $(evt).css("height", ++h); } } /** prevent collisions */ var maxY = 50; var maxX = 0; for (i = 0; i + 1 < events.length; i++) { if ($(events[i]).css("display") == "none") continue; for (j = i + 1; j < events.length; j++) { if ($(events[j]).css("display") == "none") continue; var n = 0; while (testOverlap($(events[i]), $(events[j]))) { var y = $(events[j]).position().top; y += 20; $(events[j]).css("top", y); y += 2 + $(events[j]).height(); if (maxY < y) maxY = y; } } } for (i = 0; i < events.length; i++) { var right = $(events[i]).position().left + $(events[i]).width(); } /** adjust main pane */ $("#t1").css("width", maxX); $("#t1").css("height", maxY); });