基于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 += `<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>`;
  1. 首先需要找到时间段中开始时间的开始位置,
  2. 计算出时间的width,遵循1px = 1M的规则。
  3. 在设置margin-left时,记得减去上一个时间段甘特图的margin-left(重点)。
  4. 没绘制一条后,存储其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>

基于JS实现简单甘特图相关推荐

  1. html 绘制甘特图,基于JS简单甘特图

    最近同事求助到一个小小的需求,写一个时间甘特图,主要想表现一个车在一天的不同的时间点里,停靠的站点, 先来看一下效果吧,这里的需求是从早上的5点为开始时间,到第二天到凌晨5点 前期准备 其实网上有很多 ...

  2. 超简单甘特图教程,一招教你如何管理项目进程

    甘特图可以让使用对象能更直观的了解到项目在某一时间的内容和进展,当然,它也不同于时间表或日程规划表,而是一个具有特殊代表性的甘特图. 甘特图常见用途 甘特图不仅仅是用来作业排序的,也可用于发展各式各样 ...

  3. Qt基于定时器实现简单动图展示(2例)

    目录 总体概述 (1)总体介绍 (2)素材获得途径 (3)通用函数介绍 ①绘图函数 ②定时器事件 第一例:单一动图展示 第二例:分组动图展示 总体概述 (1)总体介绍 动图展示主要是将已有的动图逐帧图 ...

  4. 基于web的甘特图,易度甘特图edogantt!

    易度甘特图发布1.6版本 EdoGantt是使用Javascript开发的.基于WEB浏览器的甘特图解决方案.可广泛应用于项目管理系统. ERP 系统.MES系统或其它的任务资源分配相关领域. Edo ...

  5. 如何使用CSS和JavaScript构建简单的甘特图

    到目前为止,在我们CSS图表系列教程中,我们已经学习了如何创建不同类型的图表,包括条形图,温度计图和饼图. 今天,我们将通过在甘特图中构建和呈现数据来继续这一旅程. 与其他图表教程不同,我们将大量使用 ...

  6. 使用Highcharts来画一个简易的甘特图

    前端组件 – 甘特图 由于在项目中需要画一个基于时间的对比甘特图,但缺乏前端知识,便在网上寻找相关插件或者已有代码. 文章目录 前端组件 -- 甘特图 前言 一.Highcharts? 二.使用 1. ...

  7. Twproject Gantt – 开源的 JavaScript 甘特图组件

    Twproject Gantt 是一款基于 jQuery 开发的甘特图组件,也可以创建其它图表,例如任务树(Task Trees).内置编辑.缩放和 CSS 皮肤等功能.更重要的是, 它是免费开源的. ...

  8. Excel甘特图 Gantt Chart

    基于Excel开发的甘特图,保留Excel的功能,单元格可嵌入各种公式,设置字体,颜色,背景 不需要Projector,比Projector更简单易用 具备节点标记,今日显示,大项任务突出显示,进度标 ...

  9. 有多少甘特图工具和资源是你熟悉的?

    https://www.evget.com/article/2014/6/27/21239.html 概述:本文整理了13款甘特图的最流行和最有效的甘特图工具和资源,可以更方便.更有效地创建甘特图列表 ...

  10. Ext Scheduler Web资源甘特图控件

    原文来自 http://www.fanganwang.com/Product-detail-item-1430.html欢迎转载. 关键字: 资源甘特图又叫负荷图,其纵轴不再列出活动,而是列出整个部门 ...

最新文章

  1. 不占用多余空间实现值的交换——异或运算
  2. [转]笑话: 耐力惊人的三只乌龟
  3. html游戏闪,HTML最简单的文字闪烁代码
  4. SQL Server-事务处理(Tansaction)与锁(Lock)
  5. 基于java springboot+mybatis学生学科竞赛管理管理系统设计和实现
  6. Ubuntu 20.04部署minikube配置不上阿里云的minikube镜像
  7. linux系统ntp服务监听端口,Linux系统 NTP服务器配置详解
  8. 有哪些比较好的免费简历网站?
  9. 台达PLC变频器通讯程序
  10. hover事件获取当前元素信息
  11. map 转换成vo_JAVAMap转换为Bean或VO
  12. GitHub / 码云 Pages 打造个人在线简历
  13. 线性约束最小方差准则
  14. 10-特质-Scala
  15. 如何在微图中提取生成等高线
  16. 给零基础初学者推荐的10个Python免费学习网站,赶快收藏
  17. pyaudio录制音频和播放音频
  18. [分享]浅谈分布式数据库
  19. 贵州大学2021计算机分数线,贵州大学录取分数线2021是多少分(附历年录取分数线)...
  20. 【自制】WS2812光立方

热门文章

  1. Unity 艺术字体制作
  2. 使用am instrument验证CTS问题
  3. 获取文件名,文件名后缀以及elementui多张图片回显
  4. 当天使爱上吸血鬼,上帝开始哭泣
  5. 编译bib文件,报错repeated entry
  6. Contextual Parameter Generation for Knowledge Graph Link Prediction
  7. Adaptive Supply Chain: Demand–Supply Synchronization Using Deep Reinforcement Learning翻译
  8. Java 源文件的命名规则
  9. Python3爬取拉钩网职位,并分析
  10. celeste实用技巧(第2弹)