JSFiddle - React, Tailwind, and code Playground

by Daniel Lamblin

HTML

<h1>A week of blocked time<a id="b_rotate" class="tooltips">&#x267a;<span>Rotate week</span></a></h1>
<section>
  <svg id="timeblock">
  </svg>
</section>

CSS

body,
html {
  font: 10pt sans-serif;
  height: 100%;
}

H1 {
  padding-right: 1em;
}

section {
  display: flex;
  flex-flow: column;
  height: 100%;
}

#timeblock {
  display: flex;
  flex-flow: nowrap;
  width: 100%;
  height: 90%;
}

#timeblock rect {
  fill: lightblue;
  stroke: lightgray;
  stroke-width: 1px;
}

#timeblock text {
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
  font-size: 12px;
  font-weight: 600;
  fill: darkslategrey;
}

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

.axis text {
  font-family: sans-serif;
  font-size: 11px;
}

#b_rotate {
  display: block;
  float: right;
  background: lightgray;
  border: 1px solid black;
  border-radius: 0.25em;
  padding: 1px;
  font-weight: normal;
}

a.tooltips {
  position: relative;
  display: inline;
}

a.tooltips span {
  position: absolute;
  width: 140px;
  height: 20px;
  color: #CCC;
  background: #333;
  font-size: 12px;
  line-height: 20px;
  text-align: center;
  visibility: hidden;
  border-radius: 6px;
}

a.tooltips span:after {
  content: '';
  position: absolute;
  bottom: 100%;
  left: 53%;
  margin-left: -8px;
  width: 0;
  height: 0;
  border-bottom: 8px solid #333;
  border-right: 8px solid transparent;
  border-left: 8px solid transparent;
}

a:hover.tooltips span {
  visibility: visible;
  opacity: 0.8;
  top: 40px;
  left: 50%;
  margin-left: -76px;
  z-index: 999;
}

JavaScript

var timeFmt = d3.time.format.utc('%H.%M'),
    weekdaydef = 'Mon Tue Wed Thu Fri Sat Sun'.split(' '),
    weekdayseq = 'Mon Tue Wed Thu Fri Sat Sun'.split(' '),
    axes = [null, null, null, null];

function hm(i) {
  var s = i.toFixed(2);
  return timeFmt.parse((s.length < 4) ? '0' + s : s);
}
var timeData = [{
  key: "m1",
  "wday": 0,
  "begin": hm(6.00),
  "end": hm(7.00),
  label: "Rising, dress etc\n\retc"
}, {
  key: "m2",
  "wday": 0,
  "begin": hm(7.00),
  "end": hm(7.30),
  label: "Prep Sophie"
}, {
  key: "m3",
  "wday": 0,
  "begin": hm(7.30),
  "end": hm(8.00),
  label: "Transit to School"
}, {
  key: "t1",
  "wday": 1,
  "begin": hm(6.00),
  "end": hm(7.00),
  label: "Rising, dress etc"
}, {
  key: "t2",
  "wday": 1,
  "begin": hm(17.00),
  "end": hm(18.00),
  label: "call"
}, {
  key: "w1",
  "wday": 2,
  "begin": hm(6.00),
  "end": hm(7.00),
  'color': 0,
  label: "Rising, dress etc"
}, {
  key: "w2",
  "wday": 2,
  "begin": hm(7.00),
  "end": hm(7.30),
  'color': 0,
  label: "Prep Sophie"
}, {
  key: "w3",
  "wday": 2,
  "begin": hm(7.30),
  "end": hm(8.00),
  'color': 1,
  label: "Transit to School"
}, {
  key: "w4",
  "wday": 2,
  "begin": hm(8.00),
  "end": hm(9.00),
  'color': 2,
  label: "Read Emails"
}, {
  key: "w5",
  "wday": 2,
  "begin": hm(9.00),
  "end": hm(10.00),
  'color': 2,
  label: "Write Emails"
}, {
  key: "w6",
  "wday": 2,
  "begin": hm(10.00),
  "end": hm(13.00),
  'color': 3,
  label: "Job"
}, {
  key: "w7",
  "wday": 2,
  "begin": hm(13.00),
  "end": hm(14.00),
  'color': 4,
  label: "Lunch & Meditation"
}, {
  key: "w8",
  "wday": 2,
  "begin": hm(14.00),
  "end": hm(15.00),
  'color': 5,
  label: "Pick Sophie & Home"
}, {
  key: "w9",
  "wday": 2,
  "begin": hm(15.00),
  "end": hm(18.00),
  'color': 0,
  label: "Clean"
}, {
  key: "wa",
  "wday": 2,
  "begin": hm(18.00),
  "end": hm(19.00),
  'color': 0,
  label: "Plan"
}, {
  key: "wb",
  "wday": 2,
  "begin": hm(19.00),
  "end": hm(20.00),
  'color': 0,
  label:...