修改AUSTool 功能

This commit is contained in:
lVAL 2020-10-21 18:36:52 +08:00
parent 599e092c57
commit c1050d16ab
25 changed files with 2366 additions and 1783 deletions

View File

@ -120,7 +120,7 @@ export function justTripNoStop(tripNo, data) {
/**
* 平移车次
*/
export function translateTripNo(tripNo, data) {
export function translateTrip(tripNo, data) {
return request({
url: `/api/rpTools/${tripNo}/trip`,
method: 'put',

View File

@ -0,0 +1,268 @@
import { createSeriesModel, createMarkLineModels, createMartPoint } from './utils';
import { toTimeStamp } from '@/utils/date';
export default {
/** 边缘高度*/
EdgeHeight: 600,
/** 间隔高度*/
CoordMultiple: 1,
/** 偏移时间*/
TranslationTime: 0,
/** 将后台数据解析成图形*/
parseDataToGraph(chart, planData, stations, kmRangeCoordinateMap) {
const graphs = [];
if (planData &&
planData.areaList &&
planData.areaList.length) {
planData.areaList.forEach(area => {
const startTime = toTimeStamp(area.startTime);
const endTime = toTimeStamp(area.endTime);
const fartherKm = this.getCoordinateYByObj(stations, kmRangeCoordinateMap, {stationCode: area.fartherStationCode});
const closerKm = this.getCoordinateYByObj(stations, kmRangeCoordinateMap, {stationCode: area.closerStationCode});
const point1 = [ startTime, fartherKm];
const point2 = [ endTime, closerKm]
const position = chart.convertToPixel('grid', point1);
const position2 = chart.convertToPixel('grid', point2)
const width = Math.abs(position[0] - position2[0]);
const height = Math.abs(position[1] - position2[1]);
graphs.push({
type: 'rect',
subType: 'Area',
areaNo: area.areaNo,
position,
point1,
point2,
model: area,
shape: {
x: 0,
y: 0,
width,
height
},
style: {
fill: 'rgb(255,0,0, 0.3)',
stroke: 'rgb(255, 0, 0, 0.8)'
},
z: 100
})
})
}
return graphs;
},
/** 将后台数据解析成折线*/
parseDataToSeries(chart, planData, stations, kmRangeCoordinateMap) {
const models = [];
if (planData &&
planData.serviceList &&
planData.serviceList.length) {
planData.serviceList.forEach((service,i) => {
if (service.tripList &&
service.tripList.length) {
service.tripList.forEach((trip,j) => {
const opt = {
name: `plan-${service.serviceNo}-${trip.tripNo}-${trip.direction}`,
type: 'line',
symbolSize: 1,
showAllSymbol: true,
markPoint: { data: [] },
data: []
};
var lastPoint = null;
var nextPoint = null;
var pointData = {
name: `${service.serviceNo}-${trip.tripNo}`,
color: '#000',
direction: trip.direction,
coord: [trip.stationTimeList[0].departureTime, this.getCoordinateYByObj(stations, kmRangeCoordinateMap, trip.stationTimeList[0], trip.direction, false)],
};
opt.markPoint.data.push(createMartPoint(pointData));
trip.stationTimeList.forEach(elem => {
const name = `${trip.direction}${trip.tripNo}`;
if (elem.arrivalTime) {
opt.data.push([elem.arrivalTime, this.getCoordinateYByObj(stations, kmRangeCoordinateMap, elem, elem.direction, false), {
stationCode: elem.stationCode,
serviceNo: service.serviceNo,
tripNo: trip.tripNo,
direction: trip.direction,
name
}]);
}
if (elem.departureTime) {
opt.data.push([elem.departureTime, this.getCoordinateYByObj(stations, kmRangeCoordinateMap, elem, elem.direction, false), {
stationCode: elem.stationCode,
serviceNo: service.serviceNo,
tripNo: trip.tripNo,
direction: trip.direction,
name
}]);
}
});
const model = createSeriesModel(opt,
{ color: '#000', width: 1 },
{ color: '#000', fill: '#000'}
);
models.push(model);
if (service.tripList[j + 1] &&
service.tripList[j + 1].stationTimeList) {
const opt = {
name: `reentry-${service.serviceNo}-${trip.tripNo}-${trip.direction}`,
type: 'line',
symbolSize: 1,
showAllSymbol: false,
markPoint: { data: [] },
data: []
};
lastPoint = trip.stationTimeList[trip.stationTimeList.length-1];
nextPoint = service.tripList[j + 1].stationTimeList[0];
const name = `${trip.direction}${trip.tripNo}`;
opt.data.push([lastPoint.arrivalTime, this.getCoordinateYByObj(stations, kmRangeCoordinateMap, lastPoint, trip.direction, false), {
stationCode: lastPoint.stationCode,
serviceNo: service.serviceNo,
tripNo: trip.tripNo,
direction: trip.direction,
name
}]);
opt.data.push([lastPoint.arrivalTime, this.getCoordinateYByObj(stations, kmRangeCoordinateMap, lastPoint, trip.direction, true), {
stationCode: lastPoint.stationCode,
serviceNo: service.serviceNo,
tripNo: trip.tripNo,
direction: trip.direction,
name
}]);
opt.data.push([nextPoint.departureTime, this.getCoordinateYByObj(stations, kmRangeCoordinateMap, lastPoint, trip.direction, true), {
stationCode: lastPoint.stationCode,
serviceNo: service.serviceNo,
tripNo: trip.tripNo,
direction: trip.direction,
name
}]);
opt.data.push([nextPoint.departureTime, this.getCoordinateYByObj(stations, kmRangeCoordinateMap, lastPoint, trip.direction, false), {
stationCode: lastPoint.stationCode,
serviceNo: service.serviceNo,
tripNo: trip.tripNo,
direction: trip.direction,
name
}]);
const model = createSeriesModel(opt,
{ color: '#000', width: 1 },
{ color: '#000', fill: '#000'}
);
models.push(model);
}
});
}
})
}
return models;
},
/** 更新数据并解析成折线*/
updateDataToModels(chart, planData, stations, kmRangeCoordinateMap, series) {
if (planData && planData.length) {
}
return series;
},
/** 初始化Y轴*/
initializeYaxis(stations) {
return createMarkLineModels(stations, (elem) => {
return this.EdgeHeight + elem.kmRange * this.CoordMultiple;
});
},
/** 将后台数据转换为试图序列模型*/
convertStationsToMap(stations) {
var map = {};
if (stations && stations.length) {
stations.forEach((elem) => {
map[`${elem.kmRange}`] = this.EdgeHeight + elem.kmRange * this.CoordMultiple;
});
}
return map;
},
/** 计算y轴最小值*/
computedYaxisMinValue(stations) {
return stations[0].kmRange * this.CoordMultiple;
},
/** 计算y轴最大值*/
computedYaxisMaxValue(stations) {
return stations[stations.length - 1].kmRange * this.CoordMultiple + this.EdgeHeight * 2;
},
/** 格式化y轴数据*/
computedFormatYAxis(stations, params) {
var yText = '0m';
stations.forEach(elem => {
if (elem.kmRange < parseInt(params.value) / this.CoordMultiple - this.EdgeHeight) {
yText = Math.floor(elem.kmRange) + 'm';
}
});
return yText;
},
/** 根据方向计算y折返偏移量*/
getYvalueByDirectionCode(defaultVlue, direction) {
if (direction === '1') {
defaultVlue -= this.EdgeHeight / 2;
} else if (direction === '2') {
defaultVlue += this.EdgeHeight / 2;
}
return defaultVlue;
},
/** 根据elem计算y值*/
getCoordinateYByObj(stations, kmRangeCoordinateMap, obj, direction, isSpecial) {
var defaultVlue = 0;
var station = stations.find(it => { return it.code == obj.stationCode; });
if (station) {
defaultVlue = kmRangeCoordinateMap[`${station.kmRange}`];
if (isSpecial) {
defaultVlue = this.getYvalueByDirectionCode(defaultVlue, direction);
}
}
return defaultVlue;
},
/** 通过y坐标获取站信息 */
getStationByCoordinate(stations, y) {
for(var i = stations.length-1; i >= 0; i--) {
const station = stations[i];
const edge = this.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;
}
};

View File

@ -1,4 +1,4 @@
import { createSeriesModel, createMarkLineModels, createMartPoint } from './utils';
import { createSeriesModel, createMarkLineModels, createRectArea, createMartPoint } from './utils';
import { toTimeStamp } from '@/utils/date';
export default {
@ -12,7 +12,7 @@ export default {
TranslationTime: 0,
/** 将后台数据解析成图形*/
parseDataToGraph(chart, planData, stations, kmRangeCoordinateMap) {
parseDataToGraph(chart, planData, stations) {
const graphs = [];
if (planData &&
planData.areaList &&
@ -21,8 +21,8 @@ export default {
const startTime = toTimeStamp(area.startTime);
const endTime = toTimeStamp(area.endTime);
const fartherKm = this.getCoordinateYByObj(stations, kmRangeCoordinateMap, {stationCode: area.fartherStationCode});
const closerKm = this.getCoordinateYByObj(stations, kmRangeCoordinateMap, {stationCode: area.closerStationCode});
const fartherKm = this.getCoordinateYByStationCode(stations, area.fartherStationCode);
const closerKm = this.getCoordinateYByStationCode(stations, area.closerStationCode);
const point1 = [ startTime, fartherKm];
const point2 = [ endTime, closerKm]
const position = chart.convertToPixel('grid', point1);
@ -30,26 +30,15 @@ export default {
const width = Math.abs(position[0] - position2[0]);
const height = Math.abs(position[1] - position2[1]);
graphs.push({
type: 'rect',
subType: 'Area',
graphs.push(createRectArea({
areaNo: area.areaNo,
model: area,
position,
point1,
point2,
model: area,
shape: {
x: 0,
y: 0,
width,
height
},
style: {
fill: 'rgb(255,0,0, 0.3)',
stroke: 'rgb(255, 0, 0, 0.8)'
},
z: 100
})
width,
height
}));
})
}
@ -57,7 +46,7 @@ export default {
},
/** 将后台数据解析成折线*/
parseDataToSeries(chart, planData, stations, kmRangeCoordinateMap) {
parseDataToSeries(chart, planData, stations) {
const models = [];
if (planData &&
planData.serviceList &&
@ -66,108 +55,85 @@ export default {
if (service.tripList &&
service.tripList.length) {
service.tripList.forEach((trip,j) => {
const opt = {
name: `plan-${service.serviceNo}-${trip.tripNo}-${trip.direction}`,
type: 'line',
symbolSize: 1,
showAllSymbol: true,
markPoint: { data: [] },
data: []
};
const opt = {
name: `service${service.serviceNo}`,
type: 'line',
symbolSize: 1,
showAllSymbol: true,
markPoint: { data: [] },
data: []
};
service.tripList.forEach((trip,j) => {
var lastPoint = null;
var nextPoint = null;
var pointData = {
name: `${service.serviceNo}-${trip.tripNo}`,
color: '#000',
direction: trip.direction,
coord: [trip.stationTimeList[0].departureTime, this.getCoordinateYByObj(stations, kmRangeCoordinateMap, trip.stationTimeList[0], trip.direction, false)],
coord: [trip.stationTimeList[0].departureTime, this.getCoordinateYByStationCode(stations, trip.stationTimeList[0].stationCode)],
};
opt.markPoint.data.push(createMartPoint(pointData));
trip.stationTimeList.forEach(elem => {
const name = `${trip.direction}${trip.tripNo}`;
if (elem.arrivalTime) {
opt.data.push([elem.arrivalTime, this.getCoordinateYByObj(stations, kmRangeCoordinateMap, elem, elem.direction, false), {
opt.data.push([elem.arrivalTime, this.getCoordinateYByStationCode(stations, elem.stationCode), {
stationCode: elem.stationCode,
serviceNo: service.serviceNo,
tripNo: trip.tripNo,
direction: trip.direction,
name
silent: false
}]);
}
if (elem.departureTime) {
opt.data.push([elem.departureTime, this.getCoordinateYByObj(stations, kmRangeCoordinateMap, elem, elem.direction, false), {
opt.data.push([elem.departureTime, this.getCoordinateYByStationCode(stations, elem.stationCode), {
stationCode: elem.stationCode,
serviceNo: service.serviceNo,
tripNo: trip.tripNo,
direction: trip.direction,
name
silent: false
}]);
}
});
const model = createSeriesModel(opt,
{ color: '#000', width: 1 },
{ color: '#000', fill: '#000'}
);
models.push(model);
if (service.tripList[j + 1] &&
service.tripList[j + 1].stationTimeList) {
const opt = {
name: `reentry-${service.serviceNo}-${trip.tripNo}-${trip.direction}`,
type: 'line',
symbolSize: 1,
showAllSymbol: false,
markPoint: { data: [] },
data: []
};
lastPoint = trip.stationTimeList[trip.stationTimeList.length-1];
nextPoint = service.tripList[j + 1].stationTimeList[0];
const name = `${trip.direction}${trip.tripNo}`;
opt.data.push([lastPoint.arrivalTime, this.getCoordinateYByObj(stations, kmRangeCoordinateMap, lastPoint, trip.direction, false), {
stationCode: lastPoint.stationCode,
serviceNo: service.serviceNo,
tripNo: trip.tripNo,
direction: trip.direction,
name
}]);
opt.data.push([lastPoint.arrivalTime, this.getCoordinateYByObj(stations, kmRangeCoordinateMap, lastPoint, trip.direction, true), {
stationCode: lastPoint.stationCode,
serviceNo: service.serviceNo,
tripNo: trip.tripNo,
direction: trip.direction,
name
}]);
opt.data.push([nextPoint.departureTime, this.getCoordinateYByObj(stations, kmRangeCoordinateMap, lastPoint, trip.direction, true), {
stationCode: lastPoint.stationCode,
serviceNo: service.serviceNo,
tripNo: trip.tripNo,
direction: trip.direction,
name
}]);
opt.data.push([nextPoint.departureTime, this.getCoordinateYByObj(stations, kmRangeCoordinateMap, lastPoint, trip.direction, false), {
stationCode: lastPoint.stationCode,
serviceNo: service.serviceNo,
tripNo: trip.tripNo,
direction: trip.direction,
name
}]);
const model = createSeriesModel(opt,
{ color: '#000', width: 1 },
{ color: '#000', fill: '#000'}
);
models.push(model);
opt.data.push({
value: [lastPoint.arrivalTime, this.getCoordinateYByStationCode(stations, lastPoint.stationCode, true, trip.direction), {
stationCode: lastPoint.stationCode,
serviceNo: service.serviceNo,
tripNo: trip.tripNo,
direction: trip.direction,
silent: true
}],
symbol: 'none',
symbolSize: 1,
});
opt.data.push({
value: [nextPoint.departureTime, this.getCoordinateYByStationCode(stations, lastPoint.stationCode, true, trip.direction), {
stationCode: lastPoint.stationCode,
serviceNo: service.serviceNo,
tripNo: trip.tripNo,
direction: trip.direction,
silent: true
}],
symbol: 'none',
symbolSize: 1,
});
}
});
const model = createSeriesModel(opt,
{ color: '#000', width: 1 },
{ color: '#000', fill: '#000'}
);
models.push(model);
}
})
}
@ -176,7 +142,7 @@ export default {
},
/** 更新数据并解析成折线*/
updateDataToModels(chart, planData, stations, kmRangeCoordinateMap, series) {
updateDataToModels(chart, planData, stations, series) {
if (planData && planData.length) {
}
return series;
@ -189,18 +155,6 @@ export default {
});
},
/** 将后台数据转换为试图序列模型*/
convertStationsToMap(stations) {
var map = {};
if (stations && stations.length) {
stations.forEach((elem) => {
map[`${elem.kmRange}`] = this.EdgeHeight + elem.kmRange * this.CoordMultiple;
});
}
return map;
},
/** 计算y轴最小值*/
computedYaxisMinValue(stations) {
return stations[0].kmRange * this.CoordMultiple;
@ -225,29 +179,29 @@ export default {
},
/** 根据方向计算y折返偏移量*/
getYvalueByDirectionCode(defaultVlue, direction) {
getOffsetYByDirection(value, direction) {
if (direction === '1') {
defaultVlue -= this.EdgeHeight / 2;
value -= this.EdgeHeight / 2;
} else if (direction === '2') {
defaultVlue += this.EdgeHeight / 2;
value += this.EdgeHeight / 2;
}
return defaultVlue;
return value;
},
/** 根据elem计算y值*/
getCoordinateYByObj(stations, kmRangeCoordinateMap, obj, direction, isSpecial) {
var defaultVlue = 0;
var station = stations.find(it => { return it.code == obj.stationCode; });
/** 通过站信息获取y坐标*/
getCoordinateYByStationCode(stations, stationCode, isSpecial=false, direction='01') {
var value = 0;
var station = stations.find(it => { return it.code == stationCode; });
if (station) {
defaultVlue = kmRangeCoordinateMap[`${station.kmRange}`];
value = this.EdgeHeight + station.kmRange * this.CoordMultiple;
if (isSpecial) {
defaultVlue = this.getYvalueByDirectionCode(defaultVlue, direction);
value = this.getOffsetYByDirection(value, direction);
}
}
return defaultVlue;
return value;
},
/** 通过y坐标获取站信息 */

View File

@ -20,11 +20,10 @@ export function createMartPoint(opt) {
};
}
/** 创建一个车次数据序列*/
/** 创建一个服务数据序列*/
export function createSeriesModel(opt, lineStyle={}, itemStyle={}) {
return {
z: opt.z || 5,
zlevel: opt.zlevel || 0,
z: opt.z || 2,
type: 'line',
name: opt.name,
data: opt.data,
@ -42,12 +41,47 @@ export function createSeriesModel(opt, lineStyle={}, itemStyle={}) {
};
}
/**
* 创建一个区域
*/
export function createRectArea(opt, style={}) {
return {
type: 'rect',
subType: 'Area',
areaNo: opt.model.areaNo,
position: opt.position,
point1: opt.point1,
point2: opt.point2,
model: opt.model,
shape: {
x: 0,
y: 0,
width: opt.width,
height: opt.height
},
style: {
fill: 'rgb(255,0,0, 0.3)',
stroke: 'rgb(255, 0, 0, 0.8)',
text: opt.model.text,
textFill: 'rgb(0, 0, 0)',
fontSize: 18,
fontWeight: 500,
textVerticalAlign: 'middle',
textAlign: 'center',
...style
},
z: 100
}
}
/** 创建标记横线*/
export function createMarkLineModels(stations, computedYaxis) {
const markLineModel = {};
if (stations && stations.length) {
markLineModel.type = 'line';
markLineModel.name = 'markline';
markLineModel.name = 'markline';
markLineModel.silent = true;
markLineModel.animation = false;
markLineModel.markLine = {};
markLineModel.markLine.silent = true;
markLineModel.markLine.data = [];
@ -76,120 +110,8 @@ export function createMarkLineModels(stations, computedYaxis) {
return markLineModel;
}
/** 创建不会重复颜色的内部对象*/
export const hexColor = {
colorIndex: 0,
difValue: 0.25, // 一般为0.25
oddColor: null,
eveColor: null,
oldColor: null,
newColor: null,
colorList: [
'#000000', '#0000FF', '#8A2BE2', '#A52A2A', '#DEB887', '#5F9EA0', '#7FFF00', '#FF7F50', '#6495ED', '#DC143C',
'#00FFFF', '#008B8B', '#B8860B', '#BDB76B', '#8B008B', '#FF8C00', '#9932CC', '#8FBC8F', '#FF1493', '#00BFFF',
'#FF00FF', '#FFD700', '#FF69B4', '#FF4500', '#DB7093', '#4169E1', '#6A5ACD', '#00FF7F', '#EE82EE', '#40E0D0'
],
colors: [
'#B9C671', '#6C9040', '#79C671', '#71A5C6', '#C6A071', '#71C689', '#'
],
randomHsl: function () {
const h = Math.random();
const s = Math.random();
const l = Math.random();
return [h, s, l];
},
hslToRgb: function (h, s, l) {
let r, g, b;
if (s === 0) {
r = g = b = l; // achromatic
} else {
const hue2rgb = function hue2rgb(p, q, t) {
if (t < 0) t += 1;
if (t > 1) t -= 1;
if (t < 1 / 6) return p + (q - p) * 6 * t;
if (t < 1 / 2) return q;
if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
return p;
};
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
const p = 2 * l - q;
r = hue2rgb(p, q, h + 1 / 3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1 / 3);
}
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
},
rgbToHsl: function (r, g, b) {
// eslint-disable-next-line no-sequences
r /= 255, g /= 255, b /= 255;
const max = Math.max(r, g, b); const min = Math.min(r, g, b);
let h; let s; const l = (max + min) / 2;
if (max === min) {
h = s = 0; // achromatic
} else {
const d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch (max) {
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
case g: h = (b - r) / d + 2; break;
case b: h = (r - g) / d + 4; break;
}
h /= 6;
}
return [h, s, l];
},
// 固定颜色
colorFixed() {
var color = this.colorList[this.colorIndex++ % this.colorList.length];
return color;
},
// 随机颜色
colorRandom() {
return '#' + (Math.random() * 0xffffff << 0).toString(16);
},
// 生成和前一个不同的随机颜色
colorContrast() {
this.newColor = this.randomHsl(); // 获取随机的hsl,并且给一个默认的hsl
this.newColor[1] = 0.7 + this.newColor[1] * 0.2; // [0.7 - 0.9] 排除过灰颜色
this.newColor[2] = 0.4 + this.newColor[2] * 0.2; // [0.4 - 0.8] 排除过亮过暗色
/** 如果oldColor不为空时要根据车次号保证两次生成的颜色差值为difValue*/
this.oldColor = Number(this.colorIndex) % 2 ? this.oddColor : this.eveColor;
if (this.oldColor) {
/** 保证本次的颜色和上次的不一致*/
for (let i = 0; i < this.newColor.length && i < this.oldColor.length; i++) {
if (i === 0 && Math.abs(this.newColor[i].toFixed(2) - this.oldColor[i].toFixed(2)) < this.difValue) {
this.colorRandom();
break;
}
}
}
/** 保存之前的颜色状态*/
if (Number(this.colorIndex) % 2) {
this.oddColor = this.newColor;
} else {
this.eveColor = this.newColor;
}
this.colorIndex += 1;
return `#${this.hslToRgb(...this.newColor).map(e => { return Number(e).toString(16); }).join('')}`;
},
// 渐进颜色
colorProgressiveColor() {
},
toCreate: function () {
return this.colorRandom();
}
};
/** 对list数据进行排序, 相同元素保持原有顺序*/
export function sortListByCallBack(list, callback) {
export function sortListByCb(list, callback) {
list.map((elem, index) => { elem[`oldIndex`] = index; });
list.sort((a, b) => {
return callback(a, b) || a.oldIndex - b.oldIndex;

View File

@ -14,7 +14,7 @@
</template>
<script>
import { DeviceMenu } from '@/scripts/ConstDic';
import { MenuEnum } from '../utils.js';
export default {
props: {
@ -29,6 +29,10 @@ export default {
default() {
return []
}
},
config: {
type: Object,
required: true
}
},
data() {
@ -38,8 +42,8 @@ export default {
this.stations[this.selected.dataIndex].kmRange -
this.stations[this.selected.dataIndex+1].kmRange
)
const min = Math.floor(offset / 19.4);
const max = Math.floor(offset / 8.3);
const min = Math.floor(offset / (this.config.maxSpeed * 1000/3600));
const max = Math.floor(offset / 1);
if (value < min) {
callback(new Error('Below minimum run time.'));
@ -69,7 +73,7 @@ export default {
},
watch: {
'$store.state.menuOperation.menuCount': function (val) {
if (this.$store.getters['menuOperation/checkDialogIsOpen'](DeviceMenu.planJustRunning)) {
if (this.$store.getters['menuOperation/checkDialogIsOpen'](MenuEnum.planJustRunning)) {
this.doShow(this.$store.state.menuOperation.menuPosition);
} else {
this.doClose();

View File

@ -14,7 +14,7 @@
</template>
<script>
import { DeviceMenu } from '@/scripts/ConstDic';
import { MenuEnum } from '../utils.js';
export default {
props: {
@ -29,12 +29,16 @@ export default {
default() {
return []
}
},
config: {
type: Object,
required: true
}
},
data() {
var validator = (rule, value, callback) => {
if (value > 0 && value <= 15) {
callback(new Error('Stop time cannot be within 0-15 seconds.'));
if (value > 0 && value <= this.config.minStopTime) {
callback(new Error(`Stop time cannot be within 0-${this.config.minStopTime} seconds.`));
} else {
callback()
}
@ -59,7 +63,7 @@ export default {
},
watch: {
'$store.state.menuOperation.menuCount': function (val) {
if (this.$store.getters['menuOperation/checkDialogIsOpen'](DeviceMenu.planJustDeparture)) {
if (this.$store.getters['menuOperation/checkDialogIsOpen'](MenuEnum.planJustStop)) {
this.doShow(this.$store.state.menuOperation.menuPosition);
} else {
this.doClose();

View File

@ -0,0 +1,158 @@
<template>
<el-dialog v-dialogDrag append-to-body title="Modification of train diagram parameters" :visible.sync="dialogShow" width="30%" :close-on-click-modal="false" :before-close="doClose">
<el-form ref="form" label-width="160px" :model="formModel" :rules="rules">
<el-form-item label="Start station" prop="startStationCode">
<el-select v-model="formModel.startStationCode" placeholder="请选择">
<el-option
v-for="(el,i) in stations"
:key="i"
:label="el.name"
:value="el.code">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="End station" prop="endStationCode">
<el-select v-model="formModel.endStationCode" placeholder="请选择">
<el-option
v-for="(el,i) in stations"
:key="i"
:label="el.name"
:value="el.code">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="Start time" prop="startTime">
<el-time-picker value-format="HH:mm:ss" v-model="formModel.startTime" />
</el-form-item>
<el-form-item label="End time" prop="endTime">
<el-time-picker value-format="HH:mm:ss" v-model="formModel.endTime" />
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogShow = false">{{ $t('map.cancel') }}</el-button>
<el-button type="primary" @click="doConfirm">{{ $t('map.confirm') }}</el-button>
</span>
</el-dialog>
</template>
<script>
import { MenuEnum } from '../utils.js';
import { getRpConfig } from '@/api/rpTools';
import { toTimeStamp } from '@/utils/date';
export default {
props: {
stations: {
type: Array,
required: true
},
target: {
type: Object,
default() {
return null
}
}
},
data() {
var startTimeValidator = (rule, value, callback) => {
const startTime = toTimeStamp(value);
const endTime = toTimeStamp(this.formModel.endTime);
if (startTime >= endTime) {
callback(new Error('The start time is greater than the end time.'));
} else if (Math.abs(startTime - endTime) < 10*60) {
callback(new Error('The time interval shall not be less than 10 min.'));
} else {
callback()
}
}
var endTimeValidator = (rule, value, callback) => {
const startTime = toTimeStamp(this.formModel.startTime);
const endTime = toTimeStamp(value);
if (endTime <= startTime) {
callback(new Error('The end time is less than the start time.'));
} else if (Math.abs(startTime - endTime) < 10*60) {
callback(new Error('The time interval shall not be less than 10 min.'));
} else {
callback()
}
}
return {
dialogShow: false,
formModel: {
areaNo: '',
startStationCode: '',
endStationCode: '',
startTime: 0,
endTime: 0
},
rules: {
startStationCode: [
{
required: true, message: 'Please select the farther station.', trigger: 'blur'
},
],
endStationCode: [
{
required: true, message: 'Please select the closer station.', trigger: 'blur'
},
],
startTime: [
{
required: true, message: 'Please select the start time.', trigger: 'blur'
},
{
validator: startTimeValidator, trigger: 'blur'
}
],
endTime: [
{
required: true, message: 'Please select the end time.', trigger: 'blur'
},
{
validator: endTimeValidator, trigger: 'blur'
}
]
}
};
},
watch: {
'$store.state.menuOperation.menuCount': function (val) {
if (this.$store.getters['menuOperation/checkDialogIsOpen'](MenuEnum.planModifyArea)) {
this.doShow(this.$store.state.menuOperation.menuPosition);
} else {
this.doClose();
}
}
},
methods: {
doShow() {
if (this.target &&
this.target.model) {
const model = this.target.model;
this.formModel = {
areaNo: model.areaNo,
startStationCode: model.fartherStationCode,
endStationCode: model.closerStationCode,
startTime: model.startTime,
endTime: model.endTime
}
}
this.dialogShow = true;
},
doClose() {
this.dialogShow = false;
},
doConfirm() {
this.$refs.form.validate((valid) => {
if(valid) {
this.$emit('modifyArea', this.formModel);
this.doClose();
}
});
}
}
};
</script>

View File

@ -0,0 +1,127 @@
<template>
<el-dialog v-dialogDrag append-to-body title="Modification of train diagram parameters" :visible.sync="dialogShow" width="30%" :close-on-click-modal="false" :before-close="doClose">
<el-form ref="form" label-width="160px" :model="formModel" :rules="rules">
<el-form-item label="Average speed" prop="averageSpeed">
<el-input-number v-model="formModel.averageSpeed" controls-position="right" :min="20" :max="60" />
<span style="padding-left: 10px">km/h</span>
</el-form-item>
<el-form-item label="Maximum speed" prop="maxSpeed">
<el-input-number v-model="formModel.maxSpeed" controls-position="right" :min="50" :max="80" />
<span style="padding-left: 10px">km/h</span>
</el-form-item>
<el-form-item label="Default stop time" prop="stopTime">
<el-input-number v-model="formModel.stopTime" controls-position="right" :min="10" :max="120" />
<span style="padding-left: 10px">s</span>
</el-form-item>
<el-form-item label="Minimum stop time" prop="minStopTime">
<el-input-number v-model="formModel.minStopTime" controls-position="right" :min="10" :max="30" />
<span style="padding-left: 10px">s</span>
</el-form-item>
<el-form-item label="Minimum interval time" prop="minIntervalTime">
<el-input-number v-model="formModel.minIntervalTime" controls-position="right" :min="30" :max="360" />
<span style="padding-left: 10px">s</span>
</el-form-item>
<el-form-item label="Turn back time" prop="turnBackTime">
<el-input-number v-model="formModel.turnBackTime" controls-position="right" :min="60" :max="180" />
<span style="padding-left: 10px">s</span>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogShow = false">{{ $t('map.cancel') }}</el-button>
<el-button type="primary" @click="doConfirm">{{ $t('map.confirm') }}</el-button>
</span>
</el-dialog>
</template>
<script>
import { MenuEnum } from '../utils.js';
export default {
props: {
config: {
type: Object,
required: true
}
},
data() {
return {
dialogShow: false,
formModel: {
averageSpeed: 40,
maxSpeed: 70,
stopTime: 30,
minStopTime: 10,
minIntervalTime: 180,
turnBackTime: 90
},
rules: {
averageSpeed: [
{
type: 'number', min: 20, max: 60, message: 'Please select the stop time.', trigger: 'blur'
}
],
maxSpeed: [
{
type: 'number', min: 50, max: 80, message: 'Please select the stop time.', trigger: 'blur'
}
],
stopTime: [
{
type: 'number', min: 10, max: 120, message: 'Please select the stop time.', trigger: 'blur'
}
],
minStopTime: [
{
type: 'number', min: 10, max: 30, message: 'Please select the stop time.', trigger: 'blur'
}
],
minIntervalTime: [
{
type: 'number', min: 30, max: 360, message: 'Please select the stop time.', trigger: 'blur'
}
],
turnBackTime: [
{
type: 'number', min: 60, max: 180, message: 'Please select the stop time.', trigger: 'blur'
}
]
}
};
},
watch: {
selected: function(val) {
},
'$store.state.menuOperation.menuCount': function (val) {
if (this.$store.getters['menuOperation/checkDialogIsOpen'](MenuEnum.planSetParams)) {
this.doShow(this.$store.state.menuOperation.menuPosition);
} else {
this.doClose();
}
}
},
methods: {
doShow() {
this.formModel = {
averageSpeed: this.config.averageSpeed,
maxSpeed: this.config.maxSpeed,
stopTime: this.config.stopTime,
minStopTime: this.config.minStopTime,
minIntervalTime: this.config.minIntervalTime,
turnBackTime: this.config.turnBackTime
}
this.dialogShow = true;
},
doClose() {
this.dialogShow = false;
},
doConfirm() {
this.$refs.form.validate((valid) => {
if(valid) {
this.$emit('setParams', this.formModel.time);
this.doClose();
}
});
}
}
};
</script>

View File

@ -0,0 +1,429 @@
<template>
<div class="monitor">
<schedule
ref="schedule"
:planUtil="planUtil"
:title="title"
:height="height"
:width="width"
:model="model"
@tag="onTarget"
@select="onSelected"
@clear="onClear"
@create="onCreate"
@translate="onTranslate"
>
<template slot="header">
<div class="header">
<div class="menus-left">
<el-button type="primary" @click="doNewPlan">New</el-button>
<el-button type="primary" @click="onDialog(MenuEnum.planSetParams)">Set Param</el-button>
</div>
<div class="menus-right">
<span style="font-size:22px;padding:0 17px;">Plan</span>
<menus
:model="model"
:selected="selected"
:target="target"
@remove="onRemove"
@clear="onClear"
/>
</div>
</div>
</template>
</schedule>
<plan-just-running :config="config" :selected="selected" :stations="stations" @justRunning="doJustRunning" />
<plan-just-stop :config="config" :selected="selected" :stations="stations" @justStop="doJustStop"/>
<plan-set-params :config="config" @setParams="doSetPlanParams" />
<plan-modify-area :target="target" :stations="stations" @modifyArea="doModifyArea" />
</div>
</template>
<script>
import Schedule from './schedule.vue';
import PlanJustRunning from './dialog/planJustRunning.vue';
import PlanJustStop from './dialog/planJustStop.vue';
import PlanSetParams from './dialog/planSetParams.vue';
import PlanModifyArea from './dialog/planModifyArea.vue';
import Menus from './menus.vue';
import { MenuEnum } from './utils.js';
import { timeFormat } from '@/utils/date';
import { mapGetters } from 'vuex';
import { getStationList } from '@/api/runplan';
import {
getRpTools, clearRpPlan, addRpTrip, delRpTrip,
justTripNoRunning, justTripNoStop,
translateTrip,
getRpConfig, modifyRpConfig,
createRpArea, modifyRpArea, delRpArea
} from '@/api/rpTools';
export default {
components: {
Schedule,
PlanJustRunning,
PlanJustStop,
PlanSetParams,
PlanModifyArea,
Menus
},
data() {
return {
title: 'XXX',
canvasId: 'canvas-plan',
stations: [],
planData: [],
selected: null,
target: null,
model: {
choice: 'Plan',
action: '',
},
config: {
}
};
},
computed: {
width() {
return this.$store.state.app.width - 2;
},
height() {
return this.$store.state.app.height - 72;
},
planId() {
return this.$route.query.planId;
},
mapId() {
return 9;
},
lineCode() {
return '00';
},
MenuEnum() {
return MenuEnum;
}
},
watch: {
width() {
this.setPosition();
},
height() {
this.setPosition();
},
},
created() {
this.planUtil = this.$theme.loadPlanConvert(this.lineCode);
},
mounted() {
this.setPosition();
this.loadInitData();
},
methods: {
setPosition() {
this.$nextTick(() => {
this.$store.dispatch('rpTools/resize', { width: this.width, height: this.height });
});
},
loadInitData() {
getStationList(this.mapId).then(resp => {
const stations = this.stations = resp.data.filter(el => {
return ['车辆段', '停车场'].findIndex(it => { return el.name.includes(it) }) < 0;
});
this.$store.commit('rpTools/setStations', stations);
this.$refs.schedule.loadChartPage(stations);
getRpTools().then(rest => {
const planData = rest.data;
this.$store.commit('rpTools/setPlanData', planData);
this.$refs.schedule.loadChartData(planData);
getRpConfig().then(resm => {
const data = resm.data;
this.config = {
averageSpeed: data.averageSpeed,
maxSpeed: data.maxSpeed,
stopTime: data.stopTime,
minStopTime: data.minStopTime,
minIntervalTime: data.minIntervalTime,
turnBackTime: data.turnBackTime
}
}).catch(error => {
this.$message.info(error.message)
})
});
}).catch(error => {
this.$messageBox(error.message);
})
},
onClear() {
this.model.action = '';
this.selected = null;
this.target = null;
this.$refs.schedule.setLineReset();
this.$refs.schedule.clearGraphic();
},
onDialog(menu) {
this.$store.dispatch('menuOperation/setPopMenu', { position: {x: 0, y: 0}, menu });
},
onTarget(target) {
this.target = target;
},
onSelected(selected) {
this.selected = selected;
},
onCreate(data) {
switch(this.model.choice) {
case 'Plan':
this.doCreateTrip(data);
break;
case 'Construction':
this.doCreateArea(data);
break;
}
},
onTranslate(data) {
switch(this.model.choice) {
case 'Plan':
this.doTranslateTrip(data);
break;
}
},
onRemove(){
this.$confirm('此操作将永久删除该数据, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
switch(this.model.choice) {
case 'Plan':
this.doRemoveTrip();
break;
case 'Construction':
this.doRemoveArea();
break;
}
}).catch(() => {
this.$message({ type: 'info', message: 'Deletion cancelled.' });
});
},
doNewPlan() {
clearRpPlan().then(resp => {
getRpTools().then(rest => {
const planData = rest.data;
this.$store.commit('rpTools/setPlanData', planData);
this.$refs.schedule.loadChartData(planData);
}).catch(() => {
this.$messageBox(this.$t('error.obtainOperationGraphFailed'));
this.$store.dispatch('rpTools/setStations', []);
});
}).catch(error => {
this.$message.info(error.message);
})
},
doSetPlanParams(data) {
modifyRpConfig(data).then(resp => {
this.config = data;
this.$message.success('Parameters of plan were modified successfully.');
}).catch(error => {
this.$message.info(error.message);
})
},
doModifyArea(data) {
const startTime = data.startTime;
const endTime = data.endTime;
const startCodeIndex = this.stations.findIndex(el => { return el.code == data.startStationCode; })
const endCodeIndex = this.stations.findIndex(el => { return el.code == data.endStationCode; })
const model = {
fartherStationCode: startCodeIndex < endCodeIndex? data.endStationCode: data.startStationCode,
closerStationCode: startCodeIndex < endCodeIndex? data.startStationCode: data.endStationCode,
startTime: data.startTime,
endTime: data.endTime
}
modifyRpArea(data.areaNo, model).then(resp => {
getRpTools().then(rest => {
const planData = rest.data;
this.$store.commit('rpTools/setPlanData', planData);
this.$refs.schedule.loadChartData(planData);
this.$message.success('Construction area modified successfully.');
}).catch(() => {
this.$messageBox('Failed to load the plan.');
});
}).catch(error => {
this.$message.info(error.message);
})
},
doJustRunning(time) {
if (this.selected) {
const model = {
seconds: time,
stationCode: this.selected.stationCode
}
justTripNoRunning(this.selected.tripNo, model).then(resp => {
getRpTools().then(rest => {
const planData = rest.data;
this.$store.commit('rpTools/setPlanData', planData);
this.$refs.schedule.loadChartData(planData);
}).catch(() => {
this.$messageBox('Failed to load the plan.');
});
}).catch(error => {
this.$message.info(error.message);
})
}
},
doJustStop(time){
if (this.selected) {
const model = {
seconds: time,
stationCode: this.selected.stationCode
}
justTripNoStop(this.selected.tripNo, model).then(resp => {
getRpTools().then(rest => {
const planData = rest.data;
this.$store.commit('rpTools/setPlanData', planData);
this.$refs.schedule.loadChartData(planData);
}).catch(() => {
this.$messageBox('Failed to load the plan.');
});
}).catch(error => {
this.$message.info(error.message);
})
}
},
doCreateTrip(data) {
const model = {
endStationCode: data.endStationCode,
startStationCode: data.startStationCode,
startTime: timeFormat(data.startTime),
endTime: timeFormat(data.endTime)
}
addRpTrip(model).then(resp => {
getRpTools().then(rest => {
const planData = rest.data;
this.$store.commit('rpTools/setPlanData', planData);
this.$refs.schedule.loadChartData(planData);
}).catch(() => {
this.$messageBox('Failed to load the plan.');
});
}).catch(error => {
this.$message.info(error.message);
this.$refs.schedule.clearGraphic(['mark']);
})
},
doCreateArea(data) {
const startTime = data.startTime;
const endTime = data.endTime;
const startCodeIndex = this.stations.findIndex(el => { return el.code == data.startStationCode; })
const endCodeIndex = this.stations.findIndex(el => { return el.code == data.endStationCode; })
if (Math.abs(endTime - startTime) < 10*60) {
this.$refs.schedule.clearGraphic(['mark']);
this.$message.info('The time interval shall not be less than 10 min.')
return;
}
const model = {
fartherStationCode: startCodeIndex < endCodeIndex? data.endStationCode: data.startStationCode,
closerStationCode: startCodeIndex < endCodeIndex? data.startStationCode: data.endStationCode,
startTime: endTime < startTime? timeFormat(data.endTime): timeFormat(data.startTime),
endTime: endTime < startTime? timeFormat(data.startTime): timeFormat(data.endTime)
}
createRpArea(model).then(resp => {
getRpTools().then(rest => {
const planData = rest.data;
this.$store.commit('rpTools/setPlanData', planData);
this.$refs.schedule.loadChartData(planData);
}).catch(() => {
this.$messageBox('Failed to load the plan.');
});
}).catch(error => {
this.$message.info(error.message);
this.$refs.schedule.clearGraphic(['mark']);
})
},
doTranslateTrip() {
if (this.selected) {
const model = {
seconds : this.selected.time
}
translateTripNo(this.selected.tripNo, model).then(resp => {
getRpTools().then(rest => {
const planData = rest.data;
this.$store.commit('rpTools/setPlanData', planData);
this.$refs.schedule.loadChartData(planData);
}).catch(() => {
this.$messageBox('Failed to load the plan.');
});
}).catch(error => {
this.$message.info(error.message);
});
}
},
doRemoveTrip() {
if (this.selected) {
delRpTrip(this.selected.tripNo).then(resp => {
getRpTools().then(rest => {
const planData = rest.data;
this.$store.commit('rpTools/setPlanData', planData);
this.$refs.schedule.loadChartData(planData);
this.onClear();
}).catch(() => {
this.$messageBox('Failed to load the plan.');
});
}).catch(error => {
this.$message.info(error.message);
})
}
},
doRemoveArea() {
if (this.target) {
delRpArea(this.target.areaNo).then(resp => {
getRpTools().then(rest => {
const planData = rest.data;
this.$store.commit('rpTools/setPlanData', planData);
this.$refs.schedule.loadChartData(planData);
this.onClear();
}).catch(() => {
this.$messageBox('Failed to load the plan.');
});
}).catch(error => {
this.$message.info(error.message);
})
}
}
}
};
</script>
<style scoped rel="stylesheet/scss" lang="scss">
@import "src/styles/mixin.scss";
.monitor {
z-index: 0;
width: 100%;
height: 100%;
position: relative;
.header {
margin: 0 80px;
display: flex;
justify-content: space-between;
align-items: center;
.menus-left {
display: flex;
align-items: center;
}
.menus-right {
display: flex;
align-items: center;
}
}
}
</style>

View File

@ -1,6 +1,6 @@
<template>
<div class="menus">
<el-select v-model="model.choice" placeholder="请选择功能类型" style="margin-right:20px">
<el-select v-model="model.choice" placeholder="请选择功能类型" style="margin-right:20px" @change="$emit('clear')">
<el-option v-for="(el,i) in options" :key="i" :label="el.label" :value="el.value" />
</el-select>
<div v-if="option">
@ -30,29 +30,34 @@ export default {
props: {
model: {
type: Object,
default() {
return {
choice: '',
action: ''
}
}
required: true
},
selected: {
type: Object,
default() {
return null
}
},
target: {
type: Object,
default() {
return null
}
}
},
data() {
return {
}
},
computed: {
options() {
return [
{
label: "绘制计划",
label: "Planning",
value: "Plan"
},
{
label: "施工区域",
label: "Construction area",
value: "Construction"
},
]
@ -77,7 +82,7 @@ export default {
buttonList: [
{
icon: 'el-icon-delete',
type: (el, i) => { return this.selected?'danger':'info' },
type: (el, i) => { return this.selected? 'danger':'info' },
handle: e => { this.$emit('remove') }
}
]
@ -88,10 +93,6 @@ export default {
label: 'Add',
value: 'Add',
},
{
label: 'Translate',
value: 'Translate'
},
{
label: 'Edit',
value: 'Edit'
@ -100,7 +101,7 @@ export default {
buttonList: [
{
icon: 'el-icon-delete',
type: (el, i) => { return this.selected?'danger':'info' },
type: (el, i) => { return this.target?'danger':'info' },
handle: e => { this.$emit('remove') }
}
]

View File

@ -0,0 +1,369 @@
import echarts from 'echarts';
import * as utils from './utils'
import { MenuEnum } from './utils';
export default {
data() {
return {
callRegister: [],
markList: [],
buildModel: {
endStationCode: '',
startStationCode: '',
startTime: 0,
endTime: 0
},
selected: null,
target: null,
dragging: false
}
},
watch: {
myChart: function() {
this.listenersBind();
}
},
beforeDestroy() {
this.listenersOff();
},
methods: {
pixelExecCb(e, cb) {
const event = e.componentType ? e.event: e;
const pointInPixel = [event.offsetX, event.offsetY]
if (this.myChart.containPixel('grid', pointInPixel) && this.planUtil) {
const pointInGrid = this.myChart.convertFromPixel({seriesIndex:0},pointInPixel);
const xIndex = pointInGrid[0];
const yIndex = pointInGrid[1];
const option = this.myChart.getOption();
const minY = option.yAxis[0].min;
const xVal = option.xAxis[0].data[xIndex];
const yObj = this.planUtil.getStationByCoordinate(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) {
const fixedList = ['Area'];
const option = this.myChart.getOption();
const elements = option.graphic[0].elements
const graphic = echarts.util.map(elements, (el) => {
if (fixedList.includes(el.subType)) {
const position = this.myChart.convertToPixel('grid', el.point1);
const position2 = this.myChart.convertToPixel('grid', el.point2);
const width = Math.abs(position[0] - position2[0]);
const height = Math.abs(position[1] - position2[1])
return {
position,
shape: { width, height }
}
} else {
return {
position: this.myChart.convertToPixel('grid', el.point)
};
}
})
this.myChart.setOption({graphic});
},
onZrMouseDown(e) {
if (e.target && ['Area'].includes(e.target.subType)) {
this.target = e.target;
this.$emit('tag', this.target);
if (this.model.choice == 'Construction') {
if (this.model.action == 'Edit') {
this.pixelExecCb(e, this.handlePopDialog);
}
}
}
if (this.model.choice == 'Plan') {
if (this.model.action == 'Add') {
this.pixelExecCb(e, this.onCreateMark);
}
} else if (this.model.choice == 'Construction') {
if (this.model.action == 'Add') {
this.pixelExecCb(e, this.onCreateArea);
}
}
if (!e.target) {
this.setLineReset();
this.$emit('tag', null);
this.$emit('select', null);
}
},
onZrMouseUp(e) {
if (['Plan', 'Construction'].includes(this.model.choice)) {
if(this.model.action == 'Translate' && this.dragging) {
this.dragging = false;
this.pixelExecCb(e, this.onTranslate)
}
}
},
onMouseDown(e) {
if (this.model.choice == 'Plan') {
if (this.model.action == 'Edit') {
this.pixelExecCb(e, this.handlePopDialog);
}
}
},
onMouseOver(e) {
this.pixelExecCb(e, ({e, pointInPixel}) => {
if (this.model.choice == 'Plan') {
this.handleSelectLine({e});
if (this.model.action == 'Translate') {
this.onCreateDrag({e, pointInPixel})
}
}
});
if (this.model.choice == 'Plan') {
if (this.model.action == 'Translate') {
setTimeout(_ => { this.onShapeMouseOver(e); }, 200);
}
}
},
onMouseOut(e) {
this.pixelExecCb(e, ({e, pointInPixel}) => {
if (this.model.choice == 'Plan') {
this.handleSelectLine({e});
if(this.model.action == 'Translate') {
this.onCreateDrag({e, pointInPixel})
}
}
});
if (this.model.choice == 'Plan') {
if (this.model.action == 'Translate') {
this.onShapeMouseOver(e);
}
}
},
onMouseUP(e) {
},
onShapeDragging(e) {
if (this.selected) {
this.dragging = true;
if (this.model.choice == 'Plan') {
if (this.model.action == 'Translate') {
this.pixelExecCb(e, this.handleSeriesDragging);
}
} else if (this.model.choice == 'Construction') {
if (this.model.action == 'Translate') {
this.pixelExecCb(e, this.handleAreaDragging);
}
}
}
},
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',
});
}
},
onCreateDrag({e, pointInPixel}) {
if (this.selected) {
const option = this.myChart.getOption();
const filters = option.graphic[0].elements.filter(el => { return el.subType != 'drag'});
filters.push(utils.buildDragDataObj(pointInPixel, this.myChart.convertFromPixel('grid', pointInPixel), this))
option.graphic[0].elements = filters;
this.myChart.setOption(option, {notMerge: true});
this.myChart.dispatchAction({
type: 'showTip',
seriesIndex: this.selected.seriesIndex,
dataIndex: this.selected.dataIndex
});
}
},
onCreateMark({e, pointInPixel, yObj, xVal}) {
const option = this.myChart.getOption();
const graphic = option.graphic;
const elements = graphic[0].elements;
elements.push(utils.buildMarkPointObj(pointInPixel, this.myChart.convertFromPixel('grid', pointInPixel), this))
this.myChart.setOption(option, {notMerge: true});
const markList = this.markList = elements.filter(el => { return el.subType == 'mark'});
const elemList = elements.filter(el => { return el.subType != 'mark'});
if (markList.length == 1) {
this.buildModel.startStationCode = yObj.code;
this.buildModel.startTime = xVal;
} else if (markList.length >= 2) {
this.buildModel.endStationCode = yObj.code;
this.buildModel.endTime = xVal;
option.graphic[0].elements = elemList;
this.$emit('create', this.buildModel);
}
},
onCreateArea({e, pointInPixel, yObj, xVal}) {
if (!e.target) {
const option = this.myChart.getOption();
const graphic = option.graphic;
const elements = graphic[0].elements;
elements.push(utils.buildMarkPointObj(pointInPixel, this.myChart.convertFromPixel('grid', pointInPixel), this))
this.myChart.setOption(option, {notMerge: true});
const markList = this.markList = elements.filter(el => { return el.subType == 'mark'});
const elemList = elements.filter(el => { return el.subType != 'mark'});
if (markList.length == 1) {
this.buildModel.startStationCode = yObj.code;
this.buildModel.startTime = xVal;
} else if (markList.length >= 2) {
this.buildModel.endStationCode = yObj.code;
this.buildModel.endTime = xVal;
option.graphic[0].elements = elemList;
this.$emit('create', this.buildModel);
}
}
},
handlePopDialog({e, pointInPixel}) {
const point = {
x: pointInPixel[0],
y: pointInPixel[1]
}
if (e.componentType == "series" &&
e.componentSubType == "line" &&
e.seriesName.includes('plan-')) {
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];
const value = e.value;
this.selected = {
dataIndex: e.dataIndex,
seriesIndex: e.seriesIndex,
seriesName: e.seriesName,
seriesId: e.seriesId,
depTime: e.dataIndex < length - 1? nxt[0] - value[0]: 0,
runTime: e.dataIndex < length - 1? nxt[0] - value[0]: 0,
...e.value[2],
_x: value[0],
dx: 0,
time: 0,
}
this.$emit('select', this.selected);
if (e.dataIndex < length - 1 && value[1] == nxt[1]) {
this.$store.dispatch('menuOperation/setPopMenu', { position: point, menu: MenuEnum.planJustStop });
} else if (e.dataIndex == 0 || e.dataIndex > 0 && value[1] == pre[1]) {
this.$store.dispatch('menuOperation/setPopMenu', { position: point, menu: MenuEnum.planJustRunning });
}
} else if (e.target && e.target.subType == 'Area') {
this.$store.dispatch('menuOperation/setPopMenu', { position: point, menu: MenuEnum.planModifyArea });
}
},
handleSelectLine({e}) {
if (e.componentType == "series" &&
e.componentSubType == "line" &&
e.seriesName.includes('plan-')) {
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.seriesId,
depTime: e.dataIndex < length - 1? nxt[0] - value[0]: 0,
runTime: e.dataIndex < length - 1? nxt[0] - value[0]: 0,
...e.value[2],
_x: value[0],
dx: 0,
time: 0
}
this.$emit('select', this.selected);
this.setLineLight();
}
},
handleSeriesDragging({e, xVal}) {
if (this.selected) {
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]
model.data.forEach(el => {
el[0] += this.selected.dx;
});
model.markPoint.data.forEach(el => {
el.coord[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});
}
},
handleAreaDragging({e, xVal}) {
},
onTranslate({e}) {
this.$emit('translate');
}
}
}

View File

@ -0,0 +1,382 @@
<template>
<div id="PlanSchedule">
<el-card class="box-card">
<div slot="header" >
<slot name="header" />
</div>
<div :id="canvasId" />
</el-card>
</div>
</template>
<script>
import echarts from 'echarts';
import Monitor from './monitor.js';
import { timeFormat } from '@/utils/date';
export default {
mixins: [Monitor],
props: {
planUtil: {
type: Object,
required: true
},
model: {
type: Object,
required: true
},
width: {
type: Number,
required: true
},
height: {
type: Number,
required: true
},
title: {
type: String,
default: ''
},
canvasId: {
type: String,
default: 'plan-tool'
}
},
data() {
return {
myChart: null,
stations: [],
planData: [],
kmRangeCoordinateMap:{}
};
},
computed: {
option() {
return {
title: {
text: '',
left: 'center',
top: '10px'
},
grid: {
top: '60px',
left: '160px',
right: '100px',
bottom: '80px',
containLabel: true,
backgroundColor: 'floralwhite'
},
toolbox: {
},
tooltip: {
trigger: 'item',
axisPointer: {
type: 'cross',
snap: true,
axis: 'x'
},
formatter: this.axisTooltip,
borderWidth: 1,
position: function (pt) {
const data = pt[0] + 10;
return [data, '20%'];
}
},
xAxis: [
{
type: 'category',
boundaryGap: false,
data: [],
axisLine: {
onZero: false,
lineStyle: {
width: 1
}
},
axisLabel: {
formatter: this.xAxisLableFormat,
textStyle: {
color: '#333'
}
},
axisPointer: {
snap: true,
label: {
formatter: this.xAxisPointFormat,
backgroundColor: 'rgb(255,0,0,0.5)',
color: 'white'
}
}
}
],
yAxis: {
type: 'value',
splitLine: {
show: false
},
axisTick: {
show: false
},
axisLine: {
onZero: false,
lineStyle: {
width: 1
}
},
axisLabel: {
interval: 'auto',
formatter: this.yAxisLableFormat
},
axisPointer: {
xAxisIndex: 'all',
label: {
formatter: this.yAxisPointFormat,
backgroundColor: 'rgb(0,100,0,0.5)',
color: 'white'
}
},
min: 0,
max: 0
},
graphic: [{
id: 'shape',
elements: []
}],
series: [],
dataZoom: [
{
type: 'inside',
zoomOnMouseWheel : true,
moveOnMouseMove : 'ctrl',
},
{
fiterMode: 'filter',
handleSize: '80%',
handleStyle: {
color: '#fff',
shadowBlur: 3,
shadowColor: 'rgba(0, 0, 0, 0.6)',
shadowOffsetX: 2,
shadowOffsetY: 2
},
bottom: '20px'
}
]
}
}
},
watch: {
width() {
this.reSize({width: this.width, height: this.height})
},
height() {
this.reSize({width: this.width, height: this.height})
}
},
mounted() {
this.loadInitChart();
},
beforeDestroy() {
this.destroy();
},
methods: {
xAxisPointFormat(params) {
return timeFormat(params.value);
},
yAxisPointFormat(params) {
return this.planUtil.computedFormatYAxis(this.stations, params);
},
xAxisLableFormat(value, index) {
if (value % 60 === 0) {
return timeFormat(value);
}
},
yAxisLableFormat(value, index) {
return '';
},
axisTooltip(param) {
let data = '';
if (param.data &&
param.data.length) {
const xVal = param.data[0];
const yObj = param.data[1];
const model = param.value[2];
const station = this.stations.find(el => { return el.code == yObj.stationCode })||{ name: '', kmRange: ''};
const list = [
`Service No: ${model.serviceNo}<br>`,
`Trip No: ${model.tripNo}<br>`,
`direction: ${model.direction == 2? 'Up': 'Down'}<br>`,
`Station name: ${station.name}<br>`,
`Kilometer post: ${station.kmRange} m <br>`,
`Arrival Time: ${timeFormat(xVal + this.planUtil.TranslationTime)}<br>`,
`<hr size=1 style="margin: 3px 0">`
];
data += list.join('');
}
return data;
},
loadInitChart() {
return new Promise((resolve, reject) => {
try {
if (this.myChart && this.myChart.isDisposed) {
this.myChart.clear();
}
if (this.$route.query.planName || this.$route.query.prdType === '05') {
this.option.title.text = this.this.title;
}
this.myChart = echarts.init(document.getElementById(this.canvasId));
this.myChart.setOption(this.option, {notMerge: true});
this.reSize({ width: this.width, height: this.height });
resolve(true);
} catch (error) {
reject(error);
}
});
},
loadChartPage(stations) {
try {
if (this.myChart) {
this.myChart.showLoading();
this.stations = stations;
this.kmRangeCoordinateMap = this.planUtil.convertStationsToMap(this.stations);
this.xAxisInit(stations);
this.yAxisInit(stations);
this.myChart.setOption(this.option, {notMerge: true});
this.myChart.hideLoading();
}
} catch (error) {
this.$messageBox(error.message);
}
},
loadChartData(planData) {
try {
const option = this.myChart.getOption();
option.series = [];
option.graphic[0].elements = [];
this.planData = planData;
this.pushModels(option.series, [this.planUtil.initializeYaxis(this.stations)]);
this.pushModels(option.series, this.planUtil.parseDataToSeries(this.myChart, planData, this.stations, this.kmRangeCoordinateMap));
this.pushModels(option.graphic[0].elements, this.planUtil.parseDataToGraph(this.myChart, planData, this.stations, this.kmRangeCoordinateMap));
this.myChart.setOption(option, {notMerge: true});
} catch (error) {
this.$messageBox(error.message);
}
},
xAxisInit(stations) {
const option = this.option;
const startValue = 3600 * 6;
const offsetTime = 3600 / 2;
const list = [];
for (var time = 0 + this.planUtil.TranslationTime; time < 3600 * 24 + this.planUtil.TranslationTime; time++) {
list.push(time);
}
option.xAxis[0].data = list;
if (!option.dataZoom[0].startValue) {
option.dataZoom[0].startValue = option.dataZoom[1].startValue = startValue - offsetTime;
}
if (!option.dataZoom[0].endValue) {
option.dataZoom[0].endValue = option.dataZoom[1].endValue = startValue + offsetTime;
}
},
yAxisInit(stations) {
const option = this.option;
if (Object.keys(this.planUtil).length) {
this.pushModels(option.series, [this.planUtil.initializeYaxis(stations)]);
option.yAxis.min = this.planUtil.computedYaxisMinValue(stations);
option.yAxis.max = this.planUtil.computedYaxisMaxValue(stations);
}
},
reSize({width, height}) {
if (this.myChart) {
this.myChart.resize({ width, height, silent: false });
}
},
destroy() {
if (this.myChart && this.myChart.isDisposed) {
this.myChart.dispose();
this.myChart = null;
}
},
pushModels(series, models) {
if (models && models.length) {
models.forEach(elem => {
if (elem) {
series.push(elem);
}
});
}
return series;
},
popModels(series, models) {
if (models && models.length) {
models.forEach(elem => {
const index = series.indexOf(elem);
if (index >= 0) {
series.split(index, 1);
}
});
}
return series;
},
setLineLight() {
if (this.selected) {
this.myChart.setOption({
series: {
name: this.selected.seriesName,
symbolSize: 6,
showAllSymbol: true,
lineStyle: {
width: 2,
color: '#0000FF'
}
}
});
}
},
setLineReset() {
if (this.selected) {
this.myChart.setOption({
series: {
name: this.selected.seriesName,
symbolSize: 1,
showAllSymbol: true,
lineStyle: {
width: 1,
color: '#000000'
}
}
});
}
},
clearGraphic(labels=['drag', 'mark']) {
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});
}
}
};
</script>
<style scoped rel="stylesheet/scss" lang="scss">
@import "src/styles/mixin.scss";
#PlanSchedule {
z-index: 0;
width: 100%;
height: 100%;
position: relative;
}
</style>

View File

@ -0,0 +1,46 @@
import echarts from 'echarts';
export const MenuEnum = {
planJustRunning: '1000',
planJustStop: '1001',
planSetParams: '1002',
planModifyArea: '1003'
}
export function buildDragDataObj(position, point, that) {
return {
type: 'circle',
subType: 'drag',
position: [...position],
point: [...point],
shape: {
cx: 0,
cy: 0,
r: 10
},
invisible: true,
draggable: 'horizontal',
ondrag: echarts.util.curry(that.onShapeDragging),
onmouseover: echarts.util.curry(that.onShapeMouseOver),
onmouseout: echarts.util.curry(that.onShapeMouseOut),
z: 100
}
}
export function buildMarkPointObj(position, point, that) {
return {
type: 'circle',
subType: 'mark',
z: 100,
position: [...position],
point: [...point],
shape: {
cx: 0,
cy: 0,
r: 10
},
style: {
fill: 'rgba(0,0,0,0.3)'
}
}
}

View File

@ -1,77 +0,0 @@
<template>
<div class="plan-tool">
<schedule
ref="schedule"
:plan-convert="PlanConvert"
:max-height="height"
:max-width="width"
/>
</div>
</template>
<script>
import Schedule from './schedule';
export default {
components: {
Schedule
},
data() {
return {
PlanConvert: {}
};
},
computed: {
width() {
return this.$store.state.app.width - 2;
},
height() {
return this.$store.state.app.height - 72;
}
},
created() {
document.title = '运行图编辑工具'
this.PlanConvert = this.$theme.loadPlanConvert(this.lineCode);
},
methods: {
}
};
</script>
<style>
.plan-tool {
position: absolute;
}
.plan-tool .pop-menu {
background: #F0F0F0;
}
.plan-tool .pop-menu span {
color: #000;
}
.plan-tool .system-close {
cursor: pointer;
height: 25px;
width: 25px;
background: -webkit-linear-gradient(#CD98A0, #C27D6E, #B63022, #C68770);
background: -o-linear-gradient(#CD98A0, #C27D6E, #B63022, #C68770);
background: -moz-linear-gradient(#CD98A0, #C27D6E, #B63022, #C68770);
background: linear-gradient(#CD98A0, #C27D6E, #B63022, #C68770);
border: 1px solid white;
border-radius: 4px;
}
.plan-tool .system-close::before {
position: absolute;
top: 0px;
left: 0px;
font-size: x-large;
}
.planEdit__tool {
overflow: hidden !important;
}
</style>

View File

@ -1,351 +0,0 @@
<template>
<div id="PlanSchedule">
<schedule
:option="option"
:title="title"
:canvasId="canvasId"
@clear="handleClear"
@create="handleCreate"
@translate="handleTranslate"
@edit="handleEdit"
/>
</div>
</template>
<script>
import Schedule from './schedule.vue';
import Monitor from './monitor.js';
import { mapGetters } from 'vuex';
import { timeFormat } from '@/utils/date';
import { getStationList } from '@/api/runplan';
import { getRpTools, clearRpPlan, addRpTrip, delRpTrip, justTripNoRunning, justTripNoStop, translateTripNo} from '@/api/rpTools';
import { getPublishMapInfo } from '@/api/jmap/map';
export default {
components: {
Schedule
},
data() {
return {
title: 'XXX',
canvasId: 'canvas-plan'
};
},
computed: {
width() {
return this.$store.state.app.width - 2;
},
height() {
return this.$store.state.app.height - 72;
},
option() {
return {
title: {
text: '',
left: 'center',
top: '10px'
},
grid: {
top: '60px',
left: '160px',
right: '100px',
bottom: '80px',
containLabel: true,
backgroundColor: 'floralwhite'
},
toolbox: {
},
tooltip: {
trigger: 'item',
axisPointer: {
type: 'cross',
snap: true,
axis: 'x'
},
formatter: this.axisTooltip,
borderWidth: 1,
position: function (pt) {
const data = pt[0] + 10;
return [data, '20%'];
}
},
xAxis: [
{
type: 'category',
boundaryGap: false,
data: [],
axisLine: {
onZero: false,
lineStyle: {
width: 1
}
},
axisLabel: {
formatter: this.xAxisLableFormat,
textStyle: {
color: '#333'
}
},
axisPointer: {
snap: true,
label: {
formatter: this.xAxisPointFormat,
backgroundColor: 'rgb(255,0,0,0.5)',
color: 'white'
}
}
}
],
yAxis: {
type: 'value',
splitLine: {
show: false
},
axisTick: {
show: false
},
axisLine: {
onZero: false,
lineStyle: {
width: 1
}
},
axisLabel: {
interval: 'auto',
formatter: this.yAxisLableFormat
},
axisPointer: {
xAxisIndex: 'all',
label: {
formatter: this.yAxisPointFormat,
backgroundColor: 'rgb(0,100,0,0.5)',
color: 'white'
}
},
min: 0,
max: 0
},
graphic: [{
id: 'shape',
elements: []
}],
series: [],
dataZoom: [
{
type: 'inside',
zoomOnMouseWheel : 'ctrl',
moveOnMouseMove : 'ctrl',
moveOnMouseWheel: 'ctrl'
},
{
type: 'slider',
filterMode: 'empty',
bottom: '20px'
}
]
}
}
},
watch: {
width() {
this.setPosition();
},
height() {
this.setPosition();
}
},
mounted() {
this.setPosition();
},
methods: {
setPosition() {
this.$nextTick(() => {
this.$store.dispatch('rpTools/resize', { width: this.width, height: this.height });
});
},
handleClear() {
this.setLineReset();
this.clearGraphic(['drag', 'mark']);
this.model.action = '';
this.selected = null;
},
handleCreate() {
switch(this.model.choice) {
case 'Plan':
this.doCreateTrip();
break;
case 'Construction':
this.doCreateArea();
break;
}
},
handleEdit() {
},
handleTranslate(data) {
switch(this.model.choice) {
case 'Plan':
this.doTranslateTrip(data);
break;
case 'Construction':
this.doTranslateArea(data);
break;
}
},
handleRemove(){
this.$confirm('此操作将永久删除该数据, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
switch(this.model.choice) {
case 'Plan':
this.doRemoveTrip();
break;
case 'Construction':
this.doRemoveArea();
break;
}
}).catch(() => {
this.$message({ type: 'info', message: '已取消删除' });
});
},
doNewPlan() {
clearRpPlan().then(resp => {
getRpTools().then(rest => {
this.$store.dispatch('rpTools/setPlanData', rest.data).then(() => {
this.loadChartData();
});
}).catch(() => {
this.$messageBox(this.$t('error.obtainOperationGraphFailed'));
});
}).catch(error => {
this.$message(error.message);
})
},
doJustRunning(time) {
if (this.selected) {
const model = {
seconds: time,
stationCode: this.selected.stationCode
}
justTripNoRunning(this.selected.seriesId, model).then(resp => {
getRpTools().then(rest => {
this.$store.dispatch('rpTools/setPlanData', rest.data).then(() => {
this.loadChartData();
});
}).catch(() => {
this.$messageBox(this.$t('error.obtainOperationGraphFailed'));
});
}).catch(error => {
this.$message(error.message);
})
}
},
doJustStop(time){
if (this.selected) {
const model = {
seconds: time,
stationCode: this.selected.stationCode
}
justTripNoStop(this.selected.seriesId, model).then(resp => {
getRpTools().then(rest => {
this.$store.dispatch('rpTools/setPlanData', rest.data).then(() => {
this.loadChartData();
});
}).catch(() => {
this.$messageBox(this.$t('error.obtainOperationGraphFailed'));
});
}).catch(error => {
this.$message(error.message);
})
}
},
doCreateTrip(data) {
if (this.myChart) {
addRpTrip(data).then(resp => {
getRpTools().then(rest => {
this.$store.dispatch('rpTools/setPlanData', rest.data).then(() => {
this.loadChartData();
});
}).catch(() => {
this.$messageBox(this.$t('error.obtainOperationGraphFailed'));
});
}).catch(error => {
this.$message(error.message);
this.clearGraphic(['mark']);
})
}
},
doCreateArea() {
},
doTranslateTrip(data) {
if (this.selected) {
const model = {
seconds : this.selected.time
}
translateTripNo(this.selected.seriesId, model).then(resp => {
getRpTools().then(rest => {
this.$store.dispatch('rpTools/setPlanData', rest.data).then(() => {
this.loadChartData();
});
}).catch(() => {
this.$messageBox(this.$t('error.obtainOperationGraphFailed'));
});
}).catch(error => {
this.$message(error.message);
});
}
},
doTranslateArea(data) {
},
doRemoveTrip() {
if (this.myChart && this.selected) {
delRpTrip(this.selected.seriesId).then(resp => {
getRpTools().then(rest => {
this.$store.dispatch('rpTools/setPlanData', rest.data).then(() => {
this.loadChartData();
this.handleClear();
});
}).catch(() => {
this.$messageBox(this.$t('error.obtainOperationGraphFailed'));
});
}).catch(error => {
this.$message(error.message);
})
}
},
doRemoveArea() {
}
}
};
</script>
<style scoped rel="stylesheet/scss" lang="scss">
@import "src/styles/mixin.scss";
#PlanSchedule {
z-index: 0;
width: 100%;
height: 100%;
position: relative;
.header {
margin: 0 80px;
display: flex;
justify-content: space-between;
align-items: center;
.menus-left {
display: flex;
align-items: center;
}
.menus-right {
display: flex;
align-items: center;
}
}
}
</style>

View File

@ -1,339 +0,0 @@
import echarts from 'echarts';
import * as utils from './utils'
import { DeviceMenu } from '@/scripts/ConstDic';
import { timeFormat } from '@/utils/date';
export default {
data() {
return {
tripModel: {
endStationCode: '',
startStationCode: '',
startTime: ''
},
selected: null,
dragging: false
}
},
watch: {
myChart: function() {
this.listenersBind();
}
},
beforeDestroy() {
this.listenersOff();
},
methods: {
getStationByCoordinate(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.getStationByCoordinate(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) {
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.model.action) {
case 'Add':
this.pixelExecCb(e, this.handleCreateMark);
break;
}
},
onZrMouseUp(e) {
switch(this.model.action) {
case 'Translate':
if (this.dragging) {
this.dragging = false;
this.doTranslateTrip(this.tripModel)
}
break;
}
},
onMouseDown(e) {
switch(this.model.action) {
case 'Edit':
this.pixelExecCb(e, this.handlePopDialog);
break;
}
},
onMouseOver(e) {
this.pixelExecCb(e, this.handleSelectLine);
if (this.model.action == 'Translate') {
setTimeout(() => {
this.onShapeMouseOver(e);
}, 200);
}
},
onMouseOut(e) {
this.pixelExecCb(e, this.handleSelectLine);
if (this.model.action == 'Translate') {
this.onShapeMouseOver(e);
}
},
onMouseUP(e) {
},
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});
},
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 && value[2] == nxt[2]) {
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.planJustRunning });
}
}
},
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.model.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(utils.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(utils.createMarkPointObj(pointInPixel))
myChart.setOption(option, {notMerge: true});
const filters = elements.filter(el => { return el.subType == 'mark'});
if (filters.length == 1) {
this.tripModel.startStationCode = yObj.code;
this.tripModel.startTime = timeFormat(xVal);
} else if (filters.length >= 2) {
this.tripModel.endStationCode = yObj.code;
this.doCreateTrip(this.tripModel);
}
},
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});
}
}
}

View File

@ -1,586 +0,0 @@
<template>
<div id="PlanSchedule">
<el-card class="box-card">
<div slot="header" class="header">
<div class="menus-left">
<el-button type="primary" @click="doNewPlan">New</el-button>
</div>
<div class="menus-right">
<span style="font-size:22px;padding:0 17px;">Plan</span>
<menus :model="model" :selected="selected" @remove="handleRemove" @clear="handleClear" />
</div>
</div>
<div :id="mapPlanId" :mapName="mapName" />
</el-card>
<plan-just-running :selected="selected" :stations="stations" @justRunning="doJustRunning" />
<plan-just-stop :selected="selected" :stations="stations" @justStop="doJustStop"/>
</div>
</template>
<script>
import echarts from 'echarts';
import PlanJustRunning from './dialog/planJustRunning.vue';
import PlanJustStop from './dialog/planJustStop.vue';
import Menus from './menus.vue';
import Monitor from './monitor.js';
import { mapGetters } from 'vuex';
import { timeFormat } from '@/utils/date';
import { getStationList } from '@/api/runplan';
import { getRpTools, clearRpPlan, addRpTrip, delRpTrip, justTripNoRunning, justTripNoStop, translateTripNo} from '@/api/rpTools';
import { getPublishMapInfo } from '@/api/jmap/map';
export default {
mixins: [Monitor],
components: {
PlanJustRunning,
PlanJustStop,
Menus
},
props: {
planConvert: {
type: Object,
required: true
},
maxWidth: {
type: Number,
required: true
},
maxHeight: {
type: Number,
required: true
},
loadRunPlanId: {
type: String,
default() {
return '';
}
}
},
data() {
return {
mapName: 'XXX',
mapPlanId: 'plan-tool',
myChart: null,
kmRangeCoordMap: {},
stationsObj: {},
model: {
choice: 'Plan',
action: '',
}
};
},
computed: {
...mapGetters('rpTools', [
'stations'
]),
planId() {
return this.$route.query.planId;
},
mapId() {
return 9;
},
option() {
return {
title: {
text: '',
left: 'center',
top: '10px'
},
grid: {
top: '60px',
left: '160px',
right: '100px',
bottom: '80px',
containLabel: true,
backgroundColor: 'floralwhite'
},
toolbox: {
},
tooltip: {
trigger: 'item',
axisPointer: {
type: 'cross',
snap: true,
axis: 'x'
},
formatter: this.axisTooltip,
borderWidth: 1,
position: function (pt) {
const data = pt[0] + 10;
return [data, '20%'];
}
},
xAxis: [
{
type: 'category',
boundaryGap: false,
data: [],
axisLine: {
onZero: false,
lineStyle: {
width: 1
}
},
axisLabel: {
formatter: this.xAxisLableFormat,
textStyle: {
color: '#333'
}
},
axisPointer: {
snap: true,
label: {
formatter: this.xAxisPointFormat,
backgroundColor: 'rgb(255,0,0,0.5)',
color: 'white'
}
}
}
],
yAxis: {
type: 'value',
splitLine: {
show: false
},
axisTick: {
show: false
},
axisLine: {
onZero: false,
lineStyle: {
width: 1
}
},
axisLabel: {
interval: 'auto',
formatter: this.yAxisLableFormat
},
axisPointer: {
xAxisIndex: 'all',
label: {
formatter: this.yAxisPointFormat,
backgroundColor: 'rgb(0,100,0,0.5)',
color: 'white'
}
},
min: 0,
max: 0
},
graphic: [{
id: 'shape',
elements: []
}],
series: [],
dataZoom: [
{
type: 'inside',
zoomOnMouseWheel : 'ctrl',
moveOnMouseMove : 'ctrl',
moveOnMouseWheel: 'ctrl'
},
{
type: 'slider',
filterMode: 'empty',
bottom: '20px'
}
]
}
}
},
watch: {
maxWidth() {
this.setPosition();
},
maxHeight() {
this.setPosition();
},
'$store.state.rpTools.planSizeCount': function () {
this.reSize({ width: this.$store.state.rpTools.width, height: this.$store.state.rpTools.height });
},
'$store.state.rpTools.refreshCount': function() {
this.loadChartPage();
},
$route() {
this.$nextTick(() => {
this.loadChartPage();
});
},
loadRunPlanId() {
this.loadChartPage();
}
},
mounted() {
this.setPosition();
this.loadChartPage();
},
beforeDestroy() {
this.destroy();
},
methods: {
setPosition() {
this.$nextTick(() => {
const width = this.maxWidth;
const height = this.maxHeight;
this.$store.dispatch('rpTools/resize', { width, height });
});
},
loadInitChart() {
return new Promise((resolve, reject) => {
try {
if (this.myChart && this.myChart.isDisposed) {
this.myChart.clear();
}
if (this.$route.query.planName || this.$route.query.prdType === '05') {
this.option.title.text = this.mapName;
}
this.myChart = echarts.init(document.getElementById(this.mapPlanId));
this.myChart.setOption(this.option, {notMerge: true});
this.reSize({ width: this.$store.state.rpTools.width, height: this.$store.state.rpTools.height });
resolve(true);
} catch (error) {
reject(error);
}
});
},
async loadChartPage() {
try {
this.$store.dispatch('rpTools/clear').then(() => {
this.loadInitChart().then(() => {
if (this.mapId) {
getStationList(this.mapId).then(resp => {
const stations = resp.data.filter(el => {
return ['车辆段', '停车场'].findIndex(it => {
return el.name.includes(it)
}) < 0;
});
this.stationsObj = {};
stations.forEach(item => {
this.stationsObj[Math.floor(item.kmRange)] = item;
});
this.$store.dispatch('rpTools/setStations', stations).then(() => {
this.loadInitData();
this.myChart && this.myChart.showLoading();
getRpTools().then(rest => {
this.$store.dispatch('rpTools/setPlanData', rest.data).then(() => {
this.loadChartData();
this.myChart && this.myChart.hideLoading();
});
}).catch(() => {
this.myChart && this.myChart.hideLoading();
this.$messageBox(this.$t('error.obtainOperationGraphFailed'));
});
});
}).catch(() => {
this.$messageBox(this.$t('tip.requestingStationDataFailed'));
this.$store.dispatch('rpTools/setStations', []);
});
}
});
});
} catch (error) {
this.$messageBox(this.$t('error.loadingOperationGraphFailed'));
}
},
async loadInitData() {
await this.xAxisInit();
await this.yAxisInit();
await this.loadInitChart();
},
async loadChartData() {
try {
const stations = this.$store.state.rpTools.stations;
const planData = this.$store.state.rpTools.planData;
const option = this.myChart.getOption();
option.series = [];
option.graphic[0].elements = [];
this.kmRangeCoordMap = this.planConvert.convertStationsToMap(stations);
this.pushModels(option.series, [this.planConvert.initializeYaxis(this.stations)]);
this.pushModels(option.series, this.planConvert.convertDataToModels(planData, stations, this.kmRangeCoordMap, { width: 0.5, color: '#000' }));
this.myChart.setOption(option, {notMerge: true});
} catch (error) {
this.$messageBox(this.$t('error.loadingOperationGraphFailed') + this.$t('global.colon') + error.message);
}
},
pushModels(series, models) {
if (models && models.length) {
models.forEach(elem => {
if (elem) {
series.push(elem);
}
});
}
return series;
},
popModels(series, models) {
if (models && models.length) {
models.forEach(elem => {
const index = series.indexOf(elem);
if (index >= 0) {
series.split(index, 1);
}
});
}
return series;
},
destroy() {
if (this.myChart && this.myChart.isDisposed) {
this.myChart.dispose();
this.myChart = null;
}
},
xAxisPointFormat(params) {
return timeFormat(params.value);
},
yAxisPointFormat(params) {
return this.planConvert.computedFormatYAxis(this.stations, params);
},
xAxisLableFormat(value, index) {
if (value % 60 === 0) {
return timeFormat(value);
}
},
yAxisLableFormat(value, index) {
return '';
},
xAxisInit() {
const list = [];
for (var time = 0 + this.planConvert.TranslationTime; time < 3600 * 24 + this.planConvert.TranslationTime; time++) {
list.push(time);
}
const startValue = 3600 * 6;
const offsetTime = 3600 / 2;
this.option.xAxis[0].data = list;
if (!this.option.dataZoom[0].startValue) {
this.option.dataZoom[0].startValue = this.option.dataZoom[1].startValue = startValue - offsetTime;
}
if (!this.option.dataZoom[0].endValue) {
this.option.dataZoom[0].endValue = this.option.dataZoom[1].endValue = startValue + offsetTime;
}
},
yAxisInit() {
if (Object.keys(this.planConvert).length) {
this.pushModels(this.option.series, [this.planConvert.initializeYaxis(this.stations)]);
this.option.yAxis.min = this.planConvert.computedYaxisMinValue(this.stations);
this.option.yAxis.max = this.planConvert.computedYaxisMaxValue(this.stations);
}
},
axisTooltip(param) {
let data = '';
const arr = [];
const station = this.stations.find(el => { return el.code == param.value[2] })||{ name: '', kmRange: ''};
if (!arr.includes(`${param.data[0]}${param.data[1]}`)) {
arr.push(`${param.data[0]}${param.data[1]}`);
const list = [
`Station name: ${station.name}<br>`,
`Kilometer post: ${station.kmRange} m <br>`,
`Arrival Time: ${timeFormat(param.data[0] + this.planConvert.TranslationTime)}<br>`,
`Train number: ${param.seriesName}${param.data[3]}`,
`<hr size=1 style="margin: 3px 0">`
];
data += list.join('');
}
return data;
},
reSize(opt) {
if (this.myChart) {
this.myChart.resize({
width: opt.width,
height: opt.height,
silent: false
});
}
},
handleClear() {
this.setLineReset();
this.clearGraphic(['drag', 'mark']);
this.model.action = '';
this.selected = null;
},
handleCreate() {
switch(this.model.choice) {
case 'Plan':
this.doCreateTrip();
break;
case 'Construction':
this.doCreateArea();
break;
}
},
handleTranslate(data) {
switch(this.model.choice) {
case 'Plan':
this.doTranslateTrip(data);
break;
case 'Construction':
this.doTranslateArea(data);
break;
}
},
handleRemove(){
this.$confirm('此操作将永久删除该数据, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
switch(this.model.choice) {
case 'Plan':
this.doRemoveTrip();
break;
case 'Construction':
this.doRemoveArea();
break;
}
}).catch(() => {
this.$message({ type: 'info', message: '已取消删除' });
});
},
doNewPlan() {
clearRpPlan().then(resp => {
getRpTools().then(rest => {
this.$store.dispatch('rpTools/setPlanData', rest.data).then(() => {
this.loadChartData();
});
}).catch(() => {
this.$messageBox(this.$t('error.obtainOperationGraphFailed'));
});
}).catch(error => {
this.$message(error.message);
})
},
doJustRunning(time) {
if (this.selected) {
const model = {
seconds: time,
stationCode: this.selected.stationCode
}
justTripNoRunning(this.selected.seriesId, model).then(resp => {
getRpTools().then(rest => {
this.$store.dispatch('rpTools/setPlanData', rest.data).then(() => {
this.loadChartData();
});
}).catch(() => {
this.$messageBox(this.$t('error.obtainOperationGraphFailed'));
});
}).catch(error => {
this.$message(error.message);
})
}
},
doJustStop(time){
if (this.selected) {
const model = {
seconds: time,
stationCode: this.selected.stationCode
}
justTripNoStop(this.selected.seriesId, model).then(resp => {
getRpTools().then(rest => {
this.$store.dispatch('rpTools/setPlanData', rest.data).then(() => {
this.loadChartData();
});
}).catch(() => {
this.$messageBox(this.$t('error.obtainOperationGraphFailed'));
});
}).catch(error => {
this.$message(error.message);
})
}
},
doCreateTrip(data) {
if (this.myChart) {
addRpTrip(data).then(resp => {
getRpTools().then(rest => {
this.$store.dispatch('rpTools/setPlanData', rest.data).then(() => {
this.loadChartData();
});
}).catch(() => {
this.$messageBox(this.$t('error.obtainOperationGraphFailed'));
});
}).catch(error => {
this.$message(error.message);
this.clearGraphic(['mark']);
})
}
},
doCreateArea() {
},
doTranslateTrip(data) {
if (this.selected) {
const model = {
seconds : this.selected.time
}
translateTripNo(this.selected.seriesId, model).then(resp => {
getRpTools().then(rest => {
this.$store.dispatch('rpTools/setPlanData', rest.data).then(() => {
this.loadChartData();
});
}).catch(() => {
this.$messageBox(this.$t('error.obtainOperationGraphFailed'));
});
}).catch(error => {
this.$message(error.message);
});
}
},
doTranslateArea(data) {
},
doRemoveTrip() {
if (this.myChart && this.selected) {
delRpTrip(this.selected.seriesId).then(resp => {
getRpTools().then(rest => {
this.$store.dispatch('rpTools/setPlanData', rest.data).then(() => {
this.loadChartData();
this.handleClear();
});
}).catch(() => {
this.$messageBox(this.$t('error.obtainOperationGraphFailed'));
});
}).catch(error => {
this.$message(error.message);
})
}
},
doRemoveArea() {
}
}
};
</script>
<style scoped rel="stylesheet/scss" lang="scss">
@import "src/styles/mixin.scss";
#PlanSchedule {
z-index: 0;
width: 100%;
height: 100%;
position: relative;
.header {
margin: 0 80px;
display: flex;
justify-content: space-between;
align-items: center;
.menus-left {
display: flex;
align-items: center;
}
.menus-right {
display: flex;
align-items: center;
}
}
}
</style>

View File

@ -1,37 +0,0 @@
export function 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
}
}
export function 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)'
}
}
}

View File

@ -1,5 +1,5 @@
<template>
<el-dialog v-dialogDrag append-to-body title="Modification of train diagram parameters" :visible.sync="dialogShow" width="30%" :close-on-click-modal="false" :before-close="doClose">
<el-dialog v-dialogDrag append-to-body title="Modify area parameters" :visible.sync="dialogShow" width="30%" :close-on-click-modal="false" :before-close="doClose">
<el-form ref="form" label-width="160px" :model="formModel" :rules="rules">
<el-form-item label="Start station" prop="startStationCode">
<el-select v-model="formModel.startStationCode" placeholder="请选择">

View File

@ -0,0 +1,80 @@
<template>
<el-dialog v-dialogDrag append-to-body title="Add area content" :visible.sync="dialogShow" width="30%" :close-on-click-modal="false" :before-close="doClose">
<el-form ref="form" label-width="100px" :model="formModel" >
<el-form-item label="Start station" prop="text">
<el-input type="textarea" :rows="2" placeholder="Please enter the content." v-model="formModel.text" />
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogShow = false">{{ $t('map.cancel') }}</el-button>
<el-button type="primary" @click="doConfirm">{{ $t('map.confirm') }}</el-button>
</span>
</el-dialog>
</template>
<script>
import { MenuEnum } from '../utils.js';
import { getRpConfig } from '@/api/rpTools';
import { toTimeStamp } from '@/utils/date';
export default {
props: {
target: {
type: Object,
default() {
return null
}
}
},
data() {
return {
dialogShow: false,
formModel: {
areaNo: '',
fartherStationCode: '',
closerStationCode: '',
startTime: '',
endTime: '',
text: ''
},
}
},
watch: {
'$store.state.menuOperation.menuCount': function (val) {
if (this.$store.getters['menuOperation/checkDialogIsOpen'](MenuEnum.planSetAreaNote)) {
this.doShow(this.$store.state.menuOperation.menuPosition);
} else {
this.doClose();
}
}
},
methods: {
doShow() {
if (this.target &&
this.target.model) {
const model = this.target.model;
this.formModel = {
areaNo: model.areaNo,
fartherStationCode: model.fartherStationCode,
closerStationCode: model.closerStationCode,
startTime: model.startTime,
endTime: model.endTime,
text: model.text
};
}
this.dialogShow = true;
},
doClose() {
this.dialogShow = false;
},
doConfirm() {
this.$refs.form.validate((valid) => {
if(valid) {
this.$emit('setAreaNote', this.formModel);
this.doClose();
}
});
}
}
};
</script>

View File

@ -36,6 +36,7 @@
<plan-just-stop :config="config" :selected="selected" :stations="stations" @justStop="doJustStop"/>
<plan-set-params :config="config" @setParams="doSetPlanParams" />
<plan-modify-area :target="target" :stations="stations" @modifyArea="doModifyArea" />
<plan-set-area-note :target="target" @setAreaNote="doSetAreaNote" />
</div>
</template>
@ -45,6 +46,7 @@ import PlanJustRunning from './dialog/planJustRunning.vue';
import PlanJustStop from './dialog/planJustStop.vue';
import PlanSetParams from './dialog/planSetParams.vue';
import PlanModifyArea from './dialog/planModifyArea.vue';
import PlanSetAreaNote from './dialog/planSetAreaNote';
import Menus from './menus.vue';
import { MenuEnum } from './utils.js';
import { timeFormat } from '@/utils/date';
@ -53,7 +55,7 @@ import { getStationList } from '@/api/runplan';
import {
getRpTools, clearRpPlan, addRpTrip, delRpTrip,
justTripNoRunning, justTripNoStop,
translateTripNo,
translateTrip,
getRpConfig, modifyRpConfig,
createRpArea, modifyRpArea, delRpArea
} from '@/api/rpTools';
@ -65,6 +67,7 @@ export default {
PlanJustStop,
PlanSetParams,
PlanModifyArea,
PlanSetAreaNote,
Menus
},
data() {
@ -155,11 +158,11 @@ export default {
})
},
onClear() {
this.model.action = '';
this.selected = null;
this.target = null;
this.$refs.schedule.setLineReset();
this.$refs.schedule.clearGraphic();
this.$refs.schedule.clearGraphic();
this.$refs.schedule.clearTrip();
},
onDialog(menu) {
this.$store.dispatch('menuOperation/setPopMenu', { position: {x: 0, y: 0}, menu });
@ -185,6 +188,9 @@ export default {
case 'Plan':
this.doTranslateTrip(data);
break;
case 'Construction':
this.doTranslateArea(data);
break;
}
},
onRemove(){
@ -253,6 +259,20 @@ export default {
this.$message.info(error.message);
})
},
doSetAreaNote(data) {
modifyRpArea(data.areaNo, data).then(resp => {
getRpTools().then(rest => {
const planData = rest.data;
this.$store.commit('rpTools/setPlanData', planData);
this.$refs.schedule.loadChartData(planData);
this.$message.success('Construction area note modified successfully.');
}).catch(() => {
this.$messageBox('Failed to load the plan.');
});
}).catch(error => {
this.$message.info(error.message);
})
},
doJustRunning(time) {
if (this.selected) {
const model = {
@ -349,10 +369,10 @@ export default {
doTranslateTrip() {
if (this.selected) {
const model = {
seconds : this.selected.time
seconds : this.selected.sx
}
translateTripNo(this.selected.tripNo, model).then(resp => {
translateTrip(this.selected.tripNo, model).then(resp => {
getRpTools().then(rest => {
const planData = rest.data;
this.$store.commit('rpTools/setPlanData', planData);
@ -364,7 +384,31 @@ export default {
this.$message.info(error.message);
});
}
},
},
doTranslateArea() {
if (this.target) {
const data = this.target.model;
const model = {
fartherStationCode: data.fartherStationCode,
closerStationCode: data.closerStationCode,
startTime: data.startTime,
endTime: data.endTime,
text: data.text
}
modifyRpArea(data.areaNo, model).then(resp => {
getRpTools().then(rest => {
const planData = rest.data;
this.$store.commit('rpTools/setPlanData', planData);
this.$refs.schedule.loadChartData(planData);
}).catch(() => {
this.$messageBox('Failed to load the plan.');
});
}).catch(error => {
this.$message.info(error.message);
});
}
},
doRemoveTrip() {
if (this.selected) {
delRpTrip(this.selected.tripNo).then(resp => {

View File

@ -1,6 +1,6 @@
<template>
<div class="menus">
<el-select v-model="model.choice" placeholder="请选择功能类型" style="margin-right:20px" @change="$emit('clear')">
<el-select v-model="model.choice" placeholder="请选择功能类型" style="margin-right:20px" @change="doSelChange">
<el-option v-for="(el,i) in options" :key="i" :label="el.label" :value="el.value" />
</el-select>
<div v-if="option">
@ -93,9 +93,17 @@ export default {
label: 'Add',
value: 'Add',
},
{
label: 'Translate',
value: 'Translate'
},
{
label: 'Edit',
value: 'Edit'
},
{
label: 'Note',
value: 'Note'
}
],
buttonList: [
@ -120,6 +128,10 @@ export default {
: el[prop]
: '';
},
doSelChange() {
this.$emit('clear');
this.model.action = '';
},
doBtnSelect(el, i) {
if (this.option.radioList &&
this.model.action != el.value) {
@ -127,6 +139,7 @@ export default {
this.model.action = el.value;
} else {
this.$emit('clear')
this.model.action = '';
}
}
}

View File

@ -1,5 +1,6 @@
import echarts from 'echarts';
import * as utils from './utils'
import { timeFormat, toTimeStamp } from '@/utils/date';
import { MenuEnum } from './utils';
export default {
@ -30,8 +31,9 @@ export default {
pixelExecCb(e, cb) {
const event = e.componentType ? e.event: e;
const pointInPixel = [event.offsetX, event.offsetY]
const pointInGrid = this.myChart.convertFromPixel('grid', pointInPixel);
if (this.myChart.containPixel('grid', pointInPixel) && this.planUtil) {
const pointInGrid = this.myChart.convertFromPixel({seriesIndex:0},pointInPixel);
const xIndex = pointInGrid[0];
const yIndex = pointInGrid[1];
const option = this.myChart.getOption();
@ -39,7 +41,7 @@ export default {
const xVal = option.xAxis[0].data[xIndex];
const yObj = this.planUtil.getStationByCoordinate(this.stations, yIndex-minY);
if (yObj && cb) {
cb({yObj, xVal, pointInPixel, e});
cb({yObj, xVal, pointInPixel, pointInGrid, e});
}
}
},
@ -47,8 +49,10 @@ export default {
if (this.myChart) {
const zr = this.myChart.getZr();
zr.on('mouseover', this.onZrMouseOver, this);
zr.on('mousedown', this.onZrMouseDown, this);
zr.on('mouseup', this.onZrMouseUp, this);
zr.on('mouseout', this.onZrMouseOut, this);
this.myChart.on('mousedown', this.onMouseDown);
this.myChart.on('mouseover', this.onMouseOver);
this.myChart.on('mouseout', this.onMouseOut);
@ -61,8 +65,10 @@ export default {
if (this.myChart) {
const zr = this.myChart.getZr();
zr.off('mousedown', this.onZrMouseDown);
zr.off('mouseover', this.onZrMouseOver, this);
zr.off('mousedown', this.onZrMouseDown, this);
zr.off('mouseup', this.onZrMouseUp, this);
zr.off('mouseout', this.onZrMouseOut, this);
this.myChart.off('mousedown', this.onMouseDown);
this.myChart.off('mouseover', this.onMouseOver);
this.myChart.off('mouseout', this.onMouseOut);
@ -93,56 +99,69 @@ export default {
}
})
this.$emit('clear');
this.myChart.setOption({graphic});
},
onZrMouseOver(e) {
this.pixelExecCb(e, this.doSetTarget);
if (this.model.choice == 'Construction') {
if (this.model.action == 'Translate') {
this.pixelExecCb(e, this.doSetAreaTranslate);
} else if (this.model.action == 'Edit') {
this.pixelExecCb(e, this.doClrAreaDrags);
}
}
},
onZrMouseDown(e) {
if (e.target && ['Area'].includes(e.target.subType)) {
this.target = e.target;
this.$emit('tag', this.target);
this.onZrMouseOver(e);
this.dragging = true;
if (this.model.choice == 'Construction') {
if (this.model.action == 'Edit') {
this.pixelExecCb(e, this.handlePopDialog);
if (this.model.action == 'Note') {
this.pixelExecCb(e, this.doPopDialog);
}
}
}
if (this.model.choice == 'Plan') {
if (this.model.action == 'Add') {
this.pixelExecCb(e, this.onCreateMark);
} else {
if (this.model.choice == 'Plan') {
if (this.model.action == 'Add') {
this.pixelExecCb(e, this.doCreateMark);
} else {
this.$emit('clear')
}
} else if (this.model.choice == 'Construction') {
if (this.model.action == 'Add') {
this.pixelExecCb(e, this.doCreateArea);
} else {
this.$emit('clear')
}
} else {
this.$emit('clear')
}
} else if (this.model.choice == 'Construction') {
if (this.model.action == 'Add') {
this.pixelExecCb(e, this.onCreateArea);
}
}
if (!e.target) {
this.setLineReset();
this.$emit('tag', null);
this.$emit('select', null);
}
},
onZrMouseUp(e) {
if (['Plan', 'Construction'].includes(this.model.choice)) {
if(this.model.action == 'Translate' && this.dragging) {
this.dragging = false;
this.pixelExecCb(e, this.onTranslate)
this.pixelExecCb(e, this.doTranslate)
}
}
this.dragging = false;
},
onMouseDown(e) {
if (this.model.choice == 'Plan') {
if (this.model.action == 'Edit') {
this.pixelExecCb(e, this.handlePopDialog);
onZrMouseOut(e) {
if (this.model.choice == 'Construction') {
if (this.model.action == 'Translate') {
this.pixelExecCb(e, this.doClrAreaTranslate);
} else if (this.model.action == 'Edit') {
this.pixelExecCb(e, this.doClrAreaDrags);
}
}
},
onMouseOver(e) {
this.pixelExecCb(e, ({e, pointInPixel}) => {
this.pixelExecCb(e, args => {
if (this.model.choice == 'Plan') {
this.handleSelectLine({e});
this.doSetSelected(args);
if (this.model.action == 'Translate') {
this.onCreateDrag({e, pointInPixel})
this.doCreateDrag(args)
}
}
});
@ -153,12 +172,20 @@ export default {
}
}
},
onMouseDown(e) {
this.dragging = true;
if (this.model.choice == 'Plan') {
if (this.model.action == 'Edit') {
this.pixelExecCb(e, this.doPopDialog);
}
}
},
onMouseOut(e) {
this.pixelExecCb(e, ({e, pointInPixel}) => {
this.pixelExecCb(e, args => {
if (this.model.choice == 'Plan') {
this.handleSelectLine({e});
this.doSetSelected(args);
if(this.model.action == 'Translate') {
this.onCreateDrag({e, pointInPixel})
this.doCreateDrag(args)
}
}
});
@ -170,22 +197,14 @@ export default {
}
},
onMouseUP(e) {
},
onShapeDragging(e) {
if (this.selected) {
this.dragging = true;
if (this.model.choice == 'Plan') {
if (this.model.action == 'Translate') {
this.pixelExecCb(e, this.handleSeriesDragging);
}
} else if (this.model.choice == 'Construction') {
if (this.model.action == 'Translate') {
this.pixelExecCb(e, this.handleAreaDragging);
}
if (['Construction'].includes(this.model.choice)) {
if(this.model.action == 'Translate' && this.dragging) {
this.pixelExecCb(e, this.doTranslate)
this.dragging = false;
}
}
},
onShapeMouseOver() {
onShapeMouseOver(e) {
if (this.selected) {
this.myChart.dispatchAction({
type: 'showTip',
@ -194,22 +213,34 @@ export default {
});
}
},
onShapeMouseOut() {
onShapeDragging(e) {
if (this.selected &&
this.model.choice == 'Plan') {
if (this.model.action == 'Translate') {
this.pixelExecCb(e, this.doSeriesDragging);
}
} else if ( this.target &&
this.model.choice == 'Construction') {
if (this.model.action == 'Translate') {
this.pixelExecCb(e, this.doAreaDragging);
}
}
},
onShapeMouseOut(e) {
if (this.selected) {
this.myChart.dispatchAction({
type: 'hideTip',
});
}
},
onCreateDrag({e, pointInPixel}) {
doCreateDrag({e, pointInGrid, pointInPixel}) {
if (this.selected) {
const option = this.myChart.getOption();
const filters = option.graphic[0].elements.filter(el => { return el.subType != 'drag'});
filters.push(utils.buildDragDataObj(pointInPixel, this.myChart.convertFromPixel('grid', pointInPixel), this))
filters.push(utils.buildDragDataObj(pointInPixel, pointInGrid, this))
option.graphic[0].elements = filters;
this.myChart.setOption(option, {notMerge: true});
this.myChart.dispatchAction({
type: 'showTip',
seriesIndex: this.selected.seriesIndex,
@ -217,12 +248,12 @@ export default {
});
}
},
onCreateMark({e, pointInPixel, yObj, xVal}) {
doCreateMark({e, pointInGrid, pointInPixel, yObj, xVal}) {
const option = this.myChart.getOption();
const graphic = option.graphic;
const elements = graphic[0].elements;
elements.push(utils.buildMarkPointObj(pointInPixel, this.myChart.convertFromPixel('grid', pointInPixel), this))
elements.push(utils.buildMarkPointObj(pointInPixel, pointInGrid, this))
this.myChart.setOption(option, {notMerge: true});
@ -239,13 +270,13 @@ export default {
this.$emit('create', this.buildModel);
}
},
onCreateArea({e, pointInPixel, yObj, xVal}) {
doCreateArea({e, pointInGrid, pointInPixel, yObj, xVal}) {
if (!e.target) {
const option = this.myChart.getOption();
const graphic = option.graphic;
const elements = graphic[0].elements;
elements.push(utils.buildMarkPointObj(pointInPixel, this.myChart.convertFromPixel('grid', pointInPixel), this))
elements.push(utils.buildMarkPointObj(pointInPixel, pointInGrid, this))
this.myChart.setOption(option, {notMerge: true});
@ -263,7 +294,111 @@ export default {
}
}
},
handlePopDialog({e, pointInPixel}) {
doSetTarget({e, pointInGrid}) {
if (e.target && ['Area'].includes(e.target.subType)) {
const target = e.target;
const model = target.model
Object.assign(model, {
_x: pointInGrid[0],
_y: pointInGrid[1],
dx: 0,
dy: 0,
sx: 0,
sy: 0
})
this.target = target;
this.$emit('tag', target);
}
},
doSetSelected({e, pointInGrid}) {
if (e.componentType == "series" &&
e.componentSubType == "line" &&
e.seriesName.includes('service')) {
const value = e.value;
const option = this.myChart.getOption();
const dataList = option.series[e.seriesIndex].data;
const length = dataList.length;
const next = utils.findNext(dataList, e.dataIndex, (el, i) => { return el instanceof Array});
const isService = this.model.choice == 'Plan' && ['Translate', 'Edit'].includes(this.model.action);
if (this.selected &&
this.selected.seriesName != e.seriesName) {
this.setLineReset();
this.clearTrip();
}
if (!isService) {
const service = option.series[e.seriesIndex];
const index = option.series.findIndex(el => { return el.name.includes('trip') })
if (index < 0) {
option.series.push({
name: 'service-trip',
type: 'line',
symbolSize: 1,
showAllSymbol: true,
data: []
})
}
const series = option.series[option.series.findIndex(el => { return el.name.includes('trip') })];
series.data = service.data.filter(el => { return el instanceof Array && el[2].tripNo == value[2].tripNo })
this.myChart.setOption(option, {notMerge: true});
}
this.selected = {
dataIndex: e.dataIndex,
seriesIndex: e.seriesIndex,
seriesName: isService? e.seriesName: 'service-trip',
seriesId: e.seriesId,
depTime: e.dataIndex < length - 1? next[0] - value[0]: 0,
runTime: e.dataIndex < length - 1? next[0] - value[0]: 0,
... value[2],
_x: pointInGrid[0],
_y: pointInGrid[1],
dx: 0,
dy: 0,
sx: 0,
sy: 0
}
this.$emit('select', this.selected);
this.setLineLight();
}
},
doSetAreaTranslate({e}) {
if (e.target && ['Area'].includes(e.target.subType)) {
const option = this.myChart.getOption();
const shape = option.graphic[0].elements.find(el => { return ['Area'].includes(el.subType) && el.areaNo == this.target.areaNo; });
Object.assign(shape, {
draggable: true,
ondrag: echarts.util.curry(this.onShapeDragging)
})
this.myChart.setOption(option);
}
},
doClrAreaTranslate({e}) {
if (e.target && ['Area'].includes(e.target.subType)) {
const option = this.myChart.getOption();
const shape = option.graphic[0].elements.find(el => { return ['Area'].includes(el.subType) && el.areaNo == this.target.areaNo; });
Object.assign(shape, {
draggable: false
})
this.myChart.setOption(option);
}
},
doSetAreaDrags({e}) {
console.log('set drag')
},
doClrAreaDrags({e}) {
console.log('clr drag')
},
doPopDialog({e, pointInGrid, pointInPixel}) {
const point = {
x: pointInPixel[0],
y: pointInPixel[1]
@ -271,98 +406,95 @@ export default {
if (e.componentType == "series" &&
e.componentSubType == "line" &&
e.seriesName.includes('plan-')) {
e.seriesName.includes('service')) {
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];
const value = e.value;
const next = utils.findNext(dataList, e.dataIndex, (el, i) => { return el instanceof Array});
const prev = utils.findPrev(dataList, e.dataIndex, (el, i) => { return el instanceof Array});
this.selected = {
dataIndex: e.dataIndex,
seriesIndex: e.seriesIndex,
seriesName: e.seriesName,
seriesId: e.seriesId,
depTime: e.dataIndex < length - 1? nxt[0] - value[0]: 0,
runTime: e.dataIndex < length - 1? nxt[0] - value[0]: 0,
...e.value[2],
_x: value[0],
dx: 0,
time: 0,
}
this.$emit('select', this.selected);
this.doSetSelected({e, pointInGrid});
if (e.dataIndex < length - 1 && value[1] == nxt[1]) {
if (e.dataIndex < length - 1 && e.value[1] == next[1]) {
this.$store.dispatch('menuOperation/setPopMenu', { position: point, menu: MenuEnum.planJustStop });
} else if (e.dataIndex == 0 || e.dataIndex > 0 && value[1] == pre[1]) {
} else if (e.dataIndex == 0 || e.dataIndex > 0 && e.value[1] == prev[1]) {
this.$store.dispatch('menuOperation/setPopMenu', { position: point, menu: MenuEnum.planJustRunning });
}
} else if (e.target && e.target.subType == 'Area') {
this.$store.dispatch('menuOperation/setPopMenu', { position: point, menu: MenuEnum.planModifyArea });
this.doSetTarget({e, pointInGrid})
if (this.model.action == 'Note') {
this.$store.dispatch('menuOperation/setPopMenu', { position: point, menu: MenuEnum.planSetAreaNote });
}
}
},
handleSelectLine({e}) {
if (e.componentType == "series" &&
e.componentSubType == "line" &&
e.seriesName.includes('plan-')) {
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];
doSeriesDragging({e, pointInGrid}) {
if (this.selected && this.dragging) {
this.selected.dx = pointInGrid[0] - this.selected._x;
this.selected.dy = pointInGrid[1] - this.selected._y;
this.selected.sx += this.selected.dx;
this.selected.sy += this.selected.dy;
this.selected._x = pointInGrid[0];
this.selected._y = pointInGrid[1];
if (this.selected &&
this.selected.seriesName != e.seriesName) {
this.setLineReset();
if (this.selected.dx || this.selected.dy) {
const option = this.myChart.getOption();
const model = option.series[this.selected.seriesIndex]
model.data.forEach(el => {
if (el instanceof Array) {
el[0] += this.selected.dx;
} else {
el.value[0] += this.selected.dx;
}
});
model.markPoint.data.forEach(el => {
el.coord[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});
}
this.selected = {
dataIndex: e.dataIndex,
seriesIndex: e.seriesIndex,
seriesName: e.seriesName,
seriesId: e.seriesId,
depTime: e.dataIndex < length - 1? nxt[0] - value[0]: 0,
runTime: e.dataIndex < length - 1? nxt[0] - value[0]: 0,
...e.value[2],
_x: value[0],
dx: 0,
time: 0
}
this.$emit('select', this.selected);
this.setLineLight();
}
},
handleSeriesDragging({e, xVal}) {
if (this.selected) {
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]
model.data.forEach(el => {
el[0] += this.selected.dx;
});
model.markPoint.data.forEach(el => {
el.coord[0] += this.selected.dx;
})
if (e.target &&
e.target.point &&
e.target.position) {
e.target.point[0] += this.selected.dx;
doAreaDragging({e, pointInGrid}) {
if (this.target && ['Area'].includes(this.target.subType) && this.dragging) {
const model = this.target.model;
if (model.sx == undefined || model.sy == undefined) {
this.onZrMouseOver(e);
} else {
model.dx = pointInGrid[0] - model._x;
model.dy = pointInGrid[1] - model._y;
model.sx += model.dx;
model.sy += model.dy;
model._x = pointInGrid[0];
model._y = pointInGrid[1];
}
this.myChart.setOption(option, {notMerge: true});
}
},
handleAreaDragging({e, xVal}) {
},
onTranslate({e}) {
doTranslate({e}) {
if (this.target && ['Area'].includes(this.target.subType)) {
const model = this.target.model;
const sx = model.sx||0;
const sy = model.sy||0;
const fartherStationValue = this.planUtil.getCoordinateYByStationCode(this.stations, model.fartherStationCode) + sy;
const closerStationValue = this.planUtil.getCoordinateYByStationCode(this.stations, model.closerStationCode) + sy;
const fartherStation = this.planUtil.getStationByCoordinate(this.stations, fartherStationValue)||{code: model.fartherStationCode};
const closerStation = this.planUtil.getStationByCoordinate(this.stations, closerStationValue)||{code: model.closerStationCode};
model.startTime = timeFormat(toTimeStamp(model.startTime)+sx);
model.endTime = timeFormat(toTimeStamp(model.endTime)+sx);
model.fartherStationCode = fartherStation.code;
model.closerStationCode = closerStation.code;
}
this.$emit('translate');
}
}

View File

@ -39,7 +39,7 @@ export default {
},
canvasId: {
type: String,
default: 'plan-tool'
default: 'service-tool'
}
},
data() {
@ -47,7 +47,6 @@ export default {
myChart: null,
stations: [],
planData: [],
kmRangeCoordinateMap:{}
};
},
computed: {
@ -241,7 +240,6 @@ export default {
this.myChart.showLoading();
this.stations = stations;
this.kmRangeCoordinateMap = this.planUtil.convertStationsToMap(this.stations);
this.xAxisInit(stations);
this.yAxisInit(stations);
@ -262,8 +260,8 @@ export default {
this.planData = planData;
this.pushModels(option.series, [this.planUtil.initializeYaxis(this.stations)]);
this.pushModels(option.series, this.planUtil.parseDataToSeries(this.myChart, planData, this.stations, this.kmRangeCoordinateMap));
this.pushModels(option.graphic[0].elements, this.planUtil.parseDataToGraph(this.myChart, planData, this.stations, this.kmRangeCoordinateMap));
this.pushModels(option.series, this.planUtil.parseDataToSeries(this.myChart, planData, this.stations));
this.pushModels(option.graphic[0].elements, this.planUtil.parseDataToGraph(this.myChart, planData, this.stations));
this.myChart.setOption(option, {notMerge: true});
} catch (error) {
@ -361,6 +359,14 @@ export default {
});
}
},
clearTrip() {
const option = this.myChart.getOption();
const index = option.series.findIndex(el => { return el.name.includes('service-trip') });
if (index >= 0) {
option.series[index].data = [];
this.myChart.setOption(option, {notMerge: true});
}
},
clearGraphic(labels=['drag', 'mark']) {
const option = this.myChart.getOption();
const elements = option.graphic[0].elements;

View File

@ -4,7 +4,8 @@ export const MenuEnum = {
planJustRunning: '1000',
planJustStop: '1001',
planSetParams: '1002',
planModifyArea: '1003'
planModifyArea: '1003',
planSetAreaNote: '1004'
}
export function buildDragDataObj(position, point, that) {
@ -44,3 +45,36 @@ export function buildMarkPointObj(position, point, that) {
}
}
}
export function createTripModel(opt, lineStyle={}, itemStyle={}) {
return {
z: opt.z || 10,
type: 'line',
name: opt.name,
data: opt.data,
sampling: 'average',
symbolSize: opt.symbolSize,
showAllSymbol: opt.showAllSymbol||'auto',
lineStyle: lineStyle,
itemStyle: itemStyle,
animation: false
};
}
export function findNext(list, idx, cb) {
for(var i = idx+1; i < list.length; i++) {
if (cb(list[i], i)) {
return list[i];
}
}
return null;
}
export function findPrev(list, idx, cb) {
for(var i = idx-1; i >= 0; i--) {
if (cb(list[i], i)) {
return list[i];
}
}
return null;
}