Simple Gantt chart based on JS
Recently, my colleague asked for help to write a time Gantt chart, which mainly wanted to show the stops of a car at different time points in a day.
To see the effect, the requirement is to start at 5 in the morning and go to 5 in the morning
preparation
In fact, there are many gantt charts on the Internet, but they can only be visualized to the sky, not to a specific point in time, and the description of each specific time period is not customized, so I am ready to write my own.
Implementation logic
We can first simulate some demo data, which is the most important data for each time point. To achieve the above effect, we need to split each time point.
var demoData: [
{
carNum: 'sichuan A09384',
innerData: [
{
start: '2019/1/21 6:23',
end: 'be 7:45 2019/1/21',
value: 'A site'.bg: 'green'
},
{
start: '2019/1/21 sons',
end: '2019/1/21 get',
value: 'B site'.bg: 'yellow'
},
{
start: '2019/1/21 20:00',
end: '2019/1/21 lies',
value: 'C site'.bg: 'blue'
}
]
},
{ carNum: 'sichuan A04384',
innerData: [
{
start: '2019/1/21 5:23',
end: '2019/1/21 6:05',
value: 'A site'.bg: 'blue'
},
{
start: '2019/1/21 10:23',
end: '2019/1/21 when',
value: 'B site'.bg: 'green'
},
{
start: '2019/1/21 21:00',
end: '2019/1/22 cause',
value: 'C site'.bg: 'yellow'}},]]Copy the code
First create time
// createHours:function(){
var startHour = 5;
var endHour = 11;
var html = ' ';
for (let i = startHour; i< 24; i++) {
html += `<div>${i < 10 ? `0${i}` : i}:00</div>`
}
for (let i = 0; i< endHour; i++) {
html += `<div>${i < 10 ? `0${i}` : i}:00</div>`
}
document.getElementById('hour').innerHTML = html;
},
Copy the code
Draw a Gantt chart from the data
We set 1H = 60px; The width is fixed like this, i.e. 1px = 1M;
Start :’2019/1/21 6:23′; end: ‘2019/1/21 7:45’;
var start = new Date('2019/1/21 6:23'),
end = new Date('be 7:45 2019/1/21'), start_h = start.gethours (), // Start time start_m = start.getminutes (), // Start minute end_h = end.gethours (), // End time end_m = end.getminutes (), // End minute left_offset = 0; _left_offset = 0; width =' '; // Get the start position of the gantt chart for the time period (we're starting at 5, so -5); left_offset = (start_h - 5) * 60 + start_m; // Get the width of each gantt chart, // calculate the position of the end time, then subtract the left margin of the start time; width = ((end_h - 5) * 60 + end_m) - left_offset; _left_offset = left_offset-allleft; // When drawing the next time break, left_offset is used to store the distance to the left of the previous time break using allLeft. allLeft = left_offset + width; // Add it to the DOM HTML += '<span style="width:${width}px; margin-left:${_left_offset}px;">${innerData[i].value}</span>`;
Copy the code
- First, you need to find the start position of the start time in the time range.
- Calculate the width of the time, following the rule 1px = 1M.
- When setting the margin-left, remember to subtract the margin-left of the gantt chart of the previous period.
- If no one is drawn, the margin-left is stored for use in the next period.
How about counting across the sky
How do we calculate the start and end positions and the width of our time span when it’s across the sky? I just posted the code,
createData: function() { var data = this.demoData; var today = new Date().getDate(); // Today's datefor (let m = 0; m< data.length; m++) {
var innerData = data[m].innerData;
var html = ' ';
var allLeft = 0;
for (let i = 0; i< innerData.length; i++) {
var start = new Date(innerData[i].start),
end = new Date(innerData[i].end),
start_d = start.getDate(),
end_d = end.getDate(),
start_h = start.getHours(),
start_m = start.getMinutes(),
end_h = end.getHours(),
end_m = end.getMinutes(),
left_offset = 0;
_left_offset = 0;
width = ' ';
if (start_d === (today + 1)) {
left_offset = ((23 - 5) * 60) + ((start_h + 1) * 60) + start_m;
_left_offset = left_offset - allLeft;
width = (((23 + (end_h + 1)) - 5) * 60 + end_m) - left_offset;
} else if (end_d === (today + 1)) {
left_offset = ((start_h - 5) * 60) + start_m;
_left_offset = left_offset - allLeft;
width = (((24 + end_h) - 5) * 60 + end_m) - left_offset;
} else {
left_offset = (start_h - 5) * 60 + start_m;
_left_offset = left_offset - allLeft;
width = ((end_h - 5) * 60 + end_m) - left_offset;
}
allLeft = left_offset + width;
html += `<span style="width:${width}px; margin-left:${_left_offset}px; background:${innerData[i].bg}">${innerData[i].value}</span>`;
}
document.getElementById('container').innerHTML += `<div class="gantt-item" >${html}</div>`; }}Copy the code
This place does not explain in detail, what do not understand the place welcome everyone to leave a message. The code is very simple, mainly used to achieve a relatively simple Gantt chart. You don’t need to download any plug-ins or anything.
Here to post the code, we can communicate, maybe you have a better way to implement it.
< HTML > <head> <title> Test demo</title> <styletype="text/css">
#container {
width: 100%;
overflow: scroll;
height: calc(100vh - 0px);
width: 1900px;
}
.carNum {
float:left;
width:100px;
text-align: center;
}
#hour {
width: 1800px;
overflow: scroll;
}
#hour div{
width: 60px;
float: left;
border-left: 1px solid #ddd;
background: #ccc;text-align: center; box-sizing: border-box; } .gantt-item { width: 1800px; }. Gantt - item: hover {background: rgba (, 0, 0, 1); } .gantt-item span { height: 20px;; display: inline-block; margin: 5px 0px; font-size: 12px; text-align: center; color:#fff;
background:green;
}
.nowTime {
border: 1px solid green;
display: inline-block;
height: 500px;
height: calc(100vh - 0px);
position: absolute;
top: 0px;
}
</style>
</head>
<body>
<div id="container">
<div class="carNum">
<div style="background:#ccc;"<div style= "box-sizing: border-box! Important"line-height:30px;"<div style= "box-sizing: border-box! Important; word-wrap: break-word! Important;"line-height:30px;"<div style= "box-sizing: border-box! Important; word-wrap: break-word! Important;"line-height:30px;"> </div> <div id="hour" style="float:righ">
</div>
</div>
</body>
<script type="text/javascript">
var gantt = {
demoData: [
{
innerData: [
{
start: '2019/1/21 6:23',
end: 'be 7:45 2019/1/21',
value: 'A site'.bg: 'green'
},
{
start: '2019/1/21 sons',
end: '2019/1/21 get',
value: 'B site'.bg: 'yellow'
},
{
start: '2019/1/21 20:00',
end: '2019/1/21 lies',
value: 'C site'.bg: 'blue'
}
]
},
{
innerData: [
{
start: '2019/1/21 5:23',
end: '2019/1/21 6:05',
value: 'A site'.bg: 'blue'
},
{
start: '2019/1/21 10:23',
end: '2019/1/21 when',
value: 'B site'.bg: 'green'
},
{
start: '2019/1/21 21:00',
end: '2019/1/22 cause',
value: 'C site'.bg: 'yellow'
},
]
},
{
innerData: [
{
start: '2019/1/21 8:23',
end: '2019/1/21 10:05',
value: 'A site'.bg: 'blue'
},
{
start: '2019/1/21 but',
end: '2019/1/21 14:45',
value: 'B site'.bg: 'green'
},
{
start: '2019/1/21 22:00',
end: '2019/1/22 cause',
value: 'C site'.bg: 'red'
},
{
start: '2019/1/22 4:00 PM',
end: '2019/1/22 7:35',
value: 'D site'.bg: 'green'},]},], // initialize init:function() { this.showNowTime(); this.createHours(); this.createData(); }, // create time createHours:function(){
var startHour = 5;
var endHour = 11;
var html = ' ';
for (let i = startHour; i< 24; i++) {
html += `<div>${i < 10 ? `0${i}` : i}:00</div>`
}
for (let i = 0; i< endHour; i++) {
html += `<div>${i < 10 ? `0${i}` : i}:00</div>`
}
document.getElementById('hour').innerHTML = html; }, // Current time line showNowTime:function() {
var date = new Date();
var h = date.getHours(),
m = date.getMinutes();
var offset = (h - 5) * 60 + m;
var html = `<div class="nowTime" style="margin-left:${offset}px"></div>`;
document.getElementById('container').innerHTML += `<div class="gantt-item">${html}</div>`;
},
createData: function() { var data = this.demoData; var today = new Date().getDate(); // Today's datefor (let m = 0; m< data.length; m++) {
var innerData = data[m].innerData;
var html = ' ';
var allLeft = 0;
for (let i = 0; i< innerData.length; i++) {
var start = new Date(innerData[i].start),
end = new Date(innerData[i].end),
start_d = start.getDate(),
end_d = end.getDate(),
start_h = start.getHours(),
start_m = start.getMinutes(),
end_h = end.getHours(),
end_m = end.getMinutes(),
left_offset = 0;
_left_offset = 0;
width = ' ';
if (start_d === (today + 1)) {
left_offset = ((23 - 5) * 60) + ((start_h + 1) * 60) + start_m;
_left_offset = left_offset - allLeft;
width = (((23 + (end_h + 1)) - 5) * 60 + end_m) - left_offset;
} else if (end_d === (today + 1)) {
left_offset = ((start_h - 5) * 60) + start_m;
_left_offset = left_offset - allLeft;
width = (((24 + end_h) - 5) * 60 + end_m) - left_offset;
} else {
left_offset = (start_h - 5) * 60 + start_m;
_left_offset = left_offset - allLeft;
width = ((end_h - 5) * 60 + end_m) - left_offset;
}
allLeft = left_offset + width;
html += `<span style="width:${width}px; margin-left:${_left_offset}px;">${innerData[i].value}</span>`;
}
document.getElementById('container').innerHTML += `<div class="gantt-item" >${html}</div>`;
}
}
}
gantt.init();
</script>
</html>
Copy the code