JSFiddle - React, Tailwind, and code Playground

by eprouver

HTML

<div id="outerTimeline" class="outer">
    
</div>

CSS

body {
  font: 11px sans-serif;
}

svg{
    border-right:13px solid #ccc;
}

.outer{
    max-width: 100%;
    white-space:nowrap;
   overflow-x:scroll;
}

.axis path,
.axis line {
  fill: none;
  stroke: #ccc;
  shape-rendering: crispEdges;
}

.tooltip {
  position: absolute;
  width: 200px;
  height: 28px;
  pointer-events: none;
}

JavaScript

// load data
var data = Array.apply(null, new Array(100)).map(function(
            v) {
              function rand(min, max){
                  return ~~( Math.random() * (max - min)) + min;
              }
              
            return {
              startdate: ['2014-', rand(1, 3),'-',rand(1,30),' ',rand(0,20),':',rand(0,60),':16'].join(''),
              css_class: ['time_video', 'time_lesson', 'time_test', 'time_app'][~~(Math.random() *
                4)]
            };
          });

var actMap = {"time_video":"Video","time_lesson":"Lesson","time_test":"Test","time_app":"App"};
var hourWidth = 40;
var margin = {
              top: 30,
              right: 20,
              bottom: 20,
              left: 20
            },
color = d3.scale.category10();
var span = d3.extent(data, function(d){ return new Date(d.startdate); });
var days = Array.apply(null, new Array(Math.ceil((span[1] - span[0])/86400000))).map(function(){
return []});

var maxYscale = [];

data.forEach(function(v){
    v.date = new Date(v.startdate);
    v.activity = actMap[v.css_class];
    v.duration = Math.random() * 600;
    maxYscale.push(v.duration);
    days[~~((v.date - span[0])/86400000)].push(v);
});

maxYscale = d3.max(maxYscale) + 1;

days.forEach(function(v, i){
    if(v.length > 0){
       createDay(v, i);
    }
});
          var tooltip = d3.select("body").append("div")
            .attr("class", "tooltip")
            .style("opacity", 0);

function createDay(data, index){
    
var totalHours = Math.max(Math.ceil(d3.extent(data, function(d){return d.date}).reduce(function(p, c, i, ar){ return c-p; })/ 3600000),2);

            var width = (totalHours * hourWidth) - margin.left - margin.right,
            height = 400 - margin.top - margin.bottom;

          // add the graph canvas to the body of the webpage
          var svg = d3.select("#outerTimeline").append("svg")
            .attr("width", width + margin.left + margin.right)
            .attr("height", height +...