iscs 绘图

This commit is contained in:
fan 2020-01-14 09:06:03 +08:00
parent 8c43ac0b07
commit 365f36edef
16 changed files with 880 additions and 121 deletions

View File

@ -72,5 +72,6 @@ export default {
newsBulletin: 'New bulletin',
commandDictionary: 'Command dictionary',
configLine: 'Line management',
deviceManage: 'Device management'
deviceManage: 'Device management',
iscsDraw: 'Iscs Draw'
};

View File

@ -73,5 +73,6 @@ export default {
newsBulletin: '消息公告',
commandDictionary: '指令字典',
configLine: '线路管理',
deviceManage: '设备管理'
deviceManage: '设备管理',
iscsDraw: 'Iscs绘制'
};

View File

@ -0,0 +1,5 @@
import deviceType from './deviceType';
const deviceRender = {};
export default deviceRender;

View File

@ -0,0 +1,17 @@
const deviceType = {
SquareButton: 'SquareButton',
Arrow: 'Arrow',
TipBox: 'TipBox',
Background: 'Background',
CircularLamp: 'CircularLamp',
AppendageBox: 'AppendageBox',
Alarm: 'Alarm',
Elevator: 'Elevator',
Key: 'Key',
TeleTerminal: 'TeleTerminal',
Clock: 'Clock',
RotateTip: 'RotateTip',
CheckBox: 'CheckBox'
};
export default deviceType;

View File

@ -1,17 +1,16 @@
import zrender from 'zrender';
// import * as zrUtil from 'zrender/src/core/util';
import localStore from 'storejs';
import Options from './options';
import MouseController from './mouseController';
import Painter from './painter';
import deviceType from './constant/deviceType';
import {calculateDCenter, createBoundingRect, deviceFactory} from './utils/parser';
import { updateIbpData } from './utils/parser';
import { updateIscsData } from './utils/parser';
const renderer = 'canvas';
const devicePixelRatio = 1;
class IbpPan {
class Iscs {
constructor(opts) {
this.methods = opts.methods;
@ -19,25 +18,25 @@ class IbpPan {
this.events = { __Pan: 'pan', Selected: 'selected', Contextmenu: 'contextmenu'};
// 设备数据
this.ibpDevice = {};
this.iscsDevice = {};
// 展示的画布大小
this.canvasSize = {};
this.initIbpPage(opts);
this.initIscsPage(opts);
}
initIbpPage(opts) {
initIscsPage(opts) {
const width = opts.config.width;
const height = opts.config.height;
this.isAllowDragging = false;
this.$ibpZr = zrender.init(opts.dom, Object.assign({ renderer, devicePixelRatio, width, height }, opts.config));
this.$iscsZr = zrender.init(opts.dom, Object.assign({ renderer, devicePixelRatio, width, height }, opts.config));
this.$options = new Options(Object.assign({ scaleRate: 1, offsetX: 0, offsetY: 0 }, opts.options || {})); // 缩放
this.$mouseController = new MouseController(this);
this.$mouseController.enable();
this.$painter = new Painter(this);
this.$painter.updateZrSize({width: this.$ibpZr.getWidth(), height: this.$ibpZr.getHeight()});
this.$painter.updateZrSize({width: this.$iscsZr.getWidth(), height: this.$iscsZr.getHeight()});
this.$painter.updateTransform(this.$options, this.canvasSize);
this.optionsHandler = this.setOptions.bind(this);
@ -45,7 +44,7 @@ class IbpPan {
this.$mouseController.on(this.events.__Pan, this.optionsHandler);
}
setIbp(config, ibpDevice) {
setIscs(config, iscsDevice) {
// 保存平移缩放数据
if (config.config) {
this.$options.scaleRate = config.scaling;
@ -65,16 +64,16 @@ class IbpPan {
};
// 地图数据
this.ibpDevice = ibpDevice;
this.iscsDevice = iscsDevice;
// 数据加载完成 回调
if (this.methods.dataLoaded instanceof Function) { this.methods.dataLoaded(this.ibpDevice); }
if (this.methods.dataLoaded instanceof Function) { this.methods.dataLoaded(this.iscsDevice); }
// 初次渲染视图
this.$painter.repaint(this.ibpDevice);
this.$painter.repaint(this.iscsDevice);
// 视图加载完成 回调
if (this.methods.viewLoaded instanceof Function) { this.methods.viewLoaded(this.ibpDevice); }
if (this.methods.viewLoaded instanceof Function) { this.methods.viewLoaded(this.iscsDevice); }
this.$painter.updateTransform(this.$options, this.canvasSize);
}
@ -105,10 +104,10 @@ class IbpPan {
}
setCenter(deviceCode) {
const device = this.ibpDevice[deviceCode];
const device = this.iscsDevice[deviceCode];
if (device && device.instance) {
var rect = createBoundingRect(device.instance);
var dcenter = calculateDCenter(rect, { width: this.$ibpZr.getWidth(), height: this.$ibpZr.getHeight() });
var dcenter = calculateDCenter(rect, { width: this.$iscsZr.getWidth(), height: this.$iscsZr.getHeight() });
this.setOptions(dcenter);
}
}
@ -129,13 +128,13 @@ class IbpPan {
height: elem.height
};
}
updateIbpData(elem);
const oDevice = this.ibpDevice[code] || deviceFactory(type, elem);
updateIscsData(elem);
const oDevice = this.iscsDevice[code] || deviceFactory(type, elem);
const nDevice = deviceFactory(type, Object.assign(oDevice.model || {}, elem));
delete this.ibpDevice[code];
delete this.iscsDevice[code];
this.$painter.delete(oDevice);
if (!elem._dispose) {
this.ibpDevice[code] = nDevice;
this.iscsDevice[code] = nDevice;
this.$painter.add(nDevice);
}
});
@ -168,7 +167,7 @@ class IbpPan {
update(list) {
(list || []).forEach(elem => {
const code = elem.code;
const oDevice = this.ibpDevice[code];
const oDevice = this.iscsDevice[code];
if (elem.dispose) {
this.$painter.delete(oDevice);
} else {
@ -181,11 +180,11 @@ class IbpPan {
if (this.methods.stateUpdate instanceof Function) { this.methods.stateUpdate(list); }
}
setStatus(code, model) {
const oDevcie = this.ibpDevice[code].instance;
const oDevcie = this.iscsDevice[code].instance;
oDevcie.setStatus(model);
}
setDeviceStatus(list) {
const deviceList = Object.values(this.ibpDevice);
const deviceList = Object.values(this.iscsDevice);
deviceList.forEach(elem =>{
(list || []).forEach(it =>{
if (elem.model.linkDevice === it.code) {
@ -195,14 +194,14 @@ class IbpPan {
});
}
drawIbpInit() {
drawIscsInit() {
this.$mouseController.setAllowDragging(true);
}
pullBack(payload) {
if (payload.type === 'zoom') {
const zrWidth = this.$ibpZr.getWidth();
const zrHeight = this.$ibpZr.getHeight();
const zrWidth = this.$iscsZr.getWidth();
const zrHeight = this.$iscsZr.getHeight();
const originX = payload.originX || zrWidth / 2;
const originY = payload.originY || zrHeight / 2;
const x = (this.$options.offsetX + originX) / this.$options.scaleRate;
@ -218,7 +217,7 @@ class IbpPan {
}
getZr() {
return this.$ibpZr;
return this.$iscsZr;
}
getEvents() {
@ -226,11 +225,11 @@ class IbpPan {
}
getDeviceByCode(code) {
return this.ibpDevice[code];
return this.iscsDevice[code];
}
resize(opt) {
this.$ibpZr.resize(opt);
this.$iscsZr.resize(opt);
this.$painter.updateZrSize(opt);
}
@ -240,25 +239,9 @@ class IbpPan {
clear() {
this.skinCode = '';
this.style = {};
this.ibpDevice = {};
this.iscsDevice = {};
this.$painter.clear();
}
initClockTime(initTime) {
Object.values(this.ibpDevice)
.forEach(elem => {
if (elem.model._type === deviceType.Clock) {
this.$painter.initClockTime(elem, initTime);
}
});
}
setClockStart(started) {
Object.values(this.ibpDevice)
.forEach(elem => {
if (elem.model._type === deviceType.Clock) {
this.$painter.setClockStart(elem, started);
}
});
}
dispose() {
this.off(this.events.Pan, this.optionsHandler);
this.off(this.events.Zoom, this.optionsHandler);
@ -266,7 +249,7 @@ class IbpPan {
this.clear();
this.$mouseController.dispose();
this.$ibpZr && zrender.dispose(this.$ibpZr);
this.$iscsZr && zrender.dispose(this.$iscsZr);
this.$painter.dispose();
}
@ -274,15 +257,15 @@ class IbpPan {
const idx = Object.values(this.events).indexOf(eventname);
if (idx >= 0) {
switch (eventname) {
case this.events.Selected:
this.$mouseController.on(this.events.Selected, cb, context);
break;
case this.events.Contextmenu:
this.$mouseController.on(this.events.Contextmenu, cb, context);
break;
case this.events.DataZoom:
this.$mouseController.on(this.events.DataZoom, cb, context);
break;
case this.events.Selected:
this.$mouseController.on(this.events.Selected, cb, context);
break;
case this.events.Contextmenu:
this.$mouseController.on(this.events.Contextmenu, cb, context);
break;
case this.events.DataZoom:
this.$mouseController.on(this.events.DataZoom, cb, context);
break;
}
}
}
@ -291,15 +274,15 @@ class IbpPan {
const idx = Object.values(this.events).indexOf(eventname);
if (idx >= 0) {
switch (eventname) {
case this.events.Selected:
this.$mouseController.off(this.events.Selected, cb);
break;
case this.events.Contextmenu:
this.$mouseController.off(this.events.Contextmenu, cb);
break;
case this.events.DataZoom:
this.$mouseController.off(this.events.DataZoom, cb);
break;
case this.events.Selected:
this.$mouseController.off(this.events.Selected, cb);
break;
case this.events.Contextmenu:
this.$mouseController.off(this.events.Contextmenu, cb);
break;
case this.events.DataZoom:
this.$mouseController.off(this.events.DataZoom, cb);
break;
}
}
}
@ -307,21 +290,21 @@ class IbpPan {
renderCheckBox(model) {
const type = model._type;
const code = model.code;
const oDevice = this.ibpDevice[code] || deviceFactory(type, model);
const oDevice = this.iscsDevice[code] || deviceFactory(type, model);
const nDevice = deviceFactory(type, Object.assign(oDevice.model || {}, model));
delete this.ibpDevice[code];
delete this.iscsDevice[code];
this.$painter.delete(oDevice);
if (!model._dispose) {
this.ibpDevice[code] = nDevice;
this.iscsDevice[code] = nDevice;
this.$painter.add(nDevice);
}
}
deleteCheckBox(code) {
const oDevice = this.ibpDevice[code];
const oDevice = this.iscsDevice[code];
if (oDevice) {
delete this.ibpDevice[code];
delete this.iscsDevice[code];
this.$painter.delete(oDevice);
}
}
}
export default IbpPan;
export default Iscs;

View File

@ -23,12 +23,12 @@ class EventModel {
}
class MouseController extends Eventful {
constructor(ibp) {
constructor(iscs) {
super();
this.$ibp = ibp;
this.$zr = ibp.getZr();
this.isAllowDragging = ibp.isAllowDragging || false; // 是否在绘图中,仅绘图状态下可拖拽
this.events = ibp.getEvents();
this.$iscs = iscs;
this.$zr = iscs.getZr();
this.isAllowDragging = iscs.isAllowDragging || false; // 是否在绘图中,仅绘图状态下可拖拽
this.events = iscs.getEvents();
this._dragging = false; // 是否在拖拽状态
this.deviceList = [];
this.rightClickPoint = {
@ -127,7 +127,7 @@ class MouseController extends Eventful {
item.setModel(e.offsetX - this._offsetX, e.offsetY - this._offsetY);
});
this.deviceList = [];
this.$ibp.deleteCheckBox('check_box');
this.$iscs.deleteCheckBox('check_box');
this.eventTarget = '';
this._dragging = false;
this.deviceList = [];
@ -158,7 +158,7 @@ class MouseController extends Eventful {
const trainDetails = store.state.map.trainDetails;
if (trainDetails) {
if (newEm.deviceType != deviceType.Train || trainDetails.code != newEm.deviceCode) {
var instance = (this.$ibp.getDeviceByCode(trainDetails.code) || {} ).instance;
var instance = (this.$iscs.getDeviceByCode(trainDetails.code) || {} ).instance;
instance && instance.removeTrainDetail && instance.removeTrainDetail();
}
}
@ -169,10 +169,10 @@ class MouseController extends Eventful {
var newEm = new EventModel(e);
if ([1, 3].includes(e.which)) {
// 查找之前和当前鼠标选中的实例
var oldDevice = this.$ibp.getDeviceByCode(oldEm.deviceCode) || {};
var newDevice = this.$ibp.getDeviceByCode(newEm.deviceCode) || {};
var oldInstance = (this.$ibp.getDeviceByCode(oldEm.deviceCode) || {}).instance || {};
var newInstance = (this.$ibp.getDeviceByCode(newEm.deviceCode) || {}).instance || {};
var oldDevice = this.$iscs.getDeviceByCode(oldEm.deviceCode) || {};
var newDevice = this.$iscs.getDeviceByCode(newEm.deviceCode) || {};
var oldInstance = (this.$iscs.getDeviceByCode(oldEm.deviceCode) || {}).instance || {};
var newInstance = (this.$iscs.getDeviceByCode(newEm.deviceCode) || {}).instance || {};
// 如果之前和当前选中的实例不一致
if (oldInstance != newInstance) {
@ -205,17 +205,17 @@ class MouseController extends Eventful {
handleMouseDownLeft(e) {
if (this.eventTarget && this.eventTarget._type === deviceType.Background) {
this.eventTarget.setCursor('pointer');
this.$ibp.deleteCheckBox('check_box');
this.$iscs.deleteCheckBox('check_box');
} else if (this.eventTarget && this.eventTarget._type === deviceType.CheckBox) {
this.handleBoundingRect(this.eventTarget);
} else {
this.$ibp.deleteCheckBox('check_box');
this.$iscs.deleteCheckBox('check_box');
}
}
/** 处理滚轮按下事件 */
handleMouseDownWheel(e) {
this.deviceList = [];
Object.values(this.$ibp.ibpDevice).forEach(item => {
Object.values(this.$iscs.iscsDevice).forEach(item => {
if (item.instance._type !== deviceType.Background) {
this.deviceList.push(item.instance);
}
@ -224,11 +224,11 @@ class MouseController extends Eventful {
/** 处理右键拖动事件--- 改变选中区域大小 */
handleMouseMoveRight(point2) {
const point1 = this.rightClickPoint;
const x = Math.min(point1.x, point2.x) + this.$ibp.$options.offsetX;
const y = Math.min(point1.y, point2.y) + this.$ibp.$options.offsetY;
const x = Math.min(point1.x, point2.x) + this.$iscs.$options.offsetX;
const y = Math.min(point1.y, point2.y) + this.$iscs.$options.offsetY;
const width = Math.abs(point1.x - point2.x);
const height = Math.abs(point1.y - point2.y);
this.$ibp.renderCheckBox({code: 'check_box', _type: 'CheckBox', point: {x: x, y: y}, width: width, height: height });
this.$iscs.renderCheckBox({code: 'check_box', _type: 'CheckBox', point: {x: x, y: y}, width: width, height: height });
}
/** 处理左键拖动事件--- 图形移动 */
handleMouseMoveLeft(e, dx, dy, oldX, oldY) {
@ -254,7 +254,7 @@ class MouseController extends Eventful {
this.deviceList = [];
let boundingRect = eventTarget.grouper.getBoundingRect();
boundingRect = this.createFakeBoundingRect(eventTarget, boundingRect);
const deviceList = Object.values(this.$ibp.ibpDevice);
const deviceList = Object.values(this.$iscs.iscsDevice);
const includeDeviceList = [];
deviceList.forEach( item =>{
if (item.instance._type !== deviceType.Background) {

View File

@ -6,13 +6,13 @@ import shapefactory from './shape/factory';
import TransformHandle from './transformHandle';
class Painter {
constructor(ibp) {
constructor(iscs) {
// 父级实例
this.$ibp = ibp;
this.$ibpZr = ibp.getZr();
this.$iscs = iscs;
this.$iscsZr = iscs.getZr();
// 图层数据
this.ibpInstanceLevel = {};
this.iscsInstanceLevel = {};
// 初始图层
this.initLevels();
@ -30,26 +30,26 @@ class Painter {
// 添加父级图层
this.parentLevel = new Group({ name: '__parent__' });
this.$ibpZr.add(this.parentLevel);
this.$iscsZr.add(this.parentLevel);
// 添加子级图层
zrUtil.each(Object.values(deviceType), (type) => {
const level = new Group({ name: `__${type}__` });
this.ibpInstanceLevel[type] = level;
this.iscsInstanceLevel[type] = level;
this.parentLevel.add(level);
});
}
/**
* 重绘视图
* @param {*} ibpDevice
* @param {*} iscsDevice
*/
repaint(ibpDevice) {
repaint(iscsDevice) {
// 清空视图
this.clear();
// 创建视图
Object.values(ibpDevice).forEach(device => {
Object.values(iscsDevice).forEach(device => {
this.add(device);
});
}
@ -60,12 +60,12 @@ class Painter {
*/
add(device) {
try {
device = Object.assign(device, { event: this.$ibp.$mouseController });
const instance = shapefactory(device, this.$ibp);
device = Object.assign(device, { event: this.$iscs.$mouseController });
const instance = shapefactory(device, this.$iscs);
if (instance) {
device.instance = instance;
this.$transformHandle.transformView(instance);
this.ibpInstanceLevel[device.model._type].add(instance);
this.iscsInstanceLevel[device.model._type].add(instance);
}
} catch (error) {
console.error(error);
@ -79,7 +79,7 @@ class Painter {
delete(device) {
const instance = device.instance;
if (instance) {
this.ibpInstanceLevel[device.model._type].remove(instance);
this.iscsInstanceLevel[device.model._type].remove(instance);
}
}
@ -116,25 +116,13 @@ class Painter {
this.$transformHandle.updateZrSize(opt);
}
/**
* 初始化电子时钟时间
*/
initClockTime(device, initTime) {
device.instance.setClockTime(initTime);
}
/**
* 电子时钟开始跑秒或暂停
*/
setClockStart(device, started) {
device.instance.setClockStart(started);
}
/**
* 设置图层可见
* @param {*} code
*/
setLevelVisible(list) {
zrUtil.each(Object.values(deviceType), type => {
const level = this.ibpInstanceLevel[type];
const level = this.iscsInstanceLevel[type];
if (list.includes(type)) {
level.show();
} else {
@ -147,14 +135,14 @@ class Painter {
* 刷新图层
*/
refresh() {
this.$ibpZr.refresh();
this.$iscsZr.refresh();
}
/**
* 清除图层
*/
clearLevel(type) {
const level = this.ibpInstanceLevel[type];
const level = this.iscsInstanceLevel[type];
if (level) {
level.removeAll();
}
@ -164,7 +152,7 @@ class Painter {
* 清除canvas
*/
clear() {
zrUtil.each(Object.values(this.ibpInstanceLevel), (level) => {
zrUtil.each(Object.values(this.iscsInstanceLevel), (level) => {
level && level.removeAll();
}, this);
@ -175,7 +163,7 @@ class Painter {
* 销毁图层
*/
dispose() {
this.ibpInstanceLevel = {};
this.iscsInstanceLevel = {};
this.parentLevel = null;
}

12
src/iscs/shape/factory.js Normal file
View File

@ -0,0 +1,12 @@
const iscsShape = {};
function shapefactory(device, iscs) {
const type = device.model._type;
const shape = iscsShape[type];
if (shape instanceof Function) {
// eslint-disable-next-line
return new shape(device, iscs.style);
}
}
export default shapefactory;

View File

@ -0,0 +1,34 @@
import Group from 'zrender/src/container/Group';
import Rect from 'zrender/src/graphic/shape/Rect';
import Polygon from 'zrender/src/graphic/shape/Polygon';
export default class FireHydrantAlarmButton extends Group() {
constructor(device) {
super();
this.model = device.model;
this._type = device.model._type;
this._code = device.model.code;
this.zlevel = device.model.zlevel;
this.z = device.model.zlevel;
this.create();
}
create() {
this.rect = new Rect({
zlevel: this.model.zlevel,
z: this.model.z,
shape: {
x: this.model.point.x,
y: this.model.point.y,
width: this.model.width,
height: this.model.height
},
style: {
fill: '#0f0'
}
});
this.add(this.rect);
this.polygonTop = new Polygon({
});
}
}

View File

@ -2,6 +2,7 @@ import Group from 'zrender/src/container/Group';
import Rect from 'zrender/src/graphic/shape/Rect';
import Circle from 'zrender/src/graphic/shape/Circle';
import Text from 'zrender/src/graphic/Text';
import AppendageBox from '../../ibp/shape/appendageBox';
export default class manualAlarmButton extends Group() {
constructor(device) {
@ -14,6 +15,64 @@ export default class manualAlarmButton extends Group() {
this.create();
}
cerate() {
this.rect = new Rect({
zlevel: this.model.zlevel,
z: this.model.z - 1,
shape: {
x: this.model.point.x,
y: this.model.point.y,
width: this.model.width,
height: this.model.height
},
style: {
lineWidth: 1,
stroke: '#0F0'
}
});
this.add(this.rect);
this.text = new Text({
zlevel: this.model.zlevel,
z: this.model.z,
style: {
x: this.model.point.x,
y: this.model.point.y,
fontWeight: this.model.fontWeight,
fontSize: this.model.fontSize,
fontFamily: this.model.fontFamily,
text: this.model.context,
textStrokeWidth: this.model.textStrokeWidth,
textFill: this.model.textFill,
textAlign: this.model.textAlign,
textPosition: this.model.textPosition || 'inside',
textVerticalAlign: this.model.textVerticalAlign || null,
textLineHeight: this.model.fontSize
}
});
this.add(this.text);
this.circleOutside = new Circle({
zlevel: this.model.zlevel,
z: this.model.z,
shape: {
cx: this.model.point.x,
cy: this.model.point.y,
r: this.model.r1
},
style: {
fill: '#0f0'
}
});
this.add(this.circleOutside);
this.circleInside = new Circle({
zlevel: this.model.zlevel,
z: this.model.z,
shape: {
cx: this.model.point.x,
cy: this.model.point.y,
r: this.model.r2
},
style: {
fill: '#000'
}
});
}
}

147
src/iscs/utils/parser.js Normal file
View File

@ -0,0 +1,147 @@
import * as zrUtil from 'zrender/src/core/util';
import * as matrix from 'zrender/src/core/matrix';
import deviceType from '../constant/deviceType';
import deviceRender from '../constant/deviceRender';
import store from '@/store';
export function createTransform(opts) {
let transform = matrix.create();
transform = matrix.scale(matrix.create(), transform, [opts.scaleRate, opts.scaleRate]);
transform = matrix.translate(matrix.create(), transform, [-opts.offsetX, -opts.offsetY]);
return transform;
}
export function createBoundingRect(view) {
const rect = view.getBoundingRect();
const scale = view.scale[0];
const offsetX = view.position[0];
const offsetY = view.position[1];
rect.x = rect.x * scale + offsetX;
rect.y = rect.y * scale + offsetY;
rect.width = rect.width * scale;
rect.height = rect.height * scale;
return rect;
}
export function calculateDCenter(viewRect, zrbound) {
var dx = (zrbound.width - viewRect.width) / 2 - viewRect.x;
var dy = 0;
return { dx: dx, dy: dy };
}
export function deviceFactory(type, elem) {
return Object.assign({instance: null, event: null, model: Object.assign(elem, deviceRender[type])});
}
export function parser(data) {
var iscsDevice = {};
if (data) {
Object.assign(data.background);
iscsDevice[data.background.code] = deviceFactory(deviceType.Background, data.background);
zrUtil.each(data.squareButtonList || [], elem => {
iscsDevice[elem.code] = deviceFactory(deviceType.SquareButton, elem);
}, this);
zrUtil.each(data.circularLampList || [], elem => {
iscsDevice[elem.code] = deviceFactory(deviceType.CircularLamp, elem);
}, this);
zrUtil.each(data.alarmList || [], elem => {
iscsDevice[elem.code] = deviceFactory(deviceType.Alarm, elem);
}, this);
zrUtil.each(data.arrowList || [], elem => {
iscsDevice[elem.code] = deviceFactory(deviceType.Arrow, elem);
}, this);
zrUtil.each(data.tipBoxList || [], elem => {
iscsDevice[elem.code] = deviceFactory(deviceType.TipBox, elem);
}, this);
zrUtil.each(data.appendageBoxList || [], elem => {
iscsDevice[elem.code] = deviceFactory(deviceType.AppendageBox, elem);
}, this);
zrUtil.each(data.elevatorList || [], elem => {
iscsDevice[elem.code] = deviceFactory(deviceType.Elevator, elem);
}, this);
zrUtil.each(data.keyList || [], elem => {
iscsDevice[elem.code] = deviceFactory(deviceType.Key, elem);
}, this);
zrUtil.each(data.teleTerminalList || [], elem => {
iscsDevice[elem.code] = deviceFactory(deviceType.TeleTerminal, elem);
}, this);
zrUtil.each(data.clockList || [], elem => {
iscsDevice[elem.code] = deviceFactory(deviceType.Clock, elem);
});
zrUtil.each(data.rotateTipList || [], elem => {
iscsDevice[elem.code] = deviceFactory(deviceType.RotateTip, elem);
});
}
return iscsDevice;
}
function updateIscsListByDevice(iscs, name, device) {
var list = iscs[name];
if (list) {
const index = list.findIndex(elem => { return elem.code == device.code; });
if (index >= 0) {
device._dispose ? list.splice(index, 1) : list[index] = device;
} else {
list.push(device);
}
} else {
iscs[name] = [device];
}
return list;
}
export function updateIscsData(device) {
const iscsData = store.getters['iscs/iscs'];
switch (device._type) {
case deviceType.Background :
iscsData.background = device;
break;
case deviceType.SquareButton :
updateIscsListByDevice(iscsData, 'squareButtonList', device);
break;
case deviceType.Arrow :
updateIscsListByDevice(iscsData, 'arrowList', device);
break;
case deviceType.TipBox :
updateIscsListByDevice(iscsData, 'tipBoxList', device);
break;
case deviceType.CircularLamp :
updateIscsListByDevice(iscsData, 'circularLampList', device);
break;
case deviceType.AppendageBox :
updateIscsListByDevice(iscsData, 'appendageBoxList', device);
break;
case deviceType.Alarm :
updateIscsListByDevice(iscsData, 'alarmList', device);
break;
case deviceType.Elevator :
updateIscsListByDevice(iscsData, 'elevatorList', device);
break;
case deviceType.Key :
updateIscsListByDevice(iscsData, 'keyList', device);
break;
case deviceType.TeleTerminal :
updateIscsListByDevice(iscsData, 'teleTerminalList', device);
break;
case deviceType.Clock :
updateIscsListByDevice(iscsData, 'clockList', device);
break;
case deviceType.RotateTip:
updateIscsListByDevice(iscsData, 'rotateTipList', device);
break;
}
store.dispatch('iscs/setIscsData', iscsData);
}

View File

@ -33,6 +33,7 @@ const ExistingSimulation = () => import('@/views/system/existingSimulation/index
const CacheControl = () => import('@/views/system/cacheControl/index');
const SystemGenerate = () => import('@/views/system/systemGenerate/index');
const IbpDraw = () => import('@/views/system/ibpDraw/index');
const IscsDraw = () => import('@/views/system/iscsDraw/index');
const News = () => import('@/views/system/news/index');
const CommandDictionary = () => import('@/views/system/commandDictionary/index');
const CommandDictionaryDetail = () => import('@/views/system/commandDictionary/edit');
@ -777,6 +778,13 @@ export const asyncRouter = [
i18n: 'router.ibpDraw'
}
},
{
path:'iscs/edit',
component: IscsDraw,
meta: {
i18n: 'router.iscsDraw'
}
},
{
path: 'dictionary',
component: Dictionary,

79
src/store/modules/iscs.js Normal file
View File

@ -0,0 +1,79 @@
import Vue from 'vue';
/**
* iscs状态数据
*/
const iscs = {
namespaced: true,
state: {
iscs: null, // 数据
iscsDevice: {}, // 解析后的地图数据
iscsList: {}, // 数据列表
iscsIdList: {}, // 数据列表(以id为标识)
updateDeviceData: {}, // 修改的数据
rightClickCount: 0 // 右键点击设备
},
getters: {
iscsList: (state) => {
return state.iscsList;
},
iscs: (state) => {
return state.iscs;
},
version: (state) => {
if (state.iscs) {
return state.iscs.version;
} else {
return null;
}
},
updateDeviceData: (state) => {
return state.updateDeviceData;
}
},
mutations: {
iscsRender: (state, devices) => {
Vue.prototype.$iscs && Vue.prototype.$iscs.render(devices);
},
setIscsData: (state, iscs) => {
state.iscs = iscs;
},
setUpdateDeviceData: (state, model) => {
state.rightClickCount++;
state.updateDeviceData = model;
},
deleteIscsDevices: (state, devices) => {
Vue.prototype.$iscs && Vue.prototype.$iscs.render(devices);
}
},
actions: {
setIscsData: ({ commit }, iscs) => {
commit('setIscsData', iscs);
},
updateIscsDevices: ({ commit }, models) => {
return new Promise((resolve) => {
if (!(models instanceof Array)) {
models = [models];
}
commit('iscsRender', models);
resolve(models);
});
},
setUpdateDeviceData: ({ commit }, models) => {
commit('setUpdateDeviceData', models);
},
deleteIscsDevices: ({ commit }, models ) => {
models = Object.assign(models, {_dispose: true});
if (!(models instanceof Array)) {
models = [models];
}
commit('deleteIscsDevices', models);
}
}
};
export default iscs;

View File

@ -0,0 +1,247 @@
<template>
<div>
<div :id="iscsId" v-loading="loading" :style="{ width: this.canvasWidth +'px', height: this.canvasHeight +'px',background:'#000' }" class="iscs-canvas" />
<el-button v-if="showBackButton" class="iscs-button" type="primary" @click="back">{{ $t('global.back') }}</el-button>
</div>
</template>
<script>
import Vue from 'vue';
import Iscs from '@/iscs/iscs';
import { parser } from '@/iscs/utils/parser';
import { mapGetters } from 'vuex';
import { exitFullscreen } from '@/utils/screen';
import { putJointTrainingSimulationUser } from '@/api/chat';
import { handlerIscsEvent } from '@/api/simulation';
import { IscsOperation } from '@/scripts/ConstDic';
export default {
name: 'Iscs',
props: {
size: {
type: Object,
default() {
return null;
}
}
},
data() {
return {
width: this.$store.state.config.width,
height: this.$store.state.config.height,
dataZoom: {
offsetX: '0',
offsetY: '0',
scaleRate: '1'
},
config: {
scaleRate: '1',
origin: {
x: 0,
y: 0
}
},
showBackButton: true,
initTime: '',
started: false,
loading: false,
stationCode: '',
banUpOpenScreenDoor: false,
banDownOpenScreenDoor: false
};
},
computed: {
...mapGetters([
'canvasWidth',
'canvasHeight'
]),
iscsId() {
return ['iscs', (Math.random().toFixed(5)) * 100000].join('_');
}
},
watch: {
'$store.state.config.canvasSizeCount': function (val) {
this.reSize();
},
'$store.state.app.windowSizeCount': function() {
this.setWindowSize();
},
'$store.state.training.initTime': function (initTime) {
this.initTime = initTime;
if (this.$iscs) {
this.initClockTime(initTime);
}
},
'$store.state.training.started': function (started) {
this.started = started;
if (this.$iscs) {
this.setClockStart(started);
}
},
'$store.state.socket.equipmentStatus': function (val) {
if (val.length) {
this.statusMessage(val);
}
}
},
mounted() {
this.setWindowSize();
},
beforeDestroy() {
this.iscsDestroy();
},
methods: {
show (deviceCode, iscsPart) {
if (!deviceCode) {
return;
}
this.stationCode = deviceCode;
document.getElementById(this.iscsId).oncontextmenu = function (e) {
return false;
};
let offsetX = 0;
if (iscsPart === 'left') {
offsetX = 0;
} else if (iscsPart === 'right') {
offsetX = 1920;
}
this.iscsDestroy();
this.loading = true;
const data = {};
this.$iscs = new Iscs({
dom: document.getElementById(this.iscsId),
config: {
renderer: 'canvas',
width: this.canvasWidth,
height: this.canvasHeight
},
options: {
scaleRate: 1,
offsetX: offsetX,
offsetY: 0
},
methods: {
viewLoaded: this.handleViewLoaded
}
});
Vue.prototype.$iscs = this.$iscs;
this.$iscs.on('contextmenu', this.onContextMenu, this);
if (this.$route.query.group) {
this.$iscs.on('selected', this.onSelected, this);
}
this.setIscs(data, {});
this.$store.dispatch('iscs/setIscsData', {});
this.handleBanOpenScreenDoorStatus();
this.initClockTime(this.initTime);
window.document.oncontextmenu = function () {
return false;
};
},
setIscs(data, oldData) {
this.$iscs.setIscs(oldData, data);
},
handleBanOpenScreenDoorStatus() {
this.$store.state.iscs.iscs['keyList'].forEach(item => {
if (item.mean === 'Ban_Down_Open_Screen_Door') {
item.status === 'on' ? this.banDownOpenScreenDoor = false : this.banDownOpenScreenDoor = true;
} else if (item.mean === 'Ban_Up_Open_Screen_Door') {
item.status === 'on' ? this.banUpOpenScreenDoor = false : this.banUpOpenScreenDoor = true;
}
});
},
//
onSelected(em) {
if (em.deviceModel.mean) {
switch (IscsOperation[em.deviceModel.mean].event) {
case 'UpHoldTrain':
case 'UpCancelHoldTrain':
case 'DownHoldTrain':
case 'DownCancelHoldTrain':
handlerIscsEvent(this.$route.query.group, {operate:IscsOperation[em.deviceModel.mean].operate, stationCode:this.stationCode});
break;
case 'BanUpOpenScreenDoor':
this.banUpOpenScreenDoor = !this.banUpOpenScreenDoor;
break;
case 'BanDownOpenScreenDoor':
this.banDownOpenScreenDoor = !this.banDownOpenScreenDoor;
break;
case 'UpOpenScreenDoor':
this.openScreenDoor(this.banUpOpenScreenDoor, IscsOperation[em.deviceModel.mean].operate);
break;
case 'DownOpenScreenDoor':
this.openScreenDoor(this.banDownOpenScreenDoor, IscsOperation[em.deviceModel.mean].operate);
break;
}
}
},
openScreenDoor(flag, operate) {
if (flag) {
handlerIscsEvent(this.$route.query.group, {operate: operate, stationCode:this.stationCode});
}
},
//
onContextMenu(em) {
this.$store.dispatch('iscs/setUpdateDeviceData', em.eventTarget.model);
},
//
drawIscsInit() {
this.$iscs && this.$iscs.drawIscsInit();
this.showBackButton = false;
},
//
initClockTime(initTime) {
this.$iscs.initClockTime(initTime);
},
//
setClockStart(started) {
this.$iscs.setClockStart(started);
},
reSize() {
this.$nextTick(() => {
this.width = this.$store.state.config.width;
this.height = this.$store.state.config.height;
this.$iscs && this.$iscs.resize({ width: this.width, height: this.height });
});
},
setWindowSize() {
this.$nextTick(() => {
const width = this.size ? this.size.width : this.$store.state.app.width;
const height = this.size ? this.size.height : this.$store.state.app.height;
this.$store.dispatch('config/resize', { width: width, height: height });
});
},
back() {
this.group = this.$route.query.group;
this.$store.dispatch('training/over').then(() => {
putJointTrainingSimulationUser(this.group).then(() => {
this.$router.replace({ path: `/trainroom`, query: { group: this.group, lineCode:this.$route.query.lineCode } });
exitFullscreen();
});
});
},
iscsDestroy() {
if (this.$iscs) {
this.$iscs.dispose();
this.$iscs = '';
Vue.prototype.$iscs = '';
}
},
handleViewLoaded() {
this.loading = false;
},
statusMessage(val) {
this.$iscs && this.$iscs.setDeviceStatus(val);
}
}
};
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
.iscs-button{
position: absolute;
float: right;
right: 20px;
bottom: 15px;
}
.iscs-canvas{
}
</style>

View File

@ -0,0 +1,82 @@
<template>
<transition name="el-zoom-in-center">
<div class="mapPaint">
<div class="map-view">
<iscs-plate ref="iscsPlate" :size="size" />
</div>
<div class="map-draft">
<iscs-operate ref="iscsOperate" @iscsChange="iscsChange" />
</div>
</div>
</transition>
</template>
<script>
import IscsPlate from '@/views/iscsSystem/index';
import IscsOperate from './iscsOperate/index';
export default {
name: 'IscsView',
components: {
IscsPlate,
IscsOperate
},
data() {
return {
size: {
width: this.$store.state.app.width - 521,
height: this.$store.state.app.height - 60
}
};
},
watch: {
'$store.state.app.windowSizeCount': function() {
this.$store.dispatch('config/resize', { width: this.$store.state.app.width - 521, height: this.$store.state.app.height - 60 });
}
},
created() {
this.$store.dispatch('config/resize', { width: this.$store.state.app.width - 521, height: this.$store.state.app.height - 60 });
},
mounted() {
this.$refs.iscsPlate.show();
this.$refs.iscsPlate.drawIscsInit();
},
beforeDestroy() {
},
methods: {
iscsChange(stationCode) {
this.$refs.iscsPlate.show(stationCode);
this.$refs.iscsPlate.drawIscsInit();
}
}
};
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
@import "src/styles/mixin.scss";
.map-draft{
/deep/{
.v-modal{
opacity: 0;
}
}
}
.map-view {
float: left;
width: 60%;
}
.mapPaint{
height: 100%;
overflow: hidden;
}
.map-draft {
float: right;
width: 520px;
// /deep/ .el-scrollbar__view {
// width: 510px !important;
// height: calc(100% - 40px);
// }
}
</style>

View File

@ -0,0 +1,96 @@
<template>
<transition name="el-zoom-in-center">
<div class="map-control">
<el-card type="border-card">
<div slot="header" class="clearfix">
<span>{{ $t('ibp.stationName') }}</span>
<el-select v-model="stationCode" :placeholder="this.$t('rules.selectStation')" @change="changeStationCode">
<el-option
v-for="item in stationOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<el-button
type="text"
style="float: right; padding: 3px 0; margin-right: 5px;"
@click="handleSave"
>{{ $t('ibp.save') }}</el-button>
</div>
<el-tabs v-model="enabledTab" class="mapEdit" type="card" @tab-click="handleTabClick" />
</el-card>
</div>
</transition>
</template>
<script>
import {deviceFactory} from '@/iscs/utils/parser';
export default {
name: 'IscsOperate',
components: {
},
mixins: [
],
data() {
return {
enabledTab: 'Background',
data: '',
stationOptions:[
{
value: 'Station_203_0.07533',
label: '车站一'
},
{
value: 'Station_207_0.62282',
label: '车站二'
},
{
value: 'Station_209_0.95175',
label: '车站三'
}
],
stationCode: '',
height: this.$store.state.app.height - 190
};
},
watch: {
'$store.state.iscs.rightClickCount': function (val) {
const model = this.$store.getters['iscs/updateDeviceData'];
this.enabledTab = model._type;
}
},
mounted() {
},
beforeDestroy() {
},
methods: {
createDataModel(model) {
const newModel = deviceFactory(model._type, model);
this.$store.dispatch('iscs/updateIscsDevices', newModel.model);
},
deleteDataModel(model) {
this.$store.dispatch('iscs/deleteIscsDevices', model);
},
handleSave() {
const data = JSON.stringify(this.$store.state.iscs.iscs);
console.log(data);
},
changeStationCode(e) {
this.$emit('iscsChange', e);
this.handleTabClick();
},
handleTabClick() {
}
}
};
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
@import "src/styles/mixin.scss";
.map-control {
float: right;
width: 100%;
}
</style>