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

news2024/11/25 4:59:25

基于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.coloradmin.cn/o/459498.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ESD/EMI防护设计

内容摘取自<Rockchip_RK3568_Hardware_Design_Guide_V1.0_CN.pdf> 1.1概述 本章对于RK3568产品设计中的ESD/EMI防护设计给出了建议&#xff0c;帮助客户更好的提高产品的抗静电、抗电 磁干扰水平。 1.2 术语解释 本章中的术语解释如下&#xff1a;  ESD&#xff08;E…

直播预告丨打破 Python 束缚:Level 2 因子的脚本优化实践

有人说&#xff0c;DolphinDB 是一个时序数据库&#xff1b; 也有人说&#xff0c;DolphinDB 就是 Python 加数据库的结合&#xff1b;还有人说&#xff0c;DolphinDB 是一个支持流数据处理的实时计算软件…… 我们经常会听到类似的理解&#xff0c;其实很多小伙伴都会有好奇…

Python爱心表白,快去发给你心仪的人叭~

作者主页&#xff1a;爱笑的男孩。的博客_CSDN博客-深度学习,YOLO,活动领域博主爱笑的男孩。擅长深度学习,YOLO,活动,等方面的知识,爱笑的男孩。关注算法,python,计算机视觉,图像处理,深度学习,pytorch,神经网络,opencv领域.https://blog.csdn.net/Code_and516?typecollect个人…

Hive ---- Hive入门

Hive ---- Hive入门 1. 什么是Hive1. Hive简介2. Hive本质 2. Hive架构原理1. 用户接口&#xff1a;Client2. 元数据&#xff1a;Metastore3. 驱动器&#xff1a;Driver4. Hadoop 1. 什么是Hive 1. Hive简介 Hive是由Facebook开源&#xff0c;基于Hadoop的一个数据仓库工具&a…

关于 mysql本地使用ODBC连接突然无法连接上且无法搜索到database的 解决方法

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/130360385 红胖子网络科技的博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软…

关于Open Shift(OKD) 中应用管理部署的一些笔记

写在前面 因为参加考试&#xff0c;会陆续分享一些 OpenShift 的笔记博文内容为介绍 openshift 不同的创建应用的方式&#xff0c;包括&#xff1a; 基于 IS 创建应用基于镜像创建应用基于源码和 image 创建应用基于源码和 IS 创建应用基于模板创建应用 学习环境为 openshift v…

ChatGPT + MindShow 三分钟搞定PPT制作

制作一份“通用性”的PPT需要几步&#xff1f; 三步 接下来&#xff0c;我们借助ChatGPT和MindShow&#xff0c;大概三分钟完成操作&#xff0c;就能制作出来完胜大部分人的PPT文件。具体可看文末效果导示。 解锁更多AIGC&#xff08;ChatGPT、AI绘画&#xff09;玩法&#…

与其关注“孔乙己的长衫”,不如来看看什么是套接字

孔乙已是鲁迅笔下人物&#xff0c;穷困流倒还穿着象征读书人的长衫&#xff0c;迁腐、麻木。最近&#xff0c;大家自我调佩是“当代孔乙己”&#xff0c;学历成为思想负担&#xff0c;找工作时高不成低不就。 套接字概念 Socket本身有“插座”的意思&#xff0c;在Linux环境下…

Model-Contrastive Federated Learning 论文解读(CVPR 2021)

Model-Contrastive Federated Learning 论文解读 对比学习SimCLR 对比学习的基本想法是同类相聚&#xff0c;异类相离 从不同的图像获得的表征应该相互远离&#xff0c;从相同的图像获得的表征应该彼此靠近 具体框架&#xff1a; T随机数据增强模块&#xff1a;随机裁剪然…

米文动力 EVO Orin 刷机和克隆操作说明

刷机说明 博主在卸载 cuda 以及 python 后重启后黑屏无法显示&#xff0c;重刷系统才恢复正常。 下载 EVO Orin 用户手册&#xff08;官网没有&#xff0c;所以上传到 CSDN 供下载&#xff09;官网下载 EVO Orin 镜像文件 使用 tar -xvf 解压下载的 bootloader 和镜像包得到 …

实用提示和技巧:如何优化您的接口自动化测试工作流程?

目录 摘要 流程概述 常用工具 示例代码 结论 摘要 接口自动化测试是软件开发过程中至关重要的一环&#xff0c;它可以为开发团队提供稳定、高效的交付管道&#xff0c;并保证质量。在本文中&#xff0c;我们将介绍接口自动化测试的基本流程和常用工具&#xff0c;并提供一…

day33—选择题

文章目录 1.若一个用户进程通过read 系统调用读取一个磁盘文件中的数据&#xff0c;则下列关于此过程的叙述中&#xff0c;正确的是&#xff08;A&#xff09;2.Linux文件权限一共10位长度&#xff0c;分成四段&#xff0c;第三段表示的内容是&#xff08;C&#xff09;3.进程阻…

计算机毕业论文内容参考|人工智能|探索网络与人工智能的交叉领域

文章目录 导文文章重点摘要:引言:挑战与机遇:实际应用:结论:导文 计算机毕业论文内容参考|人工智能|探索网络与人工智能的交叉领域 文章重点 摘要: 人工智能(AI)和计算机网络的结合导致了一个新的研究领域,称为网络人工智能。网络人工智能涉及开发使计算机能够学习、…

.Net Framework 4.6.1+版本的Winform程序开启Web服务,支持Http webapi

Winform程序开启Web服务 背景思路方法1方法2方法3&#xff08;本文使用的方法&#xff09; 实现在winform程序中引入几个nuget包新建一个Startup类&#xff08;叫什么名字都行&#xff09;修改Program文件创建controller 运行效果(打开浏览器&#xff0c;输入如下地址&#xff…

“量子+生成式AI”!IBM联合生物制药公司Moderna进行疫苗研究

​ &#xff08;图片来源&#xff1a;网络&#xff09; 4月20日&#xff0c;以COVID-19疫苗而闻名的生物技术和制药公司Moderna Inc.表示&#xff0c;宣布正在与IBM公司合作&#xff0c;利用量子计算和生成式人AI探索推进研究mRNA技术的方法。 双方签署了一项协议&#xff0c;允…

python 基础系列篇:七、以函数方式编写一个数字华容道

python 基础系列篇&#xff1a;七、以函数方式编写一个数字华容道 数字华容道游戏分析开始编写完整代码代码解说定义方法的规律 小结 数字华容道 嗯&#xff0c;就是一个简单的益智游戏&#xff0c;把数字按照特定规律排列&#xff0c;并比矩阵少一个格&#xff0c;用来进行移…

CRM客户关系管理系统主要有哪些功能?

一、CRM客户管理系统是什么 客户关系管理&#xff08;Customer Relationship Management&#xff0c;简称CRM&#xff09;&#xff0c;是指企业为提高核心竞争力&#xff0c;利用相应的信息技术以及互联网技术协调企业与顾客间在销售、营销和服务上的交互&#xff0c;从而提升…

将CSDN博客内容转为PDF进行下载

打开博客文章页面–F12–控制台–输入以下代码-回车–选择“另存为PDF”–设置样式并预览–打印 回车之后需要等待一些时间 设置之后导出即可 (function(){ use strict;var articleBox $("div.article_content");articleBox.removeAttr("style");…

超低延时交换机助力金融证券极速交易场景应用

一、 极速交易技术的兴起 随着计算机技术和金融科技的快速发展&#xff0c;量化交易和高频交易在全球金融市场中已经被运用到各种交易场景&#xff0c;特别是在股票&#xff0c;期货&#xff0c;期权等衍生品市场&#xff0c;已经逐渐取代人工做市&#xff08;market maker)&am…