JSFiddle - React, Tailwind, and code Playground

by Evan Sharp

HTML

<div id="wrap" class="cf">
    <div id="times"></div>
    <div id="eventContainer">
        <div id="events"></div>
    </div>
</div>

CSS

html, body{
    font-family: Arial, sans-serif
}
#wrap{
    margin:0 auto;
    padding: 20px 0 0;
    width: 730px;
}
#times{
    float:left;
    padding: 0 9px 0 12px;
    position: relative;
    top: -7px;
}
.time{
    color: #a7a7a7;
    font-size: 10px;
    height: 29.5px;
    text-align: right;
}
.time.oclock {
    height: 30px;
}
.time.oclock span{
    color: #686868;
    font-size: 14px;
    font-weight: 600;
}
#eventContainer{
    background-color: #ececec;
    border-left:1px solid #d5d5d5;
    float:left;
    padding: 0 10px;
    width: 600px;
}
#events{
    height: 720px;
    position: relative;
    margin: 0 auto;
}
.event{
    background-color: #fff;
    border:1px solid #d5d5d5;
    border-left: 4px solid #4b6ea9;
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
}

.event:before{
    border-left: 4px solid #4b6ea9;
    content: ".";
    color: transparent;
    display: block;
    font-size: 0;
    height: 100%;
    padding: 1px 0;
    position: absolute;
    left: -4px;
    top: -1px;
}

.event>div{
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
    height: 100%;
    overflow: hidden;
    padding: 8px;
}

.event h4{
    color:#4b6ea9;
    font-size: 12px;
    font-weight: 600;
    margin:0px;
}

.event address{
    color: #7a7a7a;
    font-size: 9px;
    font-style: normal;
}

.cf:before,
.cf:after {
    content: " ";
    display: table;
}

.cf:after {
    clear: both;
}
.cf {
    *zoom: 1;
}

JavaScript

/**
 * Base event object
 *
 * Stores the properties for the event object.
 *
 * @constructor
 * @param {Object.<number, number>} event Plain object containing a start and end time.
 */
function eventItem(event){
	this.start = event.start;
	this.end = event.end;
	this.column = 1;
    this.columnSize = 1;
    this.overlap = 1;
    this.size = 1;
	this.width = 100;
    this.height = event.end - event.start;// Based on requirements, this can be assumed.
    this.position = {
        left: 0,
        top: event.start // Based on requirements, this can be assumed.
    };
}

/**
 * Generates the HTML for the event
 *
 * Creates the HTML for the current event using the event's properties
 *
 * @this {event}
 * @return {Object} HTML for the event
 */
event.prototype.getMarkup = function(i){
    return '<div class="event" style="'
        +'height:'+this.height+'px;'
        +'width:'+this.width+'%;'
        +'left:'+this.position.left+'%;'
        +'top:'+this.position.top+'px;'
        +'position:absolute;"><div>'
        +'<h4>Sample Item</h4>'
        +'<address>Sample Location</address>'
        +'</div></div>';
}

/**
 * Compares an event to the current event.
 *
 * If the start time is event less or the start times are equeal and the end time of event
 * is less, event is considered to be less.
 * If the start and end times are equal, then the events are considered equeal.
 * If the start time of event is greater or the start times are equal and the end time of
 * event is greater, then event is considered greater.
 *
 * @param {event} a Event to compare against.
 * @param {event} b Event to compare.
 * @return {number} -1 if event is less, 0 if event is equal, 1 if event is greater
 */
event.compare = function(a,b){
	if(a.start == b.start && a.end == b.end)
		return 0;
	if(a.start < b.start || (a.start == b.start && a.end > b.end))
		return -1;
	return 1;
};

/**
 * Computes the layout of the events
 *
 * Determines how the events should be layed out based on the...