I-Plan Gantt mockup (2016-03)
by Anton
HTML
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
<div id="gantt">
<div class="workcentre">
<label><i class="fa fa-caret-right"></i>Paper Machine 1</label>
<div class="run opportunistic" style="left:30px;width:30px" title="Opportunistic Run">
<label>Opp.run 1</label>
</div>
<div class="run production" style="left:60px;width:180px" title="Run 01 / Grade A">
<div class="stock ok"></div>
<div class="run-part switchover" style="width:10px;"></div><div class="run-part orders" style="width:50px;"></div><div class="run-part allocations" style="width:30px;"></div>
<label>Run 01 / Grade A</label>
</div>
<div class="shut overlapped" style="left:150px;width:40px" title="Shut 01"></div>
<div class="run production selected" style="left:240px;width:150px" title="Run 02 / Grade C">
<div class="stock ss"></div>
<div class="run-part switchover" style="width:15px;"></div><div class="run-part allocations" style="width:100px;"></div>
<label>Run 02 / Grade C</label>
</div>
</div> <!-- WKC -->
<div class="workcentre">
<label><i class="fa fa-caret-right"></i>Paper Machine 2</label>
<div class="run production" style="left:90px;width:250px" title="Run 02 / Grade C">
<div class="stock out"></div>
<div class="run-part switchover" style="width:25px;"></div><div class="run-part orders" style="width:180px;"></div><div class="run-part allocations" style="width:20px;"></div>
<label>Run 03 / Grade B</label>
</div>
<div class="shut" style="left:390px;width:70px" title="Shut 02"></div>
<div class="run production" style="left:480px;width:60px" title="Run 04 / Grade A">
<div class="stock ok"></div>
<div class="run-part switchover" style="width:5px;"></div><div class="run-part orders" style="width:10px;"></div><div class="run-part allocations" style="width:2px;"></div>
...
CSS
body {
background-color: #fff;
}
#gantt {
position: relative;
margin: 10px;
padding: 10px;
background-color: #f0f0f0;
box-shadow: rgba(0,10,30,0.1) 0 0 7px inset;
overflow: auto;
}
legend {
position: relative;
}
legend ul {
list-style: none;
margin: 10px;
padding: 0;
}
legend li {
display: inline-block;
padding: 3px 7px;
margin-right: 15px;
}
legend li > span {
display: inline-block;
height: 16px;
width: 16px;
margin-right: 5px;
margin-bottom: -3px;
}
.workcentre {
position: relative;
height: 90px;
margin-bottom: 10px;
transition: height 300ms;
}
.time-line {
position: absolute;
top: 0;
width: 1px;
height: 100%;
background-color: #e0e0e0;
z-index: 10;
}
.wkc-line {
position: absolute;
top: 45px;
height: 20px;
border-radius: 10px;
opacity: 1;
left: 0;
background-color: #e0e0e0;
z-index: 15;
transition: top 300ms, height 300ms, padding 300ms, margin 300ms,
opacity 300ms, border-radius 300ms;
}
.expanded .wkc-line {
top: 0;
height: 100%;
padding: 0 10px;
margin-left: -10px;
border-radius: 0;
opacity: 0.5;
}
label,
legend li {
font-family: 'Oswald', sans-serif;
white-space: nowrap;
-webkit-user-select: none; /* Chrome all / Safari all */
-moz-user-select: none; /* Firefox all */
-ms-user-select: none; /* IE 10+ */
user-select: none;
cursor: pointer;
}
.workcentre > label {
position: absolute;
left: 5px;
top: 5px;
color: #444;
text-shadow: 0 1px 3px rgba(255,255,255,0.8);
z-index: 20;
opacity: 0.5;
}
.workcentre:hover > label {
opacity: 1;
}
.workcentre > label i {
margin-right: 3px;
}
.run label {
position: absolute;
top: 0;
left: 3px;
overflow: hidden;
text-overflow: ellipsis;
width: calc(100% - 6px);
}
.expanded .run label {
overflow: visible;
}
.run label,
legend li {
color: #444;
font-size: 13px;
}
#gantt .shut {
position: absolute;
top: 45px;
height: 20px;
z-index: 30;
...
JavaScript
$(function() {
var gantt = $('#gantt'),
timelineOffset = 50;
for(var i = 1; i < gantt.width() / timelineOffset; i++) {
$('<div class="time-line"></div>')
.appendTo(gantt)
.css('left', i * timelineOffset);
}
$('.workcentre').each(function() {
var wkc = $(this);
$('<div class="wkc-line"></div>')
.appendTo(wkc)
.width(gantt.width());
});
$('.run, .shut').on('click', function() {
$('#gantt .selected').removeClass('selected');
$(this).addClass('selected');
});
$('.workcentre > label').on('click', function() {
var wkc = $(this).closest('.workcentre'),
arrow = wkc.children('label').find('i'),
isCollapsed = !wkc.hasClass('expanded');
wkc.toggleClass('expanded');
arrow.toggleClass('fa-caret-right', !isCollapsed).toggleClass('fa-caret-down', isCollapsed);
if(isCollapsed) {
var runHeight = wkc.find('.run').outerHeight(),
maxOffset = 0;
// Offset runs
wkc.find('.run').each(function(i) {
var offset = runHeight * i;
maxOffset = Math.max(maxOffset, offset);
$(this).css('margin-top', runHeight * i);
});
// Increase WKC height to allow for expanded runs
wkc.css('height', wkc.height() + maxOffset);
} else {
// Collapse runs back
wkc.find('.run').each(function(i) {
$(this).css('margin-top', '');
});
// Restore WKC height
wkc.css('height', '');
}
});
})