基于JS实现简单甘特图

您所在的位置:网站首页 甘特图进度条怎么做 基于JS实现简单甘特图

基于JS实现简单甘特图

2023-09-20 13:21| 来源: 网络整理| 查看: 265

基于JS实现简单甘特图

最近同事求助到一个小小的需求,写一个时间甘特图,主要想表现一个车在一天的不同的时间点里,停靠的站点,

先来看一下效果吧,这里的需求是从早上的5点为开始时间,到第二天到凌晨5点 在这里插入图片描述

前期准备

其实网上有很多甘特图的实现方式,但是他们都只能具象到天,不能具体到某个时间点,而且每一个具体的时间段中的描述是不能自定义的,所以准备自己写一下了。

实现逻辑

我们可以先模拟一些demo数据,这里面最为主要的数据为每个时间点,我们要实现上面的效果,需要对每个时间点进行拆分。

var demoData: [ { carNum: '川A09384', innerData: [ { start: '2019/1/21 6:23', end: '2019/1/21 7:45', value: 'A站点', bg: 'green' }, { start: '2019/1/21 12:23', end: '2019/1/21 16:45', value: 'B站点', bg: 'yellow' }, { start: '2019/1/21 20:00', end: '2019/1/21 23:25', value: 'C站点', bg: 'blue' } ] }, { carNum: '川A04384', innerData: [ { start: '2019/1/21 5:23', end: '2019/1/21 6:05', value: 'A站点', bg: 'blue' }, { start: '2019/1/21 10:23', end: '2019/1/21 13:45', value: 'B站点', bg: 'green' }, { start: '2019/1/21 21:00', end: '2019/1/22 3:35', value: 'C站点', bg: 'yellow' }, ] }] 首先创建时间 // 创建时间 createHours: function(){ var startHour = 5; var endHour = 11; var html = ''; for (let i = startHour; i< 24; i++) { html += `${i < 10 ? `0${i}` : i}:00` } for (let i = 0; i< endHour; i++) { html += `${i < 10 ? `0${i}` : i}:00` } document.getElementById('hour').innerHTML = html; }, 根据数据绘制甘特图

我们将 1H = 60px;这样去定宽,即 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('2019/1/21 7:45'), start_h = start.getHours(), // 开始时间 start_m = start.getMinutes(), // 开始分钟 end_h = end.getHours(), // 结束时间 end_m = end.getMinutes(), // 结束分钟 left_offset = 0; _left_offset = 0; width = ''; // 获取时间段甘特图的开始位置(我们从5点开始,所以-5); left_offset = (start_h - 5) * 60 + start_m; // 获取每一段甘特图的宽度, // 先计算出结束时间的位置,然后在减去开始时间的左边距; width = ((end_h - 5) * 60 + end_m) - left_offset; // 使用现有的左边距减去前一个时间的左边距 _left_offset = left_offset - allLeft; // 因为存在多个时间段,所以在绘制下一个时间断时,left_offset // 使用allLeft存储上一个时间断距离左边的距离。 allLeft = left_offset + width; // 将其添加到DOM中 html += `${innerData[i].value}`; 首先需要找到时间段中开始时间的开始位置,计算出时间的width,遵循1px = 1M的规则。在设置margin-left时,记得减去上一个时间段甘特图的margin-left(重点)。没绘制一条后,存储其margin-left,方便下一个时间段使用。 关于跨天怎么计算

当我们的时间段是属于跨天的怎么计算他的开始和结束位置,以及他的宽度呢?直接贴代码了哈,

createData: function() { var data = this.demoData; var today = new Date().getDate(); // 今天的日期 for (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 += `${innerData[i].value}`; } document.getElementById('container').innerHTML += `${html}`; } }

这个地方就不详细解说了,有什么不懂的地方欢迎大家留言。代码很简洁,主要用于实现一个比较简单的甘特图。不需要下载什么插件之类的。

这里把代码贴出来哈,大家可以一起交流,或许你有更好的实现方式呢。

测试demo #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,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; } 车牌号 川A09384 川A09384 川A09384 var gantt = { demoData: [ { innerData: [ { start: '2019/1/21 6:23', end: '2019/1/21 7:45', value: 'A站点', bg: 'green' }, { start: '2019/1/21 12:23', end: '2019/1/21 16:45', value: 'B站点', bg: 'yellow' }, { start: '2019/1/21 20:00', end: '2019/1/21 23:25', value: 'C站点', bg: 'blue' } ] }, { innerData: [ { start: '2019/1/21 5:23', end: '2019/1/21 6:05', value: 'A站点', bg: 'blue' }, { start: '2019/1/21 10:23', end: '2019/1/21 13:45', value: 'B站点', bg: 'green' }, { start: '2019/1/21 21:00', end: '2019/1/22 3:35', value: 'C站点', bg: 'yellow' }, ] }, { innerData: [ { start: '2019/1/21 8:23', end: '2019/1/21 10:05', value: 'A站点', bg: 'blue' }, { start: '2019/1/21 13:23', end: '2019/1/21 14:45', value: 'B站点', bg: 'green' }, { start: '2019/1/21 22:00', end: '2019/1/22 3:35', value: 'C站点', bg: 'red' }, { start: '2019/1/22 4:00', end: '2019/1/22 7:35', value: 'D站点', bg: 'green' }, ] }, ], // 初始化 init: function() { this.showNowTime(); this.createHours(); this.createData(); }, // 创建时间 createHours: function(){ var startHour = 5; var endHour = 11; var html = ''; for (let i = startHour; i< 24; i++) { html += `${i < 10 ? `0${i}` : i}:00` } for (let i = 0; i< endHour; i++) { html += `${i < 10 ? `0${i}` : i}:00` } document.getElementById('hour').innerHTML = html; }, // 当前时间线 showNowTime: function() { var date = new Date(); var h = date.getHours(), m = date.getMinutes(); var offset = (h - 5) * 60 + m; var html = ``; document.getElementById('container').innerHTML += `${html}`; }, createData: function() { var data = this.demoData; var today = new Date().getDate(); // 今天的日期 for (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 += `${innerData[i].value}`; } document.getElementById('container').innerHTML += `${html}`; } } } gantt.init();


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3