Skip to content

Instantly share code, notes, and snippets.

@nblenke
Last active December 29, 2015 09:59
Show Gist options
  • Save nblenke/7653967 to your computer and use it in GitHub Desktop.
Save nblenke/7653967 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html>
<head>
<title>Calendar Puzzle</title>
<style>
.mark {border-top:1px solid red;width:400px;height:30px;}
.time {float:left}
.event {left:100px;position:absolute;opacity:.4;color:#fff}
.event {background:red;width:302px;}
/*.event + .event {background:green;width:150px;left:252px;}*/
</style>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
</head>
<body>
<div id="container"></div>
<script>
var events = [
{start: 20, end: 190},
{start: 30, end: 150},
{start: 540, end: 600},
{start: 560, end: 620},
{start: 610, end: 670}
];
function layOutDay (events) {
var elContainer = document.getElementById('container'),
elMark = {},
elMarks = elContainer.childNodes,
elMarkTime = {},
elEvent = {},
elEvents = [],
markRange = 0,
calendarMin = 0,
calendarHour = 9,
calendarInterval = 30,
calendarHourSuffix = ['AM', 'PM'],
calenderHourSuffixUsePM = false,
calendarLength = 25,
eventStart = 0,
eventEnd = 0,
eventDuration = 0,
i = 0,
j = 0,
k = 0;
// build calendar
for (i = 0; i < calendarLength; i += 1) {
// odd rows are 30
calendarMin = (i % 2 === 1) ? '30' : '00';
elMarkTime = document.createElement('div');
elMarkTime.setAttribute('class', 'time');
elMarkTime.innerHTML = calendarHour + ':' + calendarMin + ' ' +
calendarHourSuffix[calenderHourSuffixUsePM ? 1 : 0];
elMark = document.createElement('div');
elMark.id = 'mark' + [i];
elMark.setAttribute('class', 'mark');
elMark._start = markRange;
elMark._end = markRange + calendarInterval;
elMark.appendChild(elMarkTime);
elContainer.appendChild(elMark);
calenderHourSuffixUsePM = (calendarHour === 12) ? true : calenderHourSuffixUsePM;
calendarHour += 1;
// even rows dont incr
if (i % 2 === 0) {
calendarHour -= 1;
}
// at 13 change to 1
calendarHour = calendarHour === 13 ? 1 : calendarHour;
// incr mark height
markRange += calendarInterval;
}
// place events into marks
for (i = 0; i < elMarks.length; i += 1) {
for (j = 0; j < events.length; j += 1) {
if (events[j].start > elMarks[i]._start && events[j].start <= elMarks[i]._end) {
eventDuration = events[j].end - events[j].start;
elEvent = document.createElement('div');
elEvent.id = 'event' + [j];
elEvent.setAttribute('class', 'event');
elEvent._start = events[j].start;
elEvent._duration = eventDuration;
elEvent._durationMarks = {};
elEvent._end = (events[j].start + eventDuration);
//adjust events position/duration in timeline
elEvent.style.marginTop = events[j].start - elMarks[i]._start + 'px';
elEvent.style.height = eventDuration + 'px';
elEvent.innerHTML = events[j].start + ', ' + events[j].end;
elMarks[i].appendChild(elEvent);
// store event and event start mark
elEvent._startMark = elMarks[i];
elEvents.push(elEvent);
}
// store end mark
if (events[j].end >= elMarks[i]._start && events[j].end < elMarks[i]._end) {
elEvents[j]._endMark = elMarks[i];
}
if (elMarks[i]._start >= events[j].start && elMarks[i]._end <= events[j].end) {
elEvent._durationMarks[i] = elMarks[i];
}
}
}
console.log(elEvents)
function collisions(eventArray) {
var arr = [],
len = eventArray.length - 1,
a,
b,
i = 0;
// Sort the event array on start time
eventArray.sort(function(a, b) {
return a._start - b._start;
});
// Get overlapping events
for (i = 0; i < len; i += 1) {
a = eventArray[i];
b = eventArray[i + 1];
if ((a._start <= b._start && a._end > b._start) || (a._start < b._end && a._end >= b._end) ) {
arr.push([a.id, b.id]);
}
}
return arr;
}
var el0 = {},
el1 = {};
for (i = 0; i < collisions(elEvents).length; i += 1) {
console.log(collisions(elEvents)[i])
el0 = document.getElementById(collisions(elEvents)[i][0]),
el1 = document.getElementById(collisions(elEvents)[i][1]);
el0.style.width = 150 + 'px';
el1.style.width = 150 + 'px';
if (el1.style.left === '252px') {
el0.style.left = 100 + 'px';
}
el1.style.left = 252 + 'px';
if (collisions(elEvents)[i - 1]) {
//console.log(collisions(elEvents)[i - 1].indexOf(collisions(elEvents)[i][0]))
// if previous collision has moved the event left, move it back
if (collisions(elEvents)[i - 1].indexOf(collisions(elEvents)[i][0]) === 1) {
el1.style.left = 100 + 'px';
}
}
}
}
layOutDay(events);
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment