From e985c73e00b42e5a99dd61839155432c5d95e945 Mon Sep 17 00:00:00 2001 From: lb Date: Sun, 8 Oct 2023 17:14:18 +0800 Subject: [PATCH] update gantt --- .../equipment/timing-diagram/status/demo.js | 338 ++++++++++ .../timing-diagram/status/index copy.vue | 607 ++++++++++++++++++ .../equipment/timing-diagram/status/index.vue | 114 ++-- 3 files changed, 984 insertions(+), 75 deletions(-) create mode 100644 src/views/equipment/timing-diagram/status/index copy.vue diff --git a/src/views/equipment/timing-diagram/status/demo.js b/src/views/equipment/timing-diagram/status/demo.js index e69de29b..134173e6 100644 --- a/src/views/equipment/timing-diagram/status/demo.js +++ b/src/views/equipment/timing-diagram/status/demo.js @@ -0,0 +1,338 @@ +import * as echarts from 'echarts' + +function getStartTime(timestamp) { + return new Date(new Date(timestamp).toLocaleDateString()).getTime(); +} + +function renderItem(params, api) { + var categoryIndex = api.value(0); + var start = api.coord([api.value(1), categoryIndex]); + var end = api.coord([api.value(2), categoryIndex]); + + var height = api.size([0, 1])[1] * 2; + var rectShape = echarts.graphic.clipRectByRect( + { + x: start[0], + y: start[1] - height / 2, + width: end[0] - start[0], + height: height, + }, + { + x: params.coordSys.x, + y: params.coordSys.y - 16, + width: params.coordSys.width, + height: params.coordSys.height, + } + ); + + return ( + rectShape && { + type: 'rect', + transition: ['shape'], + shape: rectShape, + style: api.style(), + } + ); +} + +// unused +function getXaxisRange(startTime) { + return Array(24) + .fill(startTime) + .map((item, index) => { + return new Date(item + index * 3600 * 1000) + .toLocaleTimeString() + .split(':') + .slice(0, 2) + .join(':'); + }); +} + +function getTodayStart(today) { + const [y, m, d] = [ + today.getFullYear(), + today.getMonth(), + today.getDate(), + ]; + // debugger; + return new Date(y, m, d).getTime(); +} + + +/** 颜色配置 */ +const types = [ + { name: '运行', color: '#288AFF' }, + { name: '故障', color: '#FC9C91' }, + { name: '计划停机', color: '#FFDC94' }, + { name: '空白', color: '#F2F4F9' }, +]; + + +export default class GanttGraph { + // tooltip - 基本是固定的 + tooltip = { + trigger: 'item', + axisPointer: { + type: 'none', + }, + formatter: (params) => { + return ` +
+

${params.seriesName}

+

${params.name}

+
+
${new Date(params.value[1]).toLocaleString()} ~ ${new Date(params.value[2]).toLocaleString()}
+ ` + } + } + grid = [] + xAxis = [] + yAxis = [] + series = [] + + constructor(data, startTime) { + this.gridIndex = 0; + this.currentXaxisId = null; + this.currentYaxisId = null; + // this.startTime = new Date(startTime); + this.startTime = new Date(new Date().toLocaleDateString()); + console.log('<> Gantt Created', this.startTime); + + this.grid.push(this.makeGrid()) + this.xAxis.push(...this.makeXaxis()) + this.yAxis.push(...this.makeYaxis("设备1")) + this.series.push(...this.makeSeries({ equipmentName: "设备1" })) + + } + + // 构造一个新的 grid + makeGrid() { + this.gridIndex++; + return { + id: 'GRID_' + this.gridIndex, + top: 12 + 64 * (this.gridIndex - 1), + right: 64, + height: 56 + } + } + + // 构造一个 xAxis + makeXaxis() { + const [id1, id2] = ['' + Math.random(), '' + Math.random()] + this.currentXaxisId = id1; + return [ + { + id: id1, + gridIndex: 'GRID_' + this.gridIndex, + axisTick: { + alignWithLabel: true, + inside: true, + }, + type: 'time', + min: getTodayStart(this.startTime), + max: getStartTime(this.startTime.getTime() + 3600 * 24 * 1000), + splitNumber: 10, + axisLabel: { + margin: 12, + formatter: function (val) { + return new Date(val) + .toLocaleTimeString() + .split(':') + .slice(0, 2) + .join(':'); + }, + }, + boundaryGap: false, + // data: getXaxisRange(getTodayStart(new Date())), + }, + { + id: id2, + gridIndex: 'GRID_' + this.gridIndex, + axisLabel: { show: false }, + axisLine: { show: false }, + }, + ] + } + + + // 构造一个 yAxis + makeYaxis(equipmentName) { + const [id1, id2] = ['' + Math.random(), '' + Math.random()] + this.currentYaxisId = id1; + return [ + // 主y轴 + { + id: id1, + gridIndex: 'GRID_' + this.gridIndex, + type: 'value', + splitLine: { show: false }, + name: equipmentName, + nameLocation: 'center', + nameGap: 56, + nameRotate: 0, + nameTextStyle: { + fontSize: 18, + }, + axisLine: { + show: true, + lineStyle: {}, + }, + axisLabel: { show: false }, + axisTick: { show: false }, + }, + // 辅y轴 + { + id: id2, + gridIndex: 'GRID_' + this.gridIndex, + type: 'value', + splitLine: { show: false }, + axisLabel: { show: false }, + axisTick: { show: false }, + }, + ] + } + + // 构造一个 series + makeSeries({ equipmentName }) { + const { currentXaxisId: xAxisIndex, currentYaxisId: yAxisIndex } = this; + const bgStartTime = this.startTime.getTime(); + const bgEndTime = bgStartTime + 3600 * 24 * 1000; + return [ + // 沉默的背景 + { + xAxisIndex, + yAxisIndex, + type: 'custom', + renderItem: renderItem, + silent: true, + itemStyle: { + opacity: 0.8, + }, + encode: { + x: [1, 2], + y: 0, + }, + data: [ + { + name: '无数据', + value: [0, bgStartTime, bgEndTime, 0], + tooltip: { show: false }, + itemStyle: { + color: '#ccc', + opacity: 0.3, + } + }, + ] + }, + { + name: equipmentName, + xAxisIndex, + yAxisIndex, + type: 'custom', + renderItem: renderItem, + itemStyle: { + opacity: 0.8, + }, + encode: { + x: [1, 2], + y: 0, + }, + data: [ + // 暂时先静态数据 + { + name: '运行', + value: [0, 1696694400000, 1696699400000, 0], + itemStyle: { + + color: types[0].color, + + }, + }, + { + name: '运行', + value: [0, 1696730000000, 1696734040450, 0], + itemStyle: { + + color: types[0].color, + + }, + }, + { + name: '故障', + value: [0, 1696737040000, 1696754040450, 0], + itemStyle: { + + color: types[1].color, + + }, + }, + { + name: '计划停机', + value: [0, 1696755000000, 1696759000000, 0], + itemStyle: { + + color: types[2].color, + + }, + }, + { + name: '运行', + value: [0, 1696759000000, 1696769000000, 0], + itemStyle: { + + color: types[0].color, + + }, + }, + { + name: '计划停机', + value: [0, 1696769400000, 1696779000000, 0], + itemStyle: { + + color: types[2].color, + + }, + }, + ], + }, + ] + } + + init(el) { + if (typeof el == 'string') { + el = document.querySelector(el); + } + this.chart = echarts.init(el); + + setTimeout(() => { + console.log("init....", this.chart, this.option); + debugger; + this.chart.setOption(this.option); + }, 200); + } + + update(data) { + // todo , handle data + this.chart.setOption(this.option); + } + + resize() { + this.chart.resize(); + } + + get option() { + return { + tooltip: this.tooltip, + grid: this.grid, + xAxis: this.xAxis, + yAxis: this.yAxis, + series: this.series, + } + } + + // print option + print() { + console.log(JSON.stringify(this.option, null, 2)); + } + +} \ No newline at end of file diff --git a/src/views/equipment/timing-diagram/status/index copy.vue b/src/views/equipment/timing-diagram/status/index copy.vue new file mode 100644 index 00000000..afae93a2 --- /dev/null +++ b/src/views/equipment/timing-diagram/status/index copy.vue @@ -0,0 +1,607 @@ + + + + + + + diff --git a/src/views/equipment/timing-diagram/status/index.vue b/src/views/equipment/timing-diagram/status/index.vue index afae93a2..d20550d4 100644 --- a/src/views/equipment/timing-diagram/status/index.vue +++ b/src/views/equipment/timing-diagram/status/index.vue @@ -6,31 +6,19 @@ -->