JSFiddle - React, Tailwind, and code Playground
HTML
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.0/css/bootstrap.min.css">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.0/js/bootstrap.min.js"></script>
<div id="svgContainer">
<svg id="svg1" width="0" height="0">
<path id="path1" class="path"/>
</svg>
</div>
<div class="content container">
<span>
<div class="page-header">
<h2 class="text-primary">Position: <small>Position Title </small></h2>
</div>
<table class="table table-bordered departments noBorder">
<tbody>
<tr>
<td class="positionBlank"></td>
<td class="position smallText" style="width:20%"><i class="fa fa-star padRight"></i>Department 1</td>
<td class="position smallText" style="width:20%"><i class="fa fa-star padRight"></i>Department 2</td>
<td class="position smallText" style="width:20%"><i class="fa fa-star padRight"></i>Department 3</td>
<td class="position smallText" style="width:20%"><i class="fa fa-star padRight"></i>Department 4</td>
<td class="position smallText" style="width:20%"><i class="fa fa-star padRight"></i>Department 5</td>
</tr>
</tbody>
</table>
<br />
<div class="dataContainer" id="dataContainer">
<div class="row" >
<div class="col-md-12">
<div class="panel panel-primary">
<div class="panel-leftheading">
<h3 class="panel-lefttitle"><i class="fa fa-thumb-tack padRight"></i>Title</h3>
</div>
<div class="panel-rightbody">
<!-- Table -->
<table class="table table-bordered positions">
<tbody>
<tr>
<td class="roleBox" style="width:20%" id="box_1">Content</td>
<td class="roleBox"...
CSS
.panel {
position: relative;
height: 240px;
}
.panel-default>.panel-leftheading {
color: #333;
background-color: #f5f5f5;
border-color: #ddd;
border-top: 10px;
}
.panel-primary>.panel-leftheading {
color: #fff;
background-color: #428bca;
border-color: #428bca;
border-top: 10px;
}
.panel-success>.panel-leftheading {
color: #3c763d;
background-color: #dff0d8;
border-color: #d6e9c6;
border-top: 10px;
}
.panel-info>.panel-leftheading {
color: #31708f;
background-color: #d9edf7;
border-color: #bce8f1;
border-top: 10px;
}
.panel-warning>.panel-leftheading {
color: #8a6d3b;
background-color: #fcf8e3;
border-color: #faebcc;
border-top: 10px;
}
.panel-danger>.panel-leftheading {
color: #a94442;
background-color: #f2dede;
border-color: #ebccd1;
border-top: 10px;
}
.panel-leftheading {
width: 42px;
padding: 10px 15px;
border-right: 1px solid transparent;
border-bottom: 1px solid transparent;
border-top-right-radius: 3px;
border-bottom-left-radius: 3px;
border-bottom-right-radius: 3px;
float: left;
height: 100%;
}
.panel-lefttitle {
margin-top: 145px;
margin-bottom: 0;
font-size: 12px;
color: inherit;
-webkit-transform: rotate(-90deg);
-webkit-transform-origin: left top;
-moz-transform: rotate(-90deg);
-moz-transform-origin: left top;
-ms-transform: rotate(-90deg);
-ms-transform-origin: left top;
-o-transform: rotate(-90deg);
-o-transform-origin: left top;
transform: rotate(-90deg);
transform-origin: left top;
white-space: nowrap;
}
.panel-rightbody {
margin-left: 42px;
height: 100%;
}
table {
margin-bottom: 0;
border-top: none;
border-bottom: none;
}
.positions {
height: 100%;
position: relative;
}
/* Fix Inner Table Styling...
JavaScript
//helper functions, it turned out chrome doesn't support Math.sgn()
function signum(x) {
return (x < 0) ? -1 : 1;
}
function absolute(x) {
return (x < 0) ? -x : x;
}
function drawPath(svg, path, startX, startY, endX, endY) {
// get the path's stroke width (if one wanted to be really precize, one could use half the stroke size)
var style = getComputedStyle(path)
var stroke = parseFloat(style.strokeWidth);
// check if the svg is big enough to draw the path, if not, set heigh/width
if (svg.getAttribute("height") < endY) svg.setAttribute("height", endY);
if (svg.getAttribute("width") < (startX + stroke)) svg.setAttribute("width", (startX + stroke));
if (svg.getAttribute("width") < (endX + stroke)) svg.setAttribute("width", (endX + stroke));
var deltaX = (endX - startX) * 0.15;
var deltaY = (endY - startY) * 0.15;
// for further calculations which ever is the shortest distance
var delta = deltaY < absolute(deltaX) ? deltaY : absolute(deltaX);
// set sweep-flag (counter/clock-wise)
// if start element is closer to the left edge,
// draw the first arc counter-clockwise, and the second one clock-wise
var arc1 = 0;
var arc2 = 1;
if (startX > endX) {
arc1 = 1;
arc2 = 0;
}
// draw tha pipe-like path
// 1. move a bit down, 2. arch, 3. move a bit to the right, 4.arch, 5. move down to the end
path.setAttribute("d", "M" + startX + " " + startY +
" V" + (startY + delta) +
" A" + delta + " " + delta + " 0 0 " + arc1 + " " + (startX + delta * signum(deltaX)) + " " + (startY + 2 * delta) +
" H" + (endX - delta * signum(deltaX)) +
" A" + delta + " " + delta + " 0 0 " + arc2 + " " + endX + " " + (startY + 3 * delta) +
" V" + endY);
}
function connectElements(svg, path, startElem, endElem) {
var svgContainer = document.getElementById('svgContainer');
// if first element is lower than the second, swap!
if (startElem.offsetTop > endElem.offsetTop) {
var temp = startElem;
startElem =...