当前位置: 首页 > news >正文

vue2.X 中使用 echarts5.4.0实现项目进度甘特图

vue2.X 中使用 echarts5.4.0实现项目进度甘特图

效果图:
在这里插入图片描述
左侧都是名称上面时间,当中的内容是日志内容

  1. 组件: gantt.vue
<template><div id="main" style="width: 100%; height: 100%"></div></template><script>import * as echarts from "echarts";export default {name: "Gantt",props: {baseDate: {type: String,default: "",},ganttData: {type: Array,default: () => [],},roomData: {type: Array,default: () => [],},},data() {return {minHours: '08:00',maxHours: '24:00',// colors: ['#5c2223','#346c9c', '#525288', '#87723e', '#d1c2d3','#f07c82', '#835e1d', '#d99156', '#954416', '#ee8055', '#126e82', '#61649f', '#a7a8bd']};},created() {},mounted() {this.myEcharts();},watch: {ganttData(newVal) {this.myEcharts();},},methods: {getTimes() {let baseDate = `${this.baseDate}`;// 获取日志的最早和最晚时间,这样防止两边出现空白,比如00:00-09:00;this.$http.post(`/sys/task/times`, {taskDate: baseDate}).then(({ data: res }) => {if (res.code !== 0) {return this.$message.error(res.msg)}this.minHours = res.data.minTimethis.maxHours = res.data.maxTime}).catch(() => {})},myEcharts() {this.getTimes();// 基于准备好的dom,初始化echarts实例const container = document.getElementById("main");this.$echarts.init(container).dispose();var myChart = this.$echarts.init(container);// 用于随机颜色var colors= ['#8dddfa','#f98e72', '#f7b84f', '#a872f9', '#d6a9d1','#a7e56d', '#ff73c7', '#d6a9d1', '#b1e7fb', '#d3b3af', '#2859b1', '#1f6cb0']//let min = `${this.$moment().format("YYYY-MM-DD")} 00:00:00`;//let max1 = `${this.$moment().add(1, "day").format("YYYY-MM-DD")} 00:00:00`;// 指定图表的配置项和数据var option = {color: "#0A8BFF",backgroundColor: "#fff",title: {},tooltip: {// enterable: true,trigger: "item",show: true,// axisPointer: { // 坐标轴指示器,坐标轴触发有效//   type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'// },// alwaysShowContent: true,hideDelay: 100,backgroundColor: "rgba(255,255,255,1)", // 背景颜色(此时为默认色)borderRadius: 5, // 边框圆角confine: true,textStyle: {color: "#000"},// 悬浮的时候展示对应的数据formatter: function (params) {for(var i = 0; i < params.data.value.length; i++) {var content = (params.data.value[i].content +// "<br/>" +// (params.data.value[i].status === "1" ? '<span style="color:#4dc394;">已完成</span>' : '<span style="color:#e5835b;">进行中</span>') +"<br/>" +params.data.value[i].stime +" - " +params.data.value[i].etime);// 作用:鼠标悬浮在内容,出现弹窗显示内容详情,这里限制了宽,以防止宽度过长var tooltipHtml = '<div style="width:fit-content; max-width: 500px; white-space: wrap;">'+content+'</div>';return tooltipHtml;//return content;}},},legend: {// left: '90px',top: "1%",itemWidth: 16,itemHeight: 16,show: true,// selectedMode: false, // 图例设为不可点击textStyle: {color: "rgba(0, 0, 0, 0.45)",fontSize: 14,},},grid: {// 绘图网格left: "2%",right: "3%",top: "10%",bottom: "10%",containLabel: true,},xAxis: {type: "time",position: "top",//  interval: 3600 * 1000, // 以一个小时递增// 以一小时的时间递增minInterval: 3600 * 1000 ,maxInterval: 3600 * 1000 ,min: `${this.baseDate} ` + this.minHours,max: `${this.baseDate} ` + this.maxHours,//max:`${this.baseDate} 24:00`,//max: `${this.baseDate} 19:00`, // 设置最大时间为18点//min:`${this.baseDate} 00:00`, //将data里最小时间的整点时间设为min,否则min会以data里面的min为开始进行整点递增//min: `${this.baseDate} 08:00`, // 将data里最小时间的整点时间设为min,否则min会以data里面的min为开始进行整点递增axisLabel: {// 设置最后一个数据显示showMaxLabel: true,formatter: function (value, index) {var data = new Date(value);var hours = data.getHours();var minutes = data.getMinutes();if ((index !== 0 && hours === 0) || index === 25){return "23:59"} else {//return hours + ":00";if (minutes === 0) {return hours + ":00";} else {return hours + ":" + minutes;}}},textStyle: {color: "rgba(0,0,0,0.65)", // 更改坐标轴文字颜色fontSize: 14, // 更改坐标轴文字大小},},axisLine: {lineStyle: {color: "#e5e5e5",},onZero: false,},splitLine: {show: true,lineStyle: {type: "dashed",},},},// dataZoom: [//   // 给x轴设置滚动条//   {//     type: 'slider',//     show: true,//     yAxisIndex: [0, 1],//     left: '96%',//     start: 1,//     end: 100,//     fiterMode: 'filter'//   },//   {//     type: 'inside',//     fiterMode: 'filter',//     yAxisIndex: [0, 1],//     start: 1,//     end: 100//   }// ],yAxis: {inverse: true, // 是否反转type: "category",axisTick:{show: true //不显示坐标轴刻度线},splitLine: {     //网格线"show": true},axisLine: {show: true,lineStyle: {color: "#e5e5e5",},},data: this.roomData,axisLabel: {textStyle: {color: "rgba(0, 0, 0, 0.65)", // 刻度颜色fontSize: 14, // 刻度大小},},},series: [{type: "custom",clickable: false,renderItem: function (params, api) {// 开发者自定义的图形元素渲染逻辑,是通过书写 renderItem 函数实现的var categoryIndex = api.value(0).index; // 这里使用 api.value(0) 取出当前 dataItem 中第一个维度的数值。var start = api.coord([api.value(0).startTime, categoryIndex]); // 这里使用 api.coord(...) 将数值在当前坐标系中转换成为屏幕上的点的像素值。var end = api.coord([api.value(0).endTime, categoryIndex]);var height = 26;return {type: "rect", // 表示这个图形元素是矩形。还可以是 'rect', 'circle', 'sector', 'polygon' 等等。shape: echarts.graphic.clipRectByRect({// 矩形的位置和大小。x: start[0],y: start[1] - height / 2,width: end[0] - start[0],height: 27,},{// 当前坐标系的包围盒。x: params.coordSys.x,y: params.coordSys.y,width: params.coordSys.width,height: params.coordSys.height,}),style: api.style(),};},label: {normal: {show: true,position: "insideBottom",formatter: function (params) {//return params.value[0].content;let value =  params.value[0].content;if (!value) return "";if (value.length > 6) {return value.slice(0, 6) + "...";}return value;},textStyle: {align: "center",fontSize: 14,fontWeight: "400",lineHeight: "20",},},},encode: {x: 1, // data 中『维度1』对应到 X 轴y: 0, // 把"维度0"映射到 Y 轴。},itemStyle: {normal: {color: function (params) {const randomIndex = Math.floor(Math.random() * colors.length);return colors[randomIndex];},},},// dataZoom: [//   {//     show: true,//     realtime: true,//     start: 0,//     end: 50//   }// ],data: this.ganttData,},],};// 使用刚指定的配置项和数据显示图表。myChart.setOption(option);window.onresize = function () {myChart.resize();};// myChart.getZr().on("mousemove", (param) => {//   var pointInPixel = [param.offsetX, param.offsetY];//   if (myChart.containPixel("grid", pointInPixel)) {//     // 若鼠标滑过区域位置在当前图表范围内 鼠标设置为小手//     // myChart.getZr().setBackgroundColor('red')//     myChart.getZr().setCursorStyle("pointer");//   } else {//     myChart.getZr().setCursorStyle("default");//   }// });// 任意位置点击事件----注册双击// myChart.getZr().on("click", (params) => {//   if (!params.target) {//     // 点击在了空白处,做些什么。//     const point = [params.offsetX, params.offsetY];//     if (myChart.containPixel("grid", point)) {//       // 获取被点击的点在y轴上的索引//       const idxArr = myChart.convertFromPixel({ seriesIndex: 0 }, point);//       const xValue = new Date(+idxArr[0]).getHours();//       const yValue = idxArr[1];//       const sendData = [xValue, yValue];//       this.$emit("getInfoCallback", sendData);//     }//   }// });// // 图例点击事件-返回数据给父组件---单击事件// myChart.on("click", (params) => {//   this.$emit("getInfoCallback", params.data.value);// });},},computed: {},};</script><style scoped lang="less"></style>
  1. js文件
import Gantt from './src/gantt'Gantt.install = function (Vue) {Vue.component(Gantt.name, Gantt)
}
export default Gantt
  1. main.js中组件引用组件
    在这里插入图片描述
    在这里插入图片描述
  2. log页面
<template><div class="appointment"><div class="a-gantt"><el-row style="padding: 12px 10px; background-color: #fff"><el-col :span="12" align="left" style="font-weight: 700">日志</el-col><el-col :span="12" align="right"><el-date-pickerv-model="baseDate"type="date"@change="handleSelect"placeholder="选择日期"value-format="yyyy-MM-dd"></el-date-picker></el-col></el-row></div><div class="f-gantt"><Gantt:baseDate="baseDate"ref="gantt":ganttData="ganttData"@getInfoCallback="getGanttInfo":roomData="roomData"></Gantt></div><!-- 新增编辑框 --><!-- <el-dialog :title="formTitle" :visible.sync="dialogVisible" width="30%"><el-form :model="form" :label-width="formLabelWidth"><el-form-item label="会议室"><el-inputdisabledv-model="usernameData[form.index]"autocomplete="off"></el-input></el-form-item><el-form-item label="内容"><el-input v-model="form.content" autocomplete="off"></el-input></el-form-item><el-form-item label="时间" :label-width="formLabelWidth"><el-date-pickerv-model="form.startTime"type="datetime"placeholder="选择日期"value-format="yyyy-MM-dd HH:mm"></el-date-picker>-<el-date-pickerv-model="form.endTime"type="datetime"placeholder="选择日期"value-format="yyyy-MM-dd HH:mm"></el-date-picker></el-form-item><el-form-item label="状态" :label-width="formLabelWidth"><el-select v-model="form.status" style="width: 100%"><el-option label="进行中" value="0"></el-option><el-option label="已完成" value="1"></el-option></el-select></el-form-item></el-form><span slot="footer" class="dialog-footer"><el-button @click="dialogVisible = false">取 消</el-button><el-button type="primary" @click="saveData">确 定</el-button></span></el-dialog> --></div>
</template><script>export default { data() {return {baseDate: `${new Date().getFullYear()}-${new Date().getMonth() + 1}-${new Date().getDate()}`,roomData: [],ganttData: [],dialogVisible: false,formLabelWidth: "120px",formTitle: "",form: {id: "",index: "",content: "",endTime: "",status: "",startTime: "",},};},created() {this.getDataList()// this.ganttData = [//   {//     value: [//       {//         index: 1,//         roomName: "会议室二",//         RoomId: "123",//         id: "333",//         startTime: '2023-09-05 08:28', //`${this.baseDate} 8:28`,//         endTime: '2023-09-05 09:28', // `${this.baseDate} 9:28`,//         status: "1",//         content: "睡觉",//       }//     ],//   },//   {//     value: [//     {//         index: 1,//         roomName: "会议室二",//         RoomId: "123",//         id: "333",//         startTime: '2023-09-05 12:28', //`${this.baseDate} 8:28`,//         endTime: '2023-09-05 15:28', // `${this.baseDate} 9:28`,//         status: "1",//         content: "工作",//       },//     ]//   },//   {//     value: [//       {//         index: 0,//         roomName: "会议室一",//         RoomId: "2234",//         id: "444",//         startTime: `2023-09-05 10:28`,//         endTime: `2023-09-05 12:28`,//         status: "0",//         content: "吃饭",//       },//     ],//   },//   {//     value: [//     {//         index: 0,//         roomName: "会议室一",//         RoomId: "123",//         id: "333",//         startTime: '2023-09-05 13:28', //`${this.baseDate} 8:28`,//         endTime: '2023-09-05 15:28', // `${this.baseDate} 9:28`,//         status: "1",//         content: "工作111",//       },//     ]//   }// ];//this.roomData = ['会议室一', '会议室二', '会议室三', '会议室四'];},mounted() {this.getDataList();},methods: {handleSelect() {this.getDataList()this.$refs.gantt.myEcharts();},getDataList() {this.$http.post(`/sys/task/ganteLog`, {taskDate: this.baseDate}).then(({ data: res }) => {if (res.code !== 0) {return this.$message.error(res.msg)}this.roomData = res.data.usernameListthis.ganttData = res.data.data}).catch(() => {})},getGanttInfo(data) {this.dialogVisible = true;// 根据data的长度判断是新增还是编辑// 新增if (data.length === 2) {this.formTitle = "新增";this.form = this.$options.data().form;this.$set(this.form, "index", data[1]);} else {this.formTitle = "修改";this.form = data[0];}},saveData() {if (this.formTitle === "修改") {this.ganttData = this.ganttData.filter((item) => {return item.value[0].id !== this.form.id;});} else {this.$set(this.form, "status", "0");}const obj = Object.assign({}, this.form);this.ganttData.push({ value: [obj] });this.$refs.gantt.myEcharts();this.dialogVisible = false;},},
};
</script><style scoped>
/* .a-gantt {position: absolute;top: 0;height: 60px;width: 100%;box-sizing: border-box;text-align: center;
} *//* .appointment {position: relative;height: 100%;overflow-y: hidden;border: 1px solid #ddd;color: #0f1419;box-sizing: border-box;
} */
.f-gantt {position: absolute;bottom: 10px;top: 80px;width: 100%;/*height: 600px;*/box-sizing: border-box;
}
</style>

注意数据结构
在这里插入图片描述

http://www.lryc.cn/news/165969.html

相关文章:

  • 《PostgreSQL与NoSQL:合作与竞争的关系》
  • 【FAQ】视频监控管理平台/视频汇聚平台EasyCVR安全检查相关问题及解决方法3.0
  • Java 8 新特性解读及应用实践
  • C++项目实战——基于多设计模式下的同步异步日志系统-④-日志系统框架设计
  • 计算机专业毕业设计项目推荐02-个人医疗系统(Java+原生Js+Mysql)
  • Nginx__高级进阶篇之LNMP动态网站环境部署
  • Zebec 生态 AMA 回顾:Nautilus 以及 $ZBC 的未来
  • NXP iMX8MM 修改 UART4至 Cortex-A53 核心
  • C#控制台程序中使用log4.net来输出日志
  • 用GPT干的18件事,能够真正提高学习生产力,建议收藏
  • 线性代数的本质(二)——线性变换与矩阵
  • JavaScript获取字符串的字节长度
  • [2023.09.13]: Rust Lang,避不开的所有权问题
  • Redux中间件源码解析与实现
  • 关于rsync用不了之后
  • 由一个多线程并发保存而引发的思考
  • python-vlc
  • 2023长城杯 web部分题目(seekingeasy_extension)
  • 2-1 张量数据结构
  • QSqlQuery查询语句
  • 用c语言编写出三底模型
  • 15 Python使用MySQL
  • 3、Nginx 常用的命令和配置文件
  • python经典百题之兔子出生问题
  • 不定积分的概念和性质
  • 远程访问服务器JupyterLab的配置方法
  • Java native 关键字
  • 【线性代数】沉浸式线性代数在线学习网站
  • Kotlin中特性、数据类、伴生对象、顶层函数
  • 《PostgreSQL物化视图:创建、维护与应用》