JSFiddle - React, Tailwind, and code Playground

HTML

<div id="timesheet"></div>

CSS

.timesheet{width:720px;height:292px;margin:0 auto}.timesheet{border-top:1px solid rgba(250,250,250,0.5);background-color:#333;position:relative}.timesheet.color-scheme-default .bubble-default{background-color:RGBA(252, 70, 74, 1)}.timesheet.color-scheme-default .bubble-lorem{background-color:RGBA(154, 202, 39, 1)}.timesheet.color-scheme-default .bubble-ipsum{background-color:RGBA(60, 182, 227, 1)}.timesheet.color-scheme-default .bubble-dolor{background-color:RGBA(244, 207, 48, 1)}.timesheet.color-scheme-default .bubble-sit{background-color:RGBA(169, 105, 202, 1)}.timesheet.color-scheme-alternative .bubble-default{background-color:#f3552e}.timesheet.color-scheme-alternative .bubble-lorem{background-color:#88c33a}.timesheet.color-scheme-alternative .bubble-ipsum{background-color:#436ae0}.timesheet.color-scheme-alternative .bubble-dolor{background-color:#f4d234}.timesheet.color-scheme-alternative .bubble-set{background-color:#707d86}.timesheet .scale{height:100%;position:absolute;top:0;left:0;float:left}.timesheet .scale section{float:left;width:59px;text-align:center;color:rgba(250,250,250,0.8);font-family:"Signika Negative";font-size:13px;line-height:24px;font-weight:lighter;border-left:1px dashed rgba(250,250,250,0.2);height:100%}.timesheet .data{margin:28px 0 0 0;padding:0;text-align:left;list-style-type:none;color:rgba(250,250,250,0.8);font-family:"Signika Negative";font-size:13px;overflow:hidden}.timesheet .data li{margin:0 0 3px 0;line-height:22px;height:21px;display:block;cursor:pointer;clear:both;position:relative;white-space:nowrap}.timesheet .data li:hover .bubble{opacity:1}.timesheet .data li .date{color:#b5b5b5;font-size:14px}.timesheet .data li .label{font-weight:lighter;font-size:14px;padding-left:5px;line-height:21px;color:#979796;white-space:nowrap}.timesheet .data li .bubble{width:24px;height:7px;display:block;float:left;position:relative;top:7px;border-radius:4px;margin:0 10px 0 0;opacity:0.7}#timesheet-alternative{background-color:RGBA(247, 247,...

JavaScript

!function(){"use strict";var Bubble=function(wMonth,min,start,end){this.min=min,this.start=start,this.end=end,this.widthMonth=wMonth};Bubble.prototype.formatMonth=function(num){return num=parseInt(num,10),num>=10?num:"0"+num},Bubble.prototype.getStartOffset=function(){return this.widthMonth/12*(12*(this.start.getFullYear()-this.min)+this.start.getMonth())},Bubble.prototype.getFullYears=function(){return(this.end&&this.end.getFullYear()||this.start.getFullYear())-this.start.getFullYear()},Bubble.prototype.getMonths=function(){var fullYears=this.getFullYears(),months=0;return this.end?this.end.hasMonth?(months+=this.end.getMonth()+1,months+=12-(this.start.hasMonth?this.start.getMonth():0),months+=12*(fullYears-1)):(months+=12-(this.start.hasMonth?this.start.getMonth():0),months+=12*(fullYears-1>0?fullYears-1:0)):months+=this.start.hasMonth?1:12,months},Bubble.prototype.getWidth=function(){return this.widthMonth/12*this.getMonths()},Bubble.prototype.getDateLabel=function(){return[(this.start.hasMonth?this.formatMonth(this.start.getMonth()+1)+"/":"")+this.start.getFullYear(),this.end?"-"+((this.end.hasMonth?this.formatMonth(this.end.getMonth()+1)+"/":"")+this.end.getFullYear()):""].join("")},window.TimesheetBubble=Bubble}(),function(){"use strict";var Timesheet=function(container,min,max,data){this.data=[],this.year={min:min,max:max},this.parse(data||[]),"undefined"!=typeof document&&(this.container="string"==typeof container?document.querySelector("#"+container):container,this.drawSections(),this.insertData())};Timesheet.prototype.insertData=function(){for(var html=[],widthMonth=this.container.querySelector(".scale section").offsetWidth,n=0,m=this.data.length;m>n;n++){var cur=this.data[n],bubble=new TimesheetBubble(widthMonth,this.year.min,cur.start,cur.end),line=['<span style="margin-left: '+bubble.getStartOffset()+"px; width: "+bubble.getWidth()+'px;" class="bubble bubble-'+(cur.type||"default")+'"...