最近在做大屏展示,其中一个需求是展示生产过程中投料情况,效果类似甘特图。
思路:1.先得到整个过程的开始时间startTime和结束时间endTime。计算出整个过长经历的时长。
2.计算横向坐标的开始时间start和结束时间end,坐标的开始时间为生产开始时间-百分之十的生产时长,即start = startTime - 0.1h;坐标的结束时间为生产结束时间+百分之十的生产时长,即end = endTime + 0.1h.
3.确定横纵坐标值,先计算横计算坐标间隔,我固定了横坐标的打点数,直接用横坐标结束时间-坐标开始时间除以点数+1,即 (end-start) / (number +1)。得到间隔之后就可以计算出横坐标值。纵坐标值直接使用物料名称
4.显示每个料的投放情况显示出来。显示是用的div,每种物料的投料时长就是div的长度。
注意:计算宽度的时候需要依据自己的实际情况进行调整
效果
代码
<template><div class="Gantt"><div class="content" ref="scrollbar"><!-- <el-scrollbar> --><divclass="info"style="margin-top: 2px; overflow: scroll; overflow-x: hidden;height: calc(100vh * 220 / 1080);"><div id="gui-content" class="gui-content"><divclass="gui-list clear room-gui-list"v-for="task in taskList":key="task.materialId"><div id="name" class="fasten ellipsis" :title="task.name">{{ task.name }}</div><div class="gui-tab"><liv-for="(o, i) in config.xAxis":key="i" :style="{width: 100 / (number + 1) + '%',cursor: 'pointer',}"></li></div><template v-if="task.materialId"><divv-for="(item, index) in task.materialData":key="index"class="meet-item-one"v-bind:class="[!item.status ? 'meet-color-having' : 'meet-color-finished',]":style="{left: getLeftTime(item.startTime) + '%',width: getWidth(item) + '%',backgroundColor: item.color,// opacity:0.8}"v-show="getWidth(item) != 0"@click="edit(item)"><el-popoverplacement="top-start"trigger="hover":style="{fontSize:'10px',padding:'0px'}"><p>{{'开始:'+item.startTime}}</p><p>{{'结束:'+item.endTime}}</p><div slot="reference" class="meet-item-one-content"><p class="ellipsis" >{{ item.content }}</p></div></el-popover></div></template></div></div></div><!-- </el-scrollbar> --><div class="time-bar clear"><div class="gui-table clear"><li:style="{width: 100 / (number + 1) +'%',}"v-for="(item, index) in config.xAxis":key="index"><div class="gui-cle"></div><div class="gui-lit"></div><div class="gui-title"><span class="">{{item.xAxis}}</span></div></li></div></div></div></div></template><script>import {Popover,Scrollbar} from 'element-ui'export default {name: "GanttDemo",data() {return {date: "",number:6,xInterval:0.1,config: {xAxis:[]},taskList: [{materialId: "1",name: "物料一",startTime: "2022-11-16 08:00:00",endTime: "2022-11-16 20:00:00",materialData: [{materialId: "1",id: "14444",status: 0,startTime: '2022-11-16 08:00:00',endTime: '2022-11-16 12:00:00',color:"#32c5e9",content:"800",},{materialId: "1",id: "15555",status: 0,startTime: '2022-11-16 18:30:10',endTime: '2022-11-16 20:00:00',color:"#32c5e9",content:"600",},],},{materialId: "2",name: "物料二",startTime: "2022-11-16 20:00:00",endTime: "2022-11-16 23:30:00",materialData:[{materialId: "2",id: "223865",status: 0,startTime: '2022-11-16 20:00:00',endTime: '2022-11-16 23:30:00',color:"#eb865e",content:"800",},]},{materialId: "3",name: "物料三",startTime: "2022-11-16 15:00:00",endTime: "2022-11-16 16:30:00",materialData:[{materialId: "3",id: "31",status: 0,startTime: '2022-11-16 15:00:00',endTime: '2022-11-16 16:30:00',color:"#eb865e",content:"500",},]},{materialId: "4",name: "物料四",startTime: "2022-11-16 12:00:00",endTime: "2022-11-16 16:30:00",materialData:[{materialId: "4",id: "41",status: 0,startTime: '2022-11-16 12:00:00',endTime: '2022-11-16 16:30:00',color:"#eb865e",content:"450",},]},{materialId: "5",name: "物料五",startTime: "2022-11-16 11:00:00",endTime: "2022-11-16 15:30:00",materialData:[{materialId: "5",id: "51",status: 0,startTime: '2022-11-16 11:00:00',endTime: '2022-11-16 15:30:00',color:"#eb865e",content:"300",},]},{materialId: "6",name: "物料六",startTime: "2022-11-16 11:00:00",endTime: "2022-11-16 12:30:00",materialData:[{materialId: "6",id: "61",status: 0,startTime: '2022-11-16 11:00:00',endTime: '2022-11-16 12:30:00',color:"#eb865e",content:"200",},]},{materialId: "7",name: "物料七",startTime: "2022-11-16 09:00:00",endTime: "2022-11-16 10:30:00",materialData:[{materialId: "7",id: "71",status: 0,startTime: '2022-11-16 09:00:00',endTime: '2022-11-16 10:30:00',color:"#eb865e",content:"300",},]},]};},components:{elPopover: Popover,elScrollbar:Scrollbar,},props:{},watch:{},mounted(){this.getConfig();},methods: {getLeftTime(cTime) {const dTime = new Date(cTime).getTime();const leftTime = new Date(this.config.startTime).getTime();const time = (dTime - leftTime) / (1000 * 60 * 60); // 小时数const leftPercent = 0.88 * (time * 100) / (this.xInterval * (this.number+1)) ;return leftPercent + 12;},getWidth(item) {const _left1 = this.getLeftTime(item.startTime);const _left2 = this.getLeftTime(item.endTime);return _left2 - _left1;},edit(item) {console.log(item);},getConfig(){if(this.taskList.length>0){let startTime = this.taskList[0].startTime;let endTime = this.taskList[0].endTime;console.log(endTime)for(let index in this.taskList){let task = this.taskList[index];let start1 = startTime?new Date(startTime):new Date();let start2 = new Date(task.startTime);if(start1 > start2 && null != task.startTime){startTime = task.startTime;}let end1 = new Date(endTime);let end2 = new Date(task.endTime?task.endTime:start2);if(end1 < end2){endTime = task.endTime;}}let hour =((new Date(endTime)).getTime() - (new Date(startTime)).getTime());this.config.start = startTime;this.config.end = endTime;this.config.startTime = this.getDateTime(new Date((new Date(startTime)).getTime()-0.1*hour));this.config.endTime = this.getDateTime(new Date((new Date(endTime)).getTime()+0.1*hour));hour = ((new Date(this.config.endTime)).getTime() - (new Date(this.config.startTime)).getTime());this.config.hour = hour;if(hour){this.xInterval = (hour / (this.number+1)) / (1000*60*60);}this.config.xAxis = []let hh = (new Date(this.config.startTime)).getHours() < 10 ? '0' + (new Date(this.config.startTime)).getHours() : (new Date(this.config.startTime)).getHours();let mm = (new Date(this.config.startTime)).getMinutes() < 10 ? '0' + (new Date(this.config.startTime)).getMinutes() : (new Date(this.config.startTime)).getMinutes();let xOne = hh +":" +mm;this.config.xAxis.push({xAxis:xOne});for(let i = 0;i < this.number;i++){console.log();let node = (new Date(this.config.startTime)).getTime()+(this.xInterval * 60 *60 * 1000 * ( i + 1 ));let nodeHh = (new Date(node)).getHours() < 10 ? '0' + (new Date(node)).getHours() : (new Date(node)).getHours();let nodeMm = (new Date(node)).getMinutes() < 10 ? '0' + (new Date(node)).getMinutes() : (new Date(node)).getMinutes();let nodeX = nodeHh + ":" + nodeMm;this.config.xAxis.push({xAxis:nodeX});}}},getDateTime(time){let year = time.getFullYear(); //获取年 2021let month = time.getMonth() + 1; // 获取月 5let day = time.getDate(); // 获取天 11let h = time.getHours() < 10 ? '0' + time.getHours() : time.getHours(); // 获取小时 18let m = time.getMinutes() < 10 ? '0' + time.getMinutes() : time.getMinutes(); // 获取分钟 42let s = time.getSeconds() < 10 ? '0' + time.getSeconds() : time.getSeconds(); // 获取秒 51let dataTime = year + '-' + month + '-' + day + ' ' + h + ':' + m + ':' + s;return dataTime;},}};</script><style lang="scss" scoped >.Gantt {padding: calc(100vw * 20 / 1920 );;border-radius: 3px;/* border: 1px solid red; */height: 100%;box-sizing: border-box;display: flex;flex-direction: column-reverse;position: relative;}.content {padding-top: calc(100vw * 20 / 1920 );}.content /deep/ .el-scrollbar{height: calc(100vh * 220 / 1080);.el-scrollbar__wrap {overflow-x: hidden;}}.content /deep/ .el-scrollbar__view {height: 100%;// display: flex;// flex-direction: column-reverse;}.Gantt .gui-table,.gui-tab {font-size: calc(100vw * 12 / 1920 );color: #333;margin: 0;width: 88%;float: right;white-space: nowrap;height: calc(100vh * 48 / 1080 );}.Gantt .gui-table li {position: relative;border-top: solid 1px #1ba5fa;z-index: 666;word-wrap: break-word;}.Gantt .gui-table li {cursor: default;}.Gantt .gui-table li{float: left;text-align: left;width: 8.9%;height: calc(100vh * 48 / 1080 );line-height: calc(100vh * 48 / 1080 );/* cursor: pointer; */white-space: pre-wrap;}.Gantt .gui-table .gui-title{line-height: calc(100vh * 24 / 1080 );position: relative;width: 100%;}.Gantt .gui-table .gui-title span{line-height: calc(100vh * 24 / 1080 );color: rgba(255,255,255,.7);position: absolute;left: -50%;text-align: center;width: 100%;}.gui-tab li {float: left;text-align: left;width: 8.9%;height: calc(100vh * 28 / 1080 );line-height: calc(100vh * 28 / 1080 );/* cursor: pointer; */white-space: pre-wrap;}.Gantt .gui-cle {position: absolute;left: -5px;top: -5px;width: 6px;height: 6px;background: #fff;border-radius: 50%;border: solid 2px #1ba5fa;z-index: 666;}.Gantt .gui-lit {position: absolute;left: 0;top: -3px;width: 3px;height: 3px;background: #fff;border-radius: 50%;border: solid 1px #1ba5fa;margin-left: 50%;z-index: 666;}.clear {*zoom: 1;}.clear:after {content: ".";display: block;clear: both;visibility: hidden;line-height: 0;height: 0;font-size: 0;}.Gantt .fasten {width: 12%;float: left;height: calc(100vh * 28 / 1080 );text-align: center;line-height: calc(100vh * 28 / 1080 );font-size: calc(100vw * 12 / 1920 );color: rgba(255, 255, 255, .7);border-right: solid 1px #1ba5fa;/* word-break: break-word;white-space: pre-line; */}.Gantt .gui-table{font-size: calc(100vw * 12 / 1920 );color: #333;margin: 0;width: 88%;float: right;white-space: nowrap;height: calc(100vh * 48 / 1080 );}.gui-tab {font-size: calc(100vw * 12 / 1920 );color: #333;margin: 0;width: 88%;float: right;white-space: nowrap;height: calc(100vh * 28 / 1080 );}/* .Gantt .gui-list:first-child {background: #fff;} */.Gantt .gui-list {position: relative;display: flex;}.Gantt .meet-color-finished {background: #4dc394;}.Gantt .meet-color-having {background: #eb865e;}.Gantt .meet-item-one {color: #000;text-align: center;position: absolute;height: calc(100vh * 26 / 1080 );left: 12%;top: 1px;color: #fafafa;font: 14px/60px microsoft yahei;/* padding: 0 5px; */box-sizing: border-box;-moz-box-sizing: border-box;-webkit-box-sizing: border-box;overflow: hidden;cursor: pointer;width: 20%;line-height: calc(100vh * 26 / 1080 );}li {list-style: none;}.Gantt .meet-item-one-content{height: 100%;}.ellipsis {overflow: hidden;margin-top: 0;white-space: nowrap;text-overflow: ellipsis;line-height: calc(100vh * 28 / 1080 );}.info,.gui-content{display: flex;flex-direction: column-reverse;}.info::-webkit-scrollbar {width : 5px; height: 1px;}.info::-webkit-scrollbar-thumb {box-shadow: 0px 1px 3px rgba(144,147,153,.3) inset; /*滚动条的内阴影*/border-radius: 10px; /*滚动条的圆角*/background-color: rgba(144,147,153,.3); /*滚动条的背景颜色*/}.info::-webkit-scrollbar-track {box-shadow: 0px 1px 3px #071e4a inset; /*滚动条的背景区域的内阴影*/border-radius: 10px; /*滚动条的背景区域的圆角*/background-color: #071e4a; /*滚动条的背景颜色*/}/* .gui-yAxis{position: absolute;height: 100%;border: solid 1px #1ba5fa;} */</style>