基于JS简单甘特图(IT枫斗者)

news/2024/12/22 14:10:40/

基于JS简单甘特图

基于JS简单甘特图

  • 先来看一下效果吧,这里的需求是从早上的5点为开始时间,到第二天到凌晨5点
  • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B8Vr2UUt-1681777493839)(C:\Users\quyanliang\AppData\Roaming\Typora\typora-user-images\1681777293302.png)]

前期准备

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

实现逻辑

  • 我们可以先模拟一些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 += `<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;
    },
    

根据数据绘制甘特图

  • 我们将 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 += `<span style="width:${width}px;margin-left:${_left_offset}px;">${innerData[i].value}</span>`;
    
  • 首先需要找到时间段中开始时间的开始位置,

  • 计算出时间的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 += `<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>`;
    }
    }
    
  • 这个地方就不详细解说了,有什么不懂的地方欢迎大家留言。代码很简洁,主要用于实现一个比较简单的甘特图。不需要下载什么插件之类的。

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

  • <html><head><title>测试demo</title><style type="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,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><div style="line-height:30px;">川A09384</div><div style="line-height:30px;">川A09384</div><div style="line-height:30px;">川A09384</div></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: '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 += `<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;},// 当前时间线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(); // 今天的日期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 += `<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>
    

http://www.ppmy.cn/news/53619.html

相关文章

【环境配置】Window上Git clone 如何提高速度

步骤一&#xff1a;得到ip 在下列网站上 https://www.ipaddress.com/ 分别搜索&#xff1a; github.global.ssl.fastly.netgithub.com然后记录得到的IP地址 步骤二&#xff1a; 修改host 在Windows中&#xff0c;先进入&#xff1a;C:\Windows\System32\drivers\etc 目录 …

HTML 颜色名

所有浏览器支持的颜色名称 所有现代浏览器均支持以下 140 种颜色名称(单击颜色名称或十六进制值可将颜色查看为背景颜色与不同的文本颜色的搭配): 有关 HTML 颜色的完整概述,请访问我们的颜色教程。 颜色名十六进制颜色值颜色AliceBlue#F0F8FFAntiqueWhite#FAEBD7Aqua#00…

elasticsearch结构化查询

在上一篇中我们介绍了DSL相关的知识&#xff0c;接下来我们将会学习elasticsearch的结构化查询&#xff0c;同时也实践一下上一篇的DSL的查询用法 什么是结构化搜索? 从《Elasticsearch权威指南》上摘取部分解释如下: 结构化搜索是指查询包含内部结构的数据。日期&#xff0…

JS-11G/11端子排静态时间继电器 JOSEF约瑟 导轨安装

JS-11G系列端子排静态时间继电器品牌&#xff1a;JOSEF约瑟名称&#xff1a;端子排静态时间继电器型号&#xff1a;JS-11G工作电压&#xff1a;48,110,220V返回时间&#xff1a;≤20mS延时范围&#xff1a;0.02S~999M 系列型号&#xff1a; JS-11G1端子排静态时间继电器&…

一文带你学会如何写一份糟糕透顶的简历

我们每个人几乎都会面对找工作这件事,而找工作或者说求职首先就是要写一份简历。今天狗哥将以一个不同的视角带你写一份无与伦比,糟糕透顶的求职简历,说实话,其实几年前,我就是这么写的。 目录 1. 文件名 2. 基本信息 3. 教育经历 4. 技术能力

2023天梯赛补题

题目详情 - L2-047 锦标赛 (pintia.cn) 思路&#xff1a; 这是一棵倒着的树&#xff0c;我们每次匹配时&#xff0c;必须当前的值大于左儿子或者右儿子的最大值&#xff0c;否则无答案。因为我们需要存储哪个位置还没放人&#xff0c;发现当前位置左儿子与右儿子都是有且仅有…

电影元素主题:《黑客帝国》中的js加密与解密

在《黑客帝国》中&#xff0c;加密和解密是非常重要的概念。加密是将信息转换为看起来毫无意义的数据&#xff0c;以确保只有拥有解密密钥的人才能读取和理解它。在这篇文章中&#xff0c;我们将探讨如何使用JavaScript进行加密和解密&#xff0c;就像黑客们在电影中所做的那样…

Python/Haskell 实现异步通信机制

###Python实现异步通信机制 在 Python 中,可以使用协程(Coroutine)来实现异步通信机制。协程是一种轻量级的线程,可以在单线程环境下实现并发,从而避免了线程切换的开销和复杂性。在 Python 3.5 及以后的版本中,引入了 asyncio 模块来支持协程编程。 下面是一个简单的示…