JSFiddle - React, Tailwind, and code Playground
by lindenb
HTML
<body>
<div class="mainpane">
<div id="t1" class="timeline">
<div class="event">
<img src="http://upload.wikimedia.org/wikipedia/commons/thumb/f/f1/Hooke_Microscope-03000276-FIG-4.jpg/64px-Hooke_Microscope-03000276-FIG-4.jpg" class="ribbon" />An early <a href="http://en.wikipedia.org/wiki/Microscope">microscope</a> was made in <span class="start">1590</span>
</div>
<div class="event">
<div>
<img src="http://upload.wikimedia.org/wikipedia/commons/thumb/9/94/Jan_Verkolje_-_Antonie_van_Leeuwenhoek.jpg/64px-Jan_Verkolje_-_Antonie_van_Leeuwenhoek.jpg" class="ribbon" />(<span class="start">1632</span>-<span class="end">1723</span>) <a href="http://en.wikipedia.org/wiki/Antonie_van_Leeuwenhoek">Antonie van Leeuwenhoek</a> teaches himself to make lenses, constructs simple microscopes and draws protozoa, such as Vorticella from rain water, and bacteria from his own mouth.</div>
</div>
<div class="event">
<img src="http://upload.wikimedia.org/wikipedia/commons/thumb/1/10/13_Portrait_of_Robert_Hooke.JPG/64px-13_Portrait_of_Robert_Hooke.JPG" class="ribbon" /><span class="start">1665</span>: <a href="http://en.wikipedia.org/wiki/Robert_Hooke">Robert Hooke</a> discovers cells in cork, then in living plant tissue using an early compound microscope</div>
<div class="event">
<img src="http://upload.wikimedia.org/wikipedia/commons/thumb/9/9c/Rudolf_Virchow_NLM3.jpg/220px-Rudolf_Virchow_NLM3.jpg" class="ribbon" /><span class="start">1855</span>: <a href="http://en.wikipedia.org/wiki/Rudolf_Virchow">Rudolf Virchow</a> states that cells always emerge from cell divisions (omnis cellula ex cellula).</div>
<div class="event">
<img src="http://upload.wikimedia.org/wikipedia/commons/thumb/3/31/Louis_Pasteur_by_Pierre_Lamy_Petit.jpg/220px-Louis_Pasteur_by_Pierre_Lamy_Petit.jpg" class="ribbon" />...
CSS
.mainpane {
position:relative;
overflow-x: auto;
overflow-y: auto;
}
.timeline {
background-color:lightgray;
border:solid 1px black;
position:relative;
}
.ribbon {
float: left;
margin:2px;
width:64px;
}
.event {
background-color:white;
border:solid 1px black;
position:absolute;
margin:2px;
box-shadow: 10px 10px 5px #888888;
}
JavaScript
/**
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)...