import echarts from 'echarts'; import { DeviceMenu } from '@/scripts/ConstDic'; import { timeFormat } from '@/utils/date'; export default { data() { return { createModel: { endStationCode: '', startStationCode: '', startTime: '' }, selected: null, dragging: false } }, watch: { myChart: function() { this.listenersBind(); } }, beforeDestroy() { this.listenersOff(); }, methods: { getStationByCoord(stations, y) { for(var i = stations.length-1; i >= 0; i--) { const station = stations[i]; const edge = this.planConvert.EdgeHeight const preKm = i == 0? edge*2: Math.abs(station.kmRange-stations[i-1].kmRange)/2; const nxtKm = i == stations.length-1? edge: Math.abs(station.kmRange-stations[i+1].kmRange)/2; const min = edge + station.kmRange - preKm; const max = edge + station.kmRange + nxtKm; if (y >= min && y <= max) { return station; } } return null; }, getStationByCoord2(stations, y) { for(var i = stations.length-1; i >= 0; i--) { const station = stations[i]; const edge = this.planConvert.EdgeHeight; const rate = this.planConvert.CoordMultiple; const preKm = i == 0? edge*2: rate/2; const nxtKm = i == stations.length-1? edge: rate/2; const min = edge + i*rate - preKm; const max = edge + i*rate + nxtKm; if (y >= min && y <= max) { return station; } } return null; }, pixelExecCb(e, cb) { const event = e.componentType ? e.event: e; const myChart = this.myChart; const pointInPixel = [event.offsetX, event.offsetY] if (myChart.containPixel('grid', pointInPixel) && this.planConvert) { const pointInGrid = myChart.convertFromPixel({seriesIndex:0},pointInPixel); const xIndex = pointInGrid[0]; const yIndex = pointInGrid[1]; const option = myChart.getOption(); const minY = option.yAxis[0].min; const xVal = option.xAxis[0].data[xIndex]; const yObj = this.getStationByCoord(this.stations, yIndex-minY); if (yObj && cb) { cb({yObj, xVal, pointInPixel, e}); } } }, listenersBind() { if (this.myChart) { const zr = this.myChart.getZr(); zr.on('mousedown', this.onZrMouseDown, this); zr.on('mouseup', this.onZrMouseUp, this); this.myChart.on('mousedown', this.onMouseDown); this.myChart.on('mouseover', this.onMouseOver); this.myChart.on('mouseout', this.onMouseOut); this.myChart.on('mouseup', this.onMouseUP); this.myChart.on('datazoom', this.onUpdatePosition); window.addEventListener('resize', this.onUpdatePosition); } }, listenersOff() { if (this.myChart) { const zr = this.myChart.getZr(); zr.off('mousedown', this.onZrMouseDown); zr.off('mouseup', this.onZrMouseUp, this); this.myChart.off('mousedown', this.onMouseDown); this.myChart.off('mouseover', this.onMouseOver); this.myChart.off('mouseout', this.onMouseOut); this.myChart.off('mouseup', this.onMouseUP); this.myChart.off('datazoom', this.onUpdatePosition); window.removeEventListener('resize', this.onUpdatePosition); } }, onUpdatePosition(e) { this.handleCancel(); const option = this.myChart.getOption(); const elements = option.graphic[0].elements const graphic = echarts.util.map(elements, (item) => { return { position: this.myChart.convertToPixel('grid', item.point)}; }) this.myChart.setOption({graphic}); }, onZrMouseDown(e) { switch(this.action) { case 'Add': this.pixelExecCb(e, this.handleCreateMark); break; } }, onZrMouseUp(e) { switch(this.action) { case 'Translate': if (this.dragging) { this.dragging = false; this.handleTranslate(this.createModel) } break; } }, onMouseDown(e) { switch(this.action) { case 'Edit': this.pixelExecCb(e, this.handlePopDialog); break; } }, onMouseOver(e) { this.pixelExecCb(e, this.handleSelectLine); if (this.action == 'Translate') { setTimeout(() => { this.onShapeMouseOver(e); }, 200); } }, onMouseOut(e) { this.pixelExecCb(e, this.handleSelectLine); if (this.action == 'Translate') { this.onShapeMouseOver(e); } }, onMouseUP(e) { // switch(this.action) { // case 'Translate': // if (this.dragging) { // this.dragging = false; // this.handleTranslate(this.createModel) // } // break; // } }, onShapePointDragging(e) { if (this.selected) { this.dragging = true; this.pixelExecCb(e, this.handleDragging); } }, onShapeMouseOver() { if (this.selected) { this.myChart.dispatchAction({ type: 'showTip', seriesIndex: this.selected.seriesIndex, dataIndex: this.selected.dataIndex }); } }, onShapeMouseOut() { if (this.selected) { this.myChart.dispatchAction({ type: 'hideTip', }); } }, setLineLight() { if (this.selected) { this.myChart.setOption({ series: { name: this.selected.seriesName, symbolSize: 10, showAllSymbol: true, lineStyle: { width: 2, color: 'red' } } }); } }, setLineReset() { if (this.selected) { this.myChart.setOption({ series: { name: this.selected.seriesName, symbolSize: 1, showAllSymbol: true, lineStyle: { width: 1, color: '#000' } } }); } }, clearGraphic(labels) { const option = this.myChart.getOption(); const elements = option.graphic[0].elements; option.graphic[0].elements = elements.filter(el => { return !labels.includes(el.subType)}); this.myChart.setOption(option, {notMerge: true}); }, createDragGraphicObj(point) { return { type: 'circle', subType: 'drag', position: this.myChart.convertToPixel('grid', point), point: [...point], shape: { cx: 0, cy: 0, r: 10 }, invisible: true, draggable: 'horizontal', ondrag: echarts.util.curry(this.onShapePointDragging), onmouseover: echarts.util.curry(this.onShapeMouseOver), onmouseout: echarts.util.curry(this.onShapeMouseOut), z: 100 } }, createMarkPointObj(point) { return { type: 'circle', subType: 'mark', z: 100, position: point, point: [...this.myChart.convertFromPixel('grid', point)], shape: { cx: 0, cy: 0, r: 10 }, style: { fill: 'rgba(0,0,0,0.3)' } } }, handlePopDialog({e, pointInPixel}) { if (e.componentType == "series" && e.componentSubType == "line" && e.seriesName.includes('run-')) { const value = e.value; const point = { x: pointInPixel[0], y: pointInPixel[1] } const option = this.myChart.getOption(); const dataList = option.series[e.seriesIndex].data; const length = dataList.length; const nxt = dataList[e.dataIndex+1]; const pre = dataList[e.dataIndex-1]; this.selected = { dataIndex: e.dataIndex, seriesIndex: e.seriesIndex, seriesName: e.seriesName, seriesId: e.seriesName.replace('run-', ''), depTime: e.dataIndex < length - 1? nxt[0] - value[0]: 0, runTime: e.dataIndex < length - 1? nxt[0] - value[0]: 0, stationCode: value[2], _x: value[0], dx: 0, time: 0 } if (e.dataIndex == length - 1 || e.dataIndex < length - 1 && value[1] == nxt[1]) { this.$store.dispatch('menuOperation/setPopMenu', { position: point, menu: DeviceMenu.planJustDeparture }); } else if (e.dataIndex == 0 || e.dataIndex > 0 && value[1] == pre[1]) { this.$store.dispatch('menuOperation/setPopMenu', { position: point, menu: DeviceMenu.planJustArrival }); } } }, handleSelectLine({e}) { if (e.componentType == "series" && e.componentSubType == "line" && e.seriesName.includes('run-')) { const value = e.value; const option = this.myChart.getOption(); const dataList = option.series[e.seriesIndex].data; const length = dataList.length; const nxt = dataList[e.dataIndex+1]; const pre = dataList[e.dataIndex-1]; if (this.selected && this.selected.seriesName != e.seriesName) { this.setLineReset(); } this.selected = { dataIndex: e.dataIndex, seriesIndex: e.seriesIndex, seriesName: e.seriesName, seriesId: e.seriesName.replace('run-', ''), depTime: e.dataIndex < length - 1? nxt[0] - value[0]: 0, runTime: e.dataIndex < length - 1? nxt[0] - value[0]: 0, stationCode: value[2], _x: value[0], dx: 0, time: 0 } this.setLineLight(); switch(this.action) { case 'Translate': this.handleCreateDrag({e}) break; } } }, handleCreateDrag({e}) { const option = this.myChart.getOption(); const filters = option.graphic[0].elements.filter(el => { return el.subType != 'drag'}); filters.push(this.createDragGraphicObj(e.value)) option.graphic[0].elements = filters; this.myChart.setOption(option, {notMerge: true}); this.myChart.dispatchAction({ type: 'showTip', seriesIndex: this.selected.seriesIndex, dataIndex: this.selected.dataIndex }); }, handleCreateMark({pointInPixel, yObj, xVal}) { const myChart = this.myChart; const option = this.myChart.getOption(); const graphic = option.graphic; const elements = graphic[0].elements; elements.push(this.createMarkPointObj(pointInPixel)) myChart.setOption(option, {notMerge: true}); const filters = elements.filter(el => { return el.subType == 'mark'}); if (filters.length == 1) { this.createModel.startStationCode = yObj.code; this.createModel.startTime = timeFormat(xVal); } else if (filters.length >= 2) { this.createModel.endStationCode = yObj.code; this.handleCreateTrip(this.createModel); } }, handleDragging({e, xVal}) { this.selected.dx = xVal - this.selected._x; this.selected.time += this.selected.dx; this.selected._x = xVal; const option = this.myChart.getOption(); const model = option.series[this.selected.seriesIndex] if (model) { model.data.forEach(el => { el[0] += this.selected.dx; }); } if (e.target && e.target.point && e.target.position) { e.target.point[0] += this.selected.dx; } this.myChart.setOption(option, {notMerge: true}); } } }