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)); } }