vue 实现类似甘特图大屏效果

news/2024/11/24 6:45:36/

最近在做大屏展示,其中一个需求是展示生产过程中投料情况,效果类似甘特图。
思路: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>

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

相关文章

echarts大屏数据可视化展示

P25 可视化面板介绍 ​ 应对现在数据可视化的趋势&#xff0c;越来越多企业需要在很多场景(营销数据&#xff0c;生产数据&#xff0c;用户数据)下使用&#xff0c;可视化图表来展示体现数据&#xff0c;让数据更加直观&#xff0c;数据特点更加突出。 一.使用技术 完成该项…

Vue 可视化大屏适配插件

注册 vue 指令如何支持类型提示? 文档说 vue 插件的 use方法是支持第二个参数的&#xff0c;一开始打算通过第二个参数做基础配置。能正确读取到该参数&#xff0c;可是不知道怎么做类型提示&#xff0c;因为官方定义的是 any[]&#xff0c; 那我总不能让使用者去从我的插件里…

web端大屏适配解决方案

背景:近期公司投放在展厅大屏中演示的大数据页面&#xff0c;出现了文字、图表、表格等多类组件显示错乱的情况。 目的 解决页面错乱问题&#xff0c;实现多种分辨率的大屏适配 入坑分析 俗话说的好&#xff0c;走过的最多路&#xff0c;就是网友们套路 vh、vw、rem组合方式…

前端大屏项目的屏幕适配方案

最近在写大屏项目, 技术栈是echartsvue, 在屏幕适配调研了很久, 网上有多种方案, 但都有自己的局限性,比如css媒体查询代码量巨大,且变化过程不平滑, vw适合定宽的不方便缩放的组件. 并不适合等比例缩放所有组件, 最后,我发现等比例缩放所有组件的话更适合用css变量来设置scale…

echarts、dataV 数据可视化大屏

一、项目描述 &#xff08;包含echarts中国地图、dataV科技炫酷边框等等&#xff09; 一个基于 Vue、Datav、Echart 框架的 " 数据大屏项目 "&#xff0c;通过 Vue 组件实现数据动态刷新渲染&#xff0c;内部图表可实现自由替换。部分图表使用 DataV 自带组件&#x…

vue实现酷炫可视化大屏

vue实现可视化大屏 技术要点效果图项目搭建代码编写 技术要点 vue2lessechartsv-chartsflexible 主要采用v-chartsecharts进行实现图表可视化 效果图 项目搭建 采用vue-cli脚手架进行项目创建 vue create 项目名称项目结构: 代码编写 v-charts官网:https://v-charts.js.org/…

FineReport_大屏搭建详细过程

最终呈现结果(比文档要详细) 一、将所需图表拉直决策报表中 选择绝对布局&#xff0c;可以设置大小 二、准备好数据源&#xff0c;设置各图表数据 点击图表--编辑--数据--设置数据源&#xff0c;&#xff0c;此处可查看帮助文档中各图表的详细设置&#xff0c;设置数据来源、…

模板学堂丨Zabbix监控告警大屏

DataEase开源数据可视化分析平台模板市场&#xff08; https://dataease.io/templates/&#xff09;于2022年6月正式发布。模板市场旨在为DataEase用户提供专业、美观、拿来即用的仪表板模板&#xff0c;方便用户根据自身的业务需求和使用场景选择对应的仪表板模板&#xff0c;…