diff --git a/src/i18n/langs/en/router.js b/src/i18n/langs/en/router.js
index 4d3e0655b..23bf2da67 100644
--- a/src/i18n/langs/en/router.js
+++ b/src/i18n/langs/en/router.js
@@ -72,5 +72,6 @@ export default {
newsBulletin: 'New bulletin',
commandDictionary: 'Command dictionary',
configLine: 'Line management',
- deviceManage: 'Device management'
+ deviceManage: 'Device management',
+ iscsDraw: 'Iscs Draw'
};
diff --git a/src/i18n/langs/zh/router.js b/src/i18n/langs/zh/router.js
index 5438cb8c8..d8601ba75 100644
--- a/src/i18n/langs/zh/router.js
+++ b/src/i18n/langs/zh/router.js
@@ -73,5 +73,6 @@ export default {
newsBulletin: '消息公告',
commandDictionary: '指令字典',
configLine: '线路管理',
- deviceManage: '设备管理'
+ deviceManage: '设备管理',
+ iscsDraw: 'Iscs绘制'
};
diff --git a/src/iscs/constant/deviceRender.js b/src/iscs/constant/deviceRender.js
new file mode 100644
index 000000000..ea258d601
--- /dev/null
+++ b/src/iscs/constant/deviceRender.js
@@ -0,0 +1,76 @@
+import deviceType from './deviceType';
+
+const deviceRender = {};
+
+/** CheckBox渲染配置 */
+deviceRender[deviceType.CheckBox] = {
+ _type: deviceType.CheckBox,
+ zlevel: 10,
+ z: 0
+};
+/** 手动报警按钮渲染配置*/
+deviceRender[deviceType.ManualAlarmButton] = {
+ _type: deviceType.ManualAlarmButton,
+ zlevel: 1,
+ z: 4
+};
+/** 消火栓报警按钮渲染配置 */
+deviceRender[deviceType.FireHydranAlarmButton] = {
+ _type: deviceType.FireHydranAlarmButton,
+ zlevel: 1,
+ z: 4
+};
+/** 气体灭火渲染配置 */
+deviceRender[deviceType.GasFireControl] = {
+ _type: deviceType.GasFireControl,
+ zlevel: 1,
+ z: 4
+};
+/** 烟感探测器渲染配置 */
+deviceRender[deviceType.SmokeDetector] = {
+ _type: deviceType.SmokeDetector,
+ zlevel: 1,
+ z: 4
+};
+/** 温度探测器渲染配置 */
+deviceRender[deviceType.TemperatureDetector] = {
+ _type: deviceType.TemperatureDetector,
+ zlevel: 1,
+ z: 4
+};
+/** 屏蔽门渲染配置 */
+deviceRender[deviceType.PlatformScreenDoor] = {
+ _type: deviceType.PlatformScreenDoor,
+ zlevel: 1,
+ z: 4
+};
+
+/** FrozenPump渲染配置 */
+deviceRender[deviceType.FrozenPump] = {
+ _type: deviceType.FrozenPump,
+ zlevel: 10,
+ z: 0
+};
+
+/** IbpText渲染配置*/
+deviceRender[deviceType.Vidicon] = {
+ _type: deviceType.Vidicon,
+ zlevel: 1,
+ z: 4
+};
+
+/** VidiconCloud渲染配置*/
+deviceRender[deviceType.VidiconCloud] = {
+ _type: deviceType.VidiconCloud,
+ zlevel: 1,
+ z: 4
+};
+
+/** 端头门渲染配置*/
+deviceRender[deviceType.EndDoor] = {
+ _type: deviceType.EndDoor,
+ zlevel: 1,
+ z: 4
+};
+
+export default deviceRender;
diff --git a/src/iscs/constant/deviceType.js b/src/iscs/constant/deviceType.js
new file mode 100644
index 000000000..9247014fc
--- /dev/null
+++ b/src/iscs/constant/deviceType.js
@@ -0,0 +1,15 @@
+const deviceType = {
+ ManualAlarmButton: 'manualAlarmButton',
+ Vidicon: 'Vidicon',
+ VidiconCloud: 'VidiconCloud',
+ CheckBox: 'CheckBox',
+ FrozenPump:'FrozenPump',
+ FireHydranAlarmButton: 'fireHydranAlarmButton',
+ GasFireControl: 'gasFireControl',
+ SmokeDetector: 'smokeDetector',
+ TemperatureDetector: 'temperatureDetector',
+ PlatformScreenDoor: 'platformScreenDoor',
+ EndDoor: 'endDoor'
+};
+
+export default deviceType;
diff --git a/src/iscs/iscs.js b/src/iscs/iscs.js
new file mode 100644
index 000000000..29e6831c9
--- /dev/null
+++ b/src/iscs/iscs.js
@@ -0,0 +1,302 @@
+import zrender from 'zrender';
+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 { updateIscsData } from './utils/parser';
+
+const renderer = 'canvas';
+const devicePixelRatio = 1;
+
+class Iscs {
+ constructor(opts) {
+ this.methods = opts.methods;
+
+ // 鼠标事件
+ this.events = { __Pan: 'pan', Selected: 'selected', Contextmenu: 'contextmenu'};
+
+ // 设备数据
+ this.iscsDevice = {};
+
+ // 展示的画布大小
+ this.canvasSize = {};
+
+ this.initIscsPage(opts);
+ }
+ initIscsPage(opts) {
+ const width = opts.config.width;
+ const height = opts.config.height;
+ this.isAllowDragging = false;
+ 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.$iscsZr.getWidth(), height: this.$iscsZr.getHeight()});
+ this.$painter.updateTransform(this.$options, this.canvasSize);
+
+ this.optionsHandler = this.setOptions.bind(this);
+
+ this.$mouseController.on(this.events.__Pan, this.optionsHandler);
+ }
+
+ setIscs(config, iscsDevice) {
+ // 保存平移缩放数据
+ if (config.config) {
+ this.$options.scaleRate = config.scaling;
+ this.$options.offsetX = config.origin.x;
+ this.$options.offsetY = config.origin.y;
+ }
+
+ // 保存原始数据
+ this.data = config;
+
+ // 保存需展现的画布大小
+ this.canvasSize = {
+ x: 0,
+ y: 0,
+ width: config.width,
+ height: config.height
+ };
+
+ // 地图数据
+ this.iscsDevice = iscsDevice;
+
+ // 数据加载完成 回调
+ if (this.methods.dataLoaded instanceof Function) { this.methods.dataLoaded(this.iscsDevice); }
+
+ // 初次渲染视图
+ this.$painter.repaint(this.iscsDevice);
+
+ // 视图加载完成 回调
+ if (this.methods.viewLoaded instanceof Function) { this.methods.viewLoaded(this.iscsDevice); }
+
+ this.$painter.updateTransform(this.$options, this.canvasSize);
+ }
+
+ setDefaultState() {
+ const list = [];
+ Object.values(this.mapDevice).forEach(elem => {
+ const type = elem.model._type;
+ list.push(deviceFactory(type, Object.assign(elem.model, this.defaultStateDict[type]) ));
+ });
+
+ this.update(list);
+ if (this.methods.stateLoaded instanceof Function) { this.methods.stateLoaded(list); }
+ }
+
+ setOptions(opts) {
+ const options = this.pullBack(opts);
+ this.$options.update(options);
+ this.$painter.updateTransform(this.$options, this.canvasSize);
+
+ if (this.$options.disabled == true) {
+ this.$mouseController.disable();
+ } else {
+ this.$mouseController.enable(opts);
+ }
+
+ if (this.methods.optionsUpdate instanceof Function) { this.methods.optionsUpdate(this.$options); }
+ }
+
+ setCenter(deviceCode) {
+ const device = this.iscsDevice[deviceCode];
+ if (device && device.instance) {
+ var rect = createBoundingRect(device.instance);
+ var dcenter = calculateDCenter(rect, { width: this.$iscsZr.getWidth(), height: this.$iscsZr.getHeight() });
+ this.setOptions(dcenter);
+ }
+ }
+
+ setLevelVisible(list) {
+ this.$painter.setLevelVisible(list);
+ }
+
+ render(list) {
+ (list || []).forEach(elem => {
+ const code = elem.code;
+ const type = elem._type;
+ updateIscsData(elem);
+ const oDevice = this.iscsDevice[code] || deviceFactory(type, elem);
+ const nDevice = deviceFactory(type, Object.assign(oDevice.model || {}, elem));
+ delete this.iscsDevice[code];
+ this.$painter.delete(oDevice);
+ if (!elem._dispose) {
+ this.iscsDevice[code] = nDevice;
+ this.$painter.add(nDevice);
+ }
+ });
+ if (this.methods.viewUpdate instanceof Function) { this.methods.viewUpdate(list); }
+ }
+
+ // 中间处理
+ hookHandle(model, elem) {
+ const code = elem.code;
+ const type = elem._type;
+ // 如果是延时计时,需要保存计数值到全局
+ if (type === deviceType.StationCounter) {
+ let val = '' + elem.val;
+ if (val === '0' || !elem.val) {
+ val = elem.val = localStore.get(code) || '0';
+ }
+
+ localStore(code, val);
+ }
+ for (var prop in elem) {
+ if (elem[prop] != model[prop]) {
+ Object.assign(model, elem);
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ update(list) {
+ (list || []).forEach(elem => {
+ const code = elem.code;
+ const oDevice = this.iscsDevice[code];
+ if (elem.dispose) {
+ this.$painter.delete(oDevice);
+ } else {
+ if (this.hookHandle(oDevice.model, elem)) {
+ this.$painter.update(oDevice);
+ }
+ }
+ });
+
+ if (this.methods.stateUpdate instanceof Function) { this.methods.stateUpdate(list); }
+ }
+ setStatus(code, model) {
+ const oDevcie = this.iscsDevice[code].instance;
+ oDevcie.setStatus(model);
+ }
+ setDeviceStatus(list) {
+ const deviceList = Object.values(this.iscsDevice);
+ deviceList.forEach(elem =>{
+ (list || []).forEach(it =>{
+ if (elem.model.linkDevice === it.code) {
+ elem.instance.setStatus(it);
+ }
+ });
+ });
+
+ }
+ drawIscsInit() {
+ this.$mouseController.setAllowDragging(true);
+ }
+
+ pullBack(payload) {
+ if (payload.type === 'zoom') {
+ 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;
+ const y = (this.$options.offsetY + originY) / this.$options.scaleRate;
+ const newScaleRate = this.$options.getScaleRate(payload.scale);
+ const dx = originX - (x * newScaleRate - this.$options.offsetX);
+ const dy = originY - (y * newScaleRate - this.$options.offsetY);
+ payload.dx = dx;
+ payload.dy = dy;
+ }
+
+ return payload || {};
+ }
+
+ getZr() {
+ return this.$iscsZr;
+ }
+
+ getEvents() {
+ return this.events;
+ }
+
+ getDeviceByCode(code) {
+ return this.iscsDevice[code];
+ }
+
+ resize(opt) {
+ this.$iscsZr.resize(opt);
+ this.$painter.updateZrSize(opt);
+ }
+
+ refresh() {
+ this.$painter.refresh();
+ }
+ clear() {
+ this.skinCode = '';
+ this.style = {};
+ this.iscsDevice = {};
+ this.$painter.clear();
+ }
+ dispose() {
+ this.off(this.events.Pan, this.optionsHandler);
+ this.off(this.events.Zoom, this.optionsHandler);
+
+ this.clear();
+
+ this.$mouseController.dispose();
+ this.$iscsZr && zrender.dispose(this.$iscsZr);
+ this.$painter.dispose();
+ }
+
+ on(eventname, cb, context) {
+ 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;
+ }
+ }
+ }
+
+ off(eventname, cb) {
+ 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;
+ }
+ }
+ }
+
+ renderCheckBox(model) {
+ const type = model._type;
+ const code = model.code;
+ const oDevice = this.iscsDevice[code] || deviceFactory(type, model);
+ const nDevice = deviceFactory(type, Object.assign(oDevice.model || {}, model));
+ delete this.iscsDevice[code];
+ this.$painter.delete(oDevice);
+ if (!model._dispose) {
+ this.iscsDevice[code] = nDevice;
+ this.$painter.add(nDevice);
+ }
+ }
+ deleteCheckBox(code) {
+ const oDevice = this.iscsDevice[code];
+ if (oDevice) {
+ delete this.iscsDevice[code];
+ this.$painter.delete(oDevice);
+ }
+ }
+}
+export default Iscs;
diff --git a/src/iscs/mouseController.js b/src/iscs/mouseController.js
new file mode 100644
index 000000000..f433ca155
--- /dev/null
+++ b/src/iscs/mouseController.js
@@ -0,0 +1,285 @@
+import deviceType from './constant/deviceType';
+import Eventful from 'zrender/src/mixin/Eventful';
+import * as eventTool from 'zrender/src/core/event';
+import store from '@/store';
+
+class EventModel {
+ constructor(e) {
+ this.clientX = e.event.clientX;
+ this.clientY = e.event.clientY;
+
+ let view = e.target;
+ while (view) {
+ if (Object.values(deviceType).includes(view._type)) {
+ this.deviceCode = view._code;
+ this.deviceType = view._type;
+ this.deviceModel = view.model;
+ this.eventTarget = view;
+ break;
+ }
+ view = view.parent;
+ }
+ }
+}
+
+class MouseController extends Eventful {
+ constructor(iscs) {
+ super();
+ this.$iscs = iscs;
+ this.$zr = iscs.getZr();
+ this.isAllowDragging = iscs.isAllowDragging || false; // 是否在绘图中,仅绘图状态下可拖拽
+ this.events = iscs.getEvents();
+ this._dragging = false; // 是否在拖拽状态
+ this.deviceList = [];
+ this.rightClickPoint = {
+ x: 0,
+ y: 0
+ }; // 右键点击坐标
+ this.initHandler(this.$zr);
+ }
+
+ initHandler(zr) {
+ if (zr) {
+ zr.on('contextmenu', this.contextmenu, this);
+ zr.on('mousemove', this.moveEvent, this);
+ zr.on('click', this.click, this);
+
+ this.enable = function (opts) {
+ opts = opts || {};
+ this._moveOnMouseMove = opts.moveOnMouseMove || true;
+ this._preventDefaultMouseMove = opts.preventDefaultMouseMove || true;
+
+ this.disable();
+
+ zr.on('mousedown', this.mousedown, this);
+ zr.on('mousemove', this.mousemove, this);
+ zr.on('mouseup', this.mouseup, this);
+ zr.on('touchstart', this.mousedown, this);
+ zr.on('touchmove', this.mousemove, this);
+ zr.on('touchend', this.mouseup, this);
+ };
+
+ this.disable = function () {
+ zr.off('mousedown', this.mousedown);
+ zr.off('mousemove', this.mousemove);
+ zr.off('mouseup', this.mouseup);
+ zr.off('touchstart', this.mousedown);
+ zr.off('touchmove', this.mousemove);
+ zr.off('touchend', this.mouseup);
+ };
+
+ this.dispose = function () {
+ zr.off('click', this.click);
+ zr.off('contextmenu', this.contextmenu);
+ zr.off('mousemove', this.moveEvent);
+ this.disable();
+ };
+
+ this.isDragging = function () { return this._dragging; };
+ }
+ }
+
+ setAllowDragging(data) {
+ this.isAllowDragging = data;
+ }
+
+ mousedown(e) {
+ e.event.preventDefault();
+ e.event.stopPropagation();
+ const em = new EventModel(e);
+ this.eventTarget = em.eventTarget;
+ this._offsetX = e.offsetX;
+ this._offsetY = e.offsetY;
+ this._x = e.offsetX;
+ this._y = e.offsetY;
+ this._dragging = true;
+ if (e.which === 3) {
+ this.handleMouseDownRight(e);
+ } else if (e.which === 1) {
+ this.handleMouseDownLeft(e);
+ } else if (e.which === 2) {
+ this.handleMouseDownWheel(e);
+ }
+ }
+
+ mousemove(e) {
+ const oldX = this._x;
+ const oldY = this._y;
+
+ const dx = e.offsetX - oldX;
+ const dy = e.offsetY - oldY;
+
+ this._x = e.offsetX;
+ this._y = e.offsetY;
+ if (e.which === 3) {
+ this.handleMouseMoveRight({x: e.offsetX, y: e.offsetY});
+ } else if (e.which === 1) {
+ this.handleMouseMoveLeft(e, dx, dy, oldX, oldY);
+ }
+ }
+
+ mouseup(e) {
+ if (eventTool.notLeftMouse(e) || !this.eventTarget ) {
+ return;
+ }
+ if (this.deviceList.length) {
+ this.deviceList.forEach(item => {
+ item.setModel(e.offsetX - this._offsetX, e.offsetY - this._offsetY);
+ });
+ this.deviceList = [];
+ this.$iscs.deleteCheckBox('check_box');
+ this.eventTarget = '';
+ this._dragging = false;
+ this.deviceList = [];
+ return;
+ }
+ if (this.isAllowDragging) {
+ this.eventTarget.setModel(e.offsetX - this._offsetX, e.offsetY - this._offsetY);
+ this.eventTarget.dirty();
+ }
+ if (this.eventTarget._type === deviceType.Background) {
+ this.eventTarget.setCursor('default');
+ }
+ this.eventTarget = '';
+ this._dragging = false;
+ this.deviceList = [];
+ }
+
+ contextmenu(e) {
+ var em = this.checkEvent(e);
+ this.trigger(this.events.Contextmenu, em);
+ }
+ click(e) {
+ var em = this.checkEvent(e);
+ this.trigger(this.events.Selected, em);
+ }
+ moveEvent(e) {
+ const newEm = new EventModel(e);
+ const trainDetails = store.state.map.trainDetails;
+ if (trainDetails) {
+ if (newEm.deviceType != deviceType.Train || trainDetails.code != newEm.deviceCode) {
+ var instance = (this.$iscs.getDeviceByCode(trainDetails.code) || {} ).instance;
+ instance && instance.removeTrainDetail && instance.removeTrainDetail();
+ }
+ }
+ }
+
+ checkEvent(e) {
+ var oldEm = new EventModel(this.$zr.curEvent || { event: {} });
+ var newEm = new EventModel(e);
+ if ([1, 3].includes(e.which)) {
+ // 查找之前和当前鼠标选中的实例
+ 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) {
+ // 如果实例有取消选择函数并且被点击,则执行取消选中函数
+ if (oldInstance.mouseEvent && oldInstance.mouseEvent.mouseout) {
+ // 视图数据设置点击标志,同步执行
+ oldDevice['down'] = false;
+ oldInstance.mouseEvent['mouseout'](e);
+ }
+
+ // 如果实例有选中函数并且被点击,则执行选中函数
+ if (e.which == 3 && newInstance.mouseEvent && newInstance.mouseEvent.mouseover) {
+ newDevice['down'] = true;
+ newInstance.mouseEvent['mouseover'](e);
+ }
+ }
+
+ // 保存当前实例到全局
+ this.$zr.curEvent = e;
+ }
+
+ return newEm;
+ }
+ /** 处理鼠标右键按下事件 */
+ handleMouseDownRight(e) {
+ this.rightClickPoint.x = e.offsetX;
+ this.rightClickPoint.y = e.offsetY;
+ }
+ /** 处理鼠标左键按下事件 */
+ handleMouseDownLeft(e) {
+ if (this.eventTarget && this.eventTarget._type === deviceType.Background) {
+ this.eventTarget.setCursor('pointer');
+ this.$iscs.deleteCheckBox('check_box');
+ } else if (this.eventTarget && this.eventTarget._type === deviceType.CheckBox) {
+ this.handleBoundingRect(this.eventTarget);
+ } else {
+ this.$iscs.deleteCheckBox('check_box');
+ }
+ }
+ /** 处理滚轮按下事件 */
+ handleMouseDownWheel(e) {
+ this.deviceList = [];
+ Object.values(this.$iscs.iscsDevice).forEach(item => {
+ if (item.instance._type !== deviceType.Background) {
+ this.deviceList.push(item.instance);
+ }
+ });
+ }
+ /** 处理右键拖动事件--- 改变选中区域大小 */
+ handleMouseMoveRight(point2) {
+ const point1 = this.rightClickPoint;
+ 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.$iscs.renderCheckBox({code: 'check_box', _type: 'CheckBox', point: {x: x, y: y}, width: width, height: height });
+ }
+ /** 处理左键拖动事件--- 图形移动 */
+ handleMouseMoveLeft(e, dx, dy, oldX, oldY) {
+ if (!this._moveOnMouseMove || !this._dragging || !this.isAllowDragging) {
+ return;
+ }
+ // 选中区域图形移动
+ if (this.deviceList.length) {
+ this.deviceList.forEach(item => {
+ item.grouper.drift(dx, dy, e);
+ });
+ } else if (this._dragging && this.eventTarget) { // 选中元素图形移动
+ if (( this.eventTarget._type === deviceType.Background) || !this.isAllowDragging) {
+ this._preventDefaultMouseMove && eventTool.stop(e.event);
+ this.trigger(this.events.__Pan, { dx, dy, oldX, oldY, newX: this._x, newY: this._y });
+ } else if (this.isAllowDragging) {
+ this.eventTarget.grouper.drift(dx, dy, e);
+ }
+ }
+ }
+ /** 通过包围盒筛选选中区域的元素 */
+ handleBoundingRect(eventTarget) {
+ this.deviceList = [];
+ let boundingRect = eventTarget.grouper.getBoundingRect();
+ boundingRect = this.createFakeBoundingRect(eventTarget, boundingRect);
+ const deviceList = Object.values(this.$iscs.iscsDevice);
+ const includeDeviceList = [];
+ deviceList.forEach( item =>{
+ if (item.instance._type !== deviceType.Background) {
+ let deviceBoundingRect = item.instance.grouper.getBoundingRect();
+ deviceBoundingRect = this.createFakeBoundingRect(item.instance, deviceBoundingRect);
+ if (this.whetherInclude(boundingRect, deviceBoundingRect )) {
+ includeDeviceList.push(item.instance);
+ }
+ }
+ });
+ this.deviceList = includeDeviceList;
+ }
+ /** 创建假包围盒对象 */
+ createFakeBoundingRect(instance, boundingRect) {
+ return {
+ x1: instance.model.point.x + boundingRect.x,
+ y1: instance.model.point.y + boundingRect.y,
+ x2: instance.model.point.x + boundingRect.width,
+ y2: instance.model.point.y + boundingRect.height
+ };
+ }
+ /** 判断元素包围盒是否在选中区域 */
+ whetherInclude(boundingRect1, boundingRect2) {
+ return boundingRect1.x1 <= boundingRect2.x1 && boundingRect1.y1 <= boundingRect2.y1 && boundingRect1.x2 >= boundingRect2.x2 && boundingRect1.y2 >= boundingRect2.y2;
+ }
+}
+
+export default MouseController;
diff --git a/src/iscs/options.js b/src/iscs/options.js
new file mode 100644
index 000000000..77ba4576e
--- /dev/null
+++ b/src/iscs/options.js
@@ -0,0 +1,100 @@
+class Options {
+ constructor(opts, trigger) {
+ this.scaleIndex = 0;
+ this.scaleList = [
+ 0.5, 0.6, 0.7, 0.8, 0.9,
+ 1, 1.2, 1.4, 1.6, 1.8,
+ 2, 2.2, 2.4, 2.6, 2.8,
+ 3, 3.2, 3.4, 3.6, 3.8,
+ 4, 4.2, 4.4, 4.6, 4.8,
+ 5, 5.2, 5.4, 5.6, 5.8,
+ 6, 6.2, 6.4, 6.6, 6.8,
+ 7, 7.2, 7.4, 7.6, 7.8,
+ 8, 8.2, 8.4, 8.6, 8.8
+ ];
+
+ if (Number.isFinite(opts.scaleRate)) {
+ const idx = this.scaleList.indexOf(opts.scaleRate);
+ if (idx >= 0) {
+ this.scaleIndex = idx;
+ }
+ }
+
+ this.scaleRate = opts.scaleRate || this.scaleList[this.scaleIndex]; // 缩放比例
+
+ this.offsetX = opts.offsetX || 0; // x偏移
+
+ this.offsetY = opts.offsetY || 0; // y偏移
+
+ this.throttle = opts.throttle || 100; // 刷新频率
+
+ this.disabled = false;
+
+ this.moveOnMouseMove = true;
+
+ this.zoomOnMouseWheel = false;
+
+ this.preventDefaultMouseMove = true;
+
+ this.trigger = trigger;
+ }
+
+ update(payload) {
+ if (Number.isFinite(payload.dx)) {
+ this.offsetX -= payload.dx;
+ }
+ if (Number.isFinite(payload.dy)) {
+ this.offsetY -= payload.dy;
+ }
+
+ if (Number.isFinite(payload.offsetX)) {
+ this.offsetX = payload.offsetX;
+ }
+ if (Number.isFinite(payload.offsetY)) {
+ this.offsetY = payload.offsetY;
+ }
+
+ if (Number.isFinite(payload.scale)) {
+ if (Number.isFinite(payload.scale)) {
+ if ((this.scaleIndex + payload.scale) >= 0 && (this.scaleIndex + payload.scale) < this.scaleList.length) {
+ this.scaleIndex = this.scaleIndex + payload.scale;
+ }
+ }
+ this.scaleRate = this.scaleList[this.scaleIndex];
+ }
+
+ if (Number.isFinite(payload.scaleRate)) {
+ const idx = this.scaleList.indexOf(payload.scaleRate);
+ if (idx < 0) {
+ return;
+ }
+ this.scaleIndex = idx;
+ this.scaleRate = payload.scaleRate;
+ }
+
+ if (payload.disabled === true || payload.disabled === false) {
+ this.disabled = payload.disabled;
+ }
+
+ if (payload.moveOnMouseMove === true || payload.moveOnMouseMove === false) {
+ this.moveOnMouseMove = payload.moveOnMouseMove;
+ }
+
+ if (payload.zoomOnMouseWheel === true || payload.zoomOnMouseWheel === false) {
+ this.zoomOnMouseWheel = payload.zoomOnMouseWheel;
+ }
+
+ if (this.trigger instanceof Function) { this.trigger(this); }
+ }
+
+ getScaleRate(scale) {
+ if (Number.isFinite(scale)) {
+ if ((this.scaleIndex + scale) >= 0 && (this.scaleIndex + scale) < this.scaleList.length) {
+ return this.scaleList[this.scaleIndex + scale];
+ }
+ }
+ return this.scaleList[this.scaleIndex];
+ }
+}
+
+export default Options;
diff --git a/src/iscs/painter.js b/src/iscs/painter.js
new file mode 100644
index 000000000..0bbf14f1e
--- /dev/null
+++ b/src/iscs/painter.js
@@ -0,0 +1,179 @@
+import * as zrUtil from 'zrender/src/core/util';
+// import * as vector from 'zrender/src/core/vector';
+import Group from 'zrender/src/container/Group';
+import deviceType from './constant/deviceType';
+import shapefactory from './shape/factory';
+import TransformHandle from './transformHandle';
+
+class Painter {
+ constructor(iscs) {
+ // 父级实例
+ this.$iscs = iscs;
+ this.$iscsZr = iscs.getZr();
+
+ // 图层数据
+ this.iscsInstanceLevel = {};
+
+ // 初始图层
+ this.initLevels();
+
+ // 视图控制器
+ this.$transformHandle = new TransformHandle(this);
+ }
+
+ /**
+ * 初始绘图实例
+ * @param {*} dom
+ * @param {*} config
+ */
+ initLevels() {
+
+ // 添加父级图层
+ this.parentLevel = new Group({ name: '__parent__' });
+ this.$iscsZr.add(this.parentLevel);
+
+ // 添加子级图层
+ zrUtil.each(Object.values(deviceType), (type) => {
+ const level = new Group({ name: `__${type}__` });
+ this.iscsInstanceLevel[type] = level;
+ this.parentLevel.add(level);
+ });
+ }
+
+ /**
+ * 重绘视图
+ * @param {*} iscsDevice
+ */
+ repaint(iscsDevice) {
+ // 清空视图
+ this.clear();
+
+ // 创建视图
+ Object.values(iscsDevice).forEach(device => {
+ this.add(device);
+ });
+ }
+
+ /**
+ * 添加视图
+ * @param {*} device
+ */
+ add(device) {
+ try {
+ device = Object.assign(device, { event: this.$iscs.$mouseController });
+ const instance = shapefactory(device, this.$iscs);
+ if (instance) {
+ device.instance = instance;
+ this.$transformHandle.transformView(instance);
+ this.iscsInstanceLevel[device.model._type].add(instance);
+ }
+ } catch (error) {
+ console.error(error);
+ }
+ }
+
+ /**
+ * 删除视图
+ * @param {*} device
+ */
+ delete(device) {
+ const instance = device.instance;
+ if (instance) {
+ this.iscsInstanceLevel[device.model._type].remove(instance);
+ }
+ }
+
+ /**
+ * 更新视图
+ * @param {*} device
+ */
+ update(device) {
+ if (device) {
+ if (device.model._dispose) {
+ this.delete(device);
+ } else {
+ const instance = device.instance;
+ if (instance) {
+ instance.setState(device);
+ }
+ }
+ }
+ }
+
+ /**
+ * 更新transform变化
+ * @param {*} opt
+ */
+ updateTransform(opt, canvasSize) {
+ this.$transformHandle.updateTransform(opt, canvasSize);
+ }
+
+ /**
+ * 更新zrender尺寸
+ * @param {*} opt
+ */
+ updateZrSize(opt) {
+ this.$transformHandle.updateZrSize(opt);
+ }
+
+ /**
+ * 设置图层可见
+ * @param {*} code
+ */
+ setLevelVisible(list) {
+ zrUtil.each(Object.values(deviceType), type => {
+ const level = this.iscsInstanceLevel[type];
+ if (list.includes(type)) {
+ level.show();
+ } else {
+ level.hide();
+ }
+ }, this);
+ }
+
+ /**
+ * 刷新图层
+ */
+ refresh() {
+ this.$iscsZr.refresh();
+ }
+
+ /**
+ * 清除图层
+ */
+ clearLevel(type) {
+ const level = this.iscsInstanceLevel[type];
+ if (level) {
+ level.removeAll();
+ }
+ }
+
+ /**
+ * 清除canvas
+ */
+ clear() {
+ zrUtil.each(Object.values(this.iscsInstanceLevel), (level) => {
+ level && level.removeAll();
+ }, this);
+
+ this.refresh();
+ }
+
+ /**
+ * 销毁图层
+ */
+ dispose() {
+ this.iscsInstanceLevel = {};
+ this.parentLevel = null;
+ }
+
+ /**
+ * 父级图层
+ */
+ getParentLevel() {
+ return this.parentLevel;
+ }
+
+}
+
+export default Painter;
diff --git a/src/iscs/shape/Vidicon.js b/src/iscs/shape/Vidicon.js
new file mode 100644
index 000000000..f90edb516
--- /dev/null
+++ b/src/iscs/shape/Vidicon.js
@@ -0,0 +1,87 @@
+import Group from 'zrender/src/container/Group';
+import Rect from 'zrender/src/graphic/shape/Rect';
+import Polyline from 'zrender/src/graphic/shape/Polyline';
+
+export default class Vidicon 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() {
+ console.log(this.model);
+ this.grouper = new Group({
+ id: this.model.code,
+ position: [this.model.point.x, this.model.point.y]
+ });
+ const vidiconHeight = this.model.width / 2.5;
+ 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: vidiconHeight,
+ r: [1, 1, 1, 1]
+ },
+ style: {
+ fill: '#00FF00'
+ }
+ });
+ const shotWidth = this.model.width / 5; // 镜头宽度
+ const shotHeight = vidiconHeight / 2; // 镜头高度
+ if (this.model.right) { // 镜头在右
+ this.PolylineRight = new Polyline({
+ zlevel: this.model.zlevel,
+ z: this.model.z + 1,
+ shape: {
+ points: [
+ [this.model.point.x + this.model.width, this.model.point.y + 3],
+ [this.model.point.x + this.model.width + shotWidth, this.model.point.y],
+ [this.model.point.x + this.model.width + shotWidth, this.model.point.y + 6 + shotHeight],
+ [this.model.point.x + this.model.width, this.model.point.y + 3 + shotHeight]
+ ],
+ smooth: 0.2
+ },
+ style: {
+ fill: '#00FF00'
+ }
+ });
+ } else { // 镜头在左
+ this.PolylineLeft = new Polyline({
+ zlevel: this.model.zlevel,
+ z: this.model.z + 1,
+ shape: {
+ points: [
+ [this.model.point.x, this.model.point.y + vidiconHeight - 3],
+ [this.model.point.x - shotWidth, this.model.point.y + vidiconHeight],
+ [this.model.point.x - shotWidth, this.model.point.y + vidiconHeight - 6 - shotHeight],
+ [this.model.point.x, this.model.point.y + vidiconHeight - 3 - shotHeight]
+ ],
+ smooth: 0.2
+ },
+ style: {
+ fill: '#00FF00'
+ }
+ });
+ }
+
+ this.grouper.add(this.rect);
+ if (this.model.right) {
+ this.grouper.add(this.PolylineRight);
+ } else {
+ this.grouper.add(this.PolylineLeft);
+ }
+ this.add(this.grouper);
+ }
+
+ setModel(dx, dy) {
+ this.model.point.x += dx;
+ this.model.point.y += dy;
+ }
+}
diff --git a/src/iscs/shape/VidiconCloud.js b/src/iscs/shape/VidiconCloud.js
new file mode 100644
index 000000000..ce9604134
--- /dev/null
+++ b/src/iscs/shape/VidiconCloud.js
@@ -0,0 +1,66 @@
+import Group from 'zrender/src/container/Group';
+import Sector from 'zrender/src/graphic/shape/Sector';
+import Polyline from 'zrender/src/graphic/shape/Polyline';
+
+export default class VidiconCloud 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() {
+ console.log(this.model, Math.cos(45 * (Math.PI / 180)));
+ this.grouper = new Group({
+ id: this.model.code,
+ position: [this.model.point.x, this.model.point.y]
+ });
+ this.semicircle = new Sector({
+ zlevel: this.model.zlevel,
+ z: this.model.z,
+ shape: {
+ cx: this.model.point.x,
+ cy: this.model.point.y,
+ r: this.model.r || 30,
+ startAngle: 0,
+ endAngle: Math.PI,
+ clockwise: true
+ },
+ style: {
+ stroke: '#00FF00',
+ lineWidth: 2,
+ fill: 'rgba(0,0,0,0)'
+ }
+ });
+
+ this.Polyline = new Polyline({
+ zlevel: this.model.zlevel,
+ z: this.model.z + 1,
+ shape: {
+ points: [
+ [this.model.point.x + this.model.r / 2, this.model.point.y],
+ [this.model.point.x - Math.cos(45 * (Math.PI / 180)) * this.model.r, this.model.point.y + Math.sin(45 * (Math.PI / 180)) * this.model.r],
+ [this.model.point.x - Math.cos(55 * (Math.PI / 180)) * this.model.r, this.model.point.y + Math.sin(55 * (Math.PI / 180)) * this.model.r],
+ [this.model.point.x + this.model.r / 1.2, this.model.point.y]
+ ]
+ },
+ style: {
+ stroke: '#00FF00',
+ lineWidth: 2,
+ fill: '#00FF00'
+ }
+ });
+
+ this.grouper.add(this.semicircle);
+ this.grouper.add(this.Polyline);
+ this.add(this.grouper);
+ }
+
+ setModel(dx, dy) {
+ this.model.point.x += dx;
+ this.model.point.y += dy;
+ }
+}
diff --git a/src/iscs/shape/checkBox.js b/src/iscs/shape/checkBox.js
new file mode 100644
index 000000000..0299ada99
--- /dev/null
+++ b/src/iscs/shape/checkBox.js
@@ -0,0 +1,46 @@
+import Group from 'zrender/src/container/Group';
+import Rect from 'zrender/src/graphic/shape/Rect';
+
+export default class checkBox 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.z;
+ this.create();
+ }
+
+ create() {
+ const model = this.model;
+ this.grouper = new Group({
+ id: model.code,
+ position: [model.point.x, model.point.y]
+ });
+ this.box = new Rect({
+ zlevel: model.zlevel,
+ z: model.z,
+ draggable: false,
+ shape: {
+ x: 0,
+ y: 0,
+ width: this.model.width,
+ height: this.model.height
+ },
+ style: {
+ fill: 'rgb(135,206,250,0.2)'
+ }
+ });
+ this.grouper.add(this.box);
+ this.add(this.grouper);
+ }
+ setModel(dx, dy) {
+ this.model.point.x += dx;
+ this.model.point.y += dy;
+ }
+ setSize(width, height) {
+ this.model.width = width;
+ this.model.height = height;
+ }
+}
diff --git a/src/iscs/shape/endDoor.js b/src/iscs/shape/endDoor.js
new file mode 100644
index 000000000..d713e0bdb
--- /dev/null
+++ b/src/iscs/shape/endDoor.js
@@ -0,0 +1,67 @@
+import Group from 'zrender/src/container/Group';
+import Rect from 'zrender/src/graphic/shape/Rect';
+import Circle from 'zrender/src/graphic/shape/Circle';
+
+export default class EndDoor extends Group {
+ constructor(device) {
+ super();
+ this.model = device.model;
+ this.zlevel = device.model.zlevel;
+ this.z = device.model.z;
+ this._type = device.model._type;
+ this._code = device.model.code;
+ this.create();
+ }
+ create() {
+ this.grouper = new Group({
+ id: this.model.code,
+ position: [this.model.point.x, this.model.point.y]
+ });
+ this.add(this.grouper);
+ this.door = new Rect({
+ zlevel: this.zlevel,
+ z: this.z,
+ shape: {
+ x: 0,
+ y: 0,
+ width: this.model.width,
+ height: this.model.width * 29 / 17
+ },
+ style: {
+ fill: '#33CC00'
+ }
+ });
+ this.doorWindow = new Rect({
+ zlevel: this.zlevel,
+ z: this.z,
+ shape: {
+ x: this.model.width * 2 / 17,
+ y: this.model.width * 6 / 17,
+ width: this.model.width * 13 / 17,
+ height: this.model.width * 4 / 17
+ },
+ style: {
+ fill: '#000'
+ }
+ });
+ this.doorknob = new Circle({
+ zlevel: this.zlevel,
+ z: this.z,
+ shape: {
+ cx: this.model.width * 13 / 17,
+ cy: this.model.width * 21 / 17,
+ r: this.model.width / 17
+ },
+ style: {
+ fill: '#000'
+ }
+ });
+ this.grouper.add(this.door);
+ this.grouper.add(this.doorWindow);
+ this.grouper.add(this.doorknob);
+ }
+ setModel(dx, dy) {
+ this.model.point.x += dx;
+ this.model.point.y += dy;
+ }
+}
diff --git a/src/iscs/shape/factory.js b/src/iscs/shape/factory.js
new file mode 100644
index 000000000..f9a8fdfbe
--- /dev/null
+++ b/src/iscs/shape/factory.js
@@ -0,0 +1,36 @@
+import ManualAlarmButton from './manualAlarmButton';
+import Vidicon from './Vidicon';
+import VidiconCloud from './VidiconCloud';
+import deviceType from '../constant/deviceType';
+import CheckBox from './checkBox';
+import FrozenPump from './frozenPump';
+import FireHydranAlarmButton from './fireHydrantAlarmButton';
+import GasFireControl from './gasFireControl';
+import SmokeDetector from './smokeDetector';
+import TemperatureDetector from './temperatureDetector';
+import PlatformScreenDoor from './psd/platformScreenDoor';
+import EndDoor from './endDoor';
+
+const iscsShape = {};
+iscsShape[deviceType.ManualAlarmButton] = ManualAlarmButton;
+iscsShape[deviceType.Vidicon] = Vidicon;
+iscsShape[deviceType.VidiconCloud] = VidiconCloud;
+iscsShape[deviceType.CheckBox] = CheckBox;
+iscsShape[deviceType.FrozenPump] = FrozenPump;
+iscsShape[deviceType.FireHydranAlarmButton] = FireHydranAlarmButton;
+iscsShape[deviceType.GasFireControl] = GasFireControl;
+iscsShape[deviceType.SmokeDetector] = SmokeDetector;
+iscsShape[deviceType.TemperatureDetector] = TemperatureDetector;
+iscsShape[deviceType.PlatformScreenDoor] = PlatformScreenDoor;
+iscsShape[deviceType.EndDoor] = EndDoor;
+
+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;
diff --git a/src/iscs/shape/fireHydrantAlarmButton.js b/src/iscs/shape/fireHydrantAlarmButton.js
new file mode 100644
index 000000000..df6434c19
--- /dev/null
+++ b/src/iscs/shape/fireHydrantAlarmButton.js
@@ -0,0 +1,63 @@
+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.grouper = new Group({
+ id: this.model.code,
+ position: [this.model.point.x, this.model.point.y]
+ });
+ this.add(this.grouper);
+ this.rect = new Rect({
+ zlevel: this.zlevel,
+ z: this.z,
+ shape: {
+ x: 0,
+ y: 0,
+ width: this.model.width,
+ height: this.model.width / 2
+ },
+ style: {
+ fill: '#0f0'
+ }
+ });
+ this.grouper.add(this.rect);
+ const width = this.model.width;
+ this.polygonTop = new Polygon({
+ zlevel: this.zlevel,
+ z: this.z,
+ shape: {
+ points: [[width / 4, width * 3 / 40], [width * 3 / 4, width * 3 / 40], [width * 3 / 5, width * 5 / 20], [width * 2 / 5, width * 5 / 20]]
+ },
+ style: {
+ color: '#000'
+ }
+ });
+ this.polygonBottom = new Polygon({
+ zlevel: this.zlevel,
+ z: this.z,
+ shape: {
+ points: [[width * 2 / 5, width * 3 / 10], [width * 3 / 5, width * 3 / 10], [width * 13 / 20, width * 2 / 5], [width * 7 / 20, width * 2 / 5]]
+ },
+ style: {
+ color: '#000'
+ }
+ });
+ this.grouper.add(this.polygonTop);
+ this.grouper.add(this.polygonBottom);
+ }
+ setModel(dx, dy) {
+ this.model.point.x += dx;
+ this.model.point.y += dy;
+ }
+}
diff --git a/src/iscs/shape/frozenPump.js b/src/iscs/shape/frozenPump.js
new file mode 100644
index 000000000..8ef266d43
--- /dev/null
+++ b/src/iscs/shape/frozenPump.js
@@ -0,0 +1,56 @@
+import Group from 'zrender/src/container/Group';
+import Circle from 'zrender/src/graphic/shape/Circle';
+import Polygon from 'zrender/src/graphic/shape/Polygon';
+export default class frozenPump 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.grouper = new Group({
+ id: this.model.code,
+ position: [this.model.point.x, this.model.point.y]
+ });
+ this.circleOutside = new Circle({
+ zlevel: this.model.zlevel,
+ z: this.model.z,
+ shape: {
+ cx: this.model.width / 2,
+ cy: this.model.width / 2,
+ r: this.model.width / 2
+ },
+ style: {
+ stroke: this.model.strokeColor,
+ lineWidth:2
+ }
+ });
+ this.triangle = new Polygon({
+ zlevel: this.model.zlevel,
+ z: this.model.z,
+ shape:{
+ points:[
+ [this.model.width / 4, this.model.width / 2 * 0.133975],
+ [this.model.width / 4, this.model.width / 2 * 1.866025],
+ [this.model.width, this.model.width / 2],
+ [this.model.width / 4, this.model.width / 2 * 0.133975]
+ ]
+ },
+ style: {
+ fill: this.model.strokeColor,
+ stroke:this.model.strokeColor
+ }
+ });
+ this.grouper.add(this.circleOutside);
+ this.grouper.add(this.triangle);
+ this.add(this.grouper);
+ }
+ setModel(dx, dy) {
+ this.model.point.x += dx;
+ this.model.point.y += dy;
+ }
+}
diff --git a/src/iscs/shape/gasFireControl.js b/src/iscs/shape/gasFireControl.js
new file mode 100644
index 000000000..499c72fa4
--- /dev/null
+++ b/src/iscs/shape/gasFireControl.js
@@ -0,0 +1,84 @@
+import Group from 'zrender/src/container/Group';
+import Rect from 'zrender/src/graphic/shape/Rect';
+import Isogon from 'zrender/src/graphic/shape/Isogon';
+import Circle from 'zrender/src/graphic/shape/Circle';
+
+export default class GasFireControl extends Group {
+ constructor(device) {
+ super();
+ this.model = device.model;
+ this.zlevel = device.model.zlevel;
+ this.z = device.z;
+ this._type = device.model._type;
+ this._code = device.model.code;
+ this.create();
+ }
+ create() {
+ this.grouper = new Group({
+ id: this.model.code,
+ position: [this.model.point.x, this.model.point.y]
+ });
+ this.add(this.grouper);
+ this.rect = new Rect({
+ zlevel: this.zlevel,
+ z: this.z,
+ shape: {
+ x: 0,
+ y: 0,
+ width: this.model.width,
+ height: this.model.width
+ },
+ style: {
+ lineWidth: 1,
+ stroke: '#0F0'
+ }
+ });
+ this.grouper.add(this.rect);
+ this.isogon = new Isogon({
+ zlevel: this.zlevel,
+ z: this.z,
+ shape: {
+ x: this.model.width / 3,
+ y: this.model.width / 2,
+ r: this.model.width / 4,
+ n: 3
+ },
+ style: {
+ fill: '#0F0'
+ }
+ });
+ this.isogon.origin = [this.model.width / 3, this.model.width / 2];
+ this.isogon.rotation = Math.PI / 180 * Number(90);
+ this.grouper.add(this.isogon);
+ this.circleTop = new Circle({
+ zlevel: this.zlevel,
+ z: this.z,
+ shape: {
+ cx: this.model.width * 2 / 3,
+ cy: this.model.width / 4,
+ r: this.model.width / 12
+ },
+ style: {
+ fill: '#0F0'
+ }
+ });
+ this.circleBottom = new Circle({
+ zlevel: this.zlevel,
+ z: this.z,
+ shape: {
+ cx: this.model.width * 2 / 3,
+ cy: this.model.width * 3 / 4,
+ r: this.model.width / 12
+ },
+ style: {
+ fill: '#0F0'
+ }
+ });
+ this.grouper.add(this.circleTop);
+ this.grouper.add(this.circleBottom);
+ }
+ setModel(dx, dy) {
+ this.model.point.x += dx;
+ this.model.point.y += dy;
+ }
+}
diff --git a/src/iscs/shape/manualAlarmButton.js b/src/iscs/shape/manualAlarmButton.js
new file mode 100644
index 000000000..4820144ba
--- /dev/null
+++ b/src/iscs/shape/manualAlarmButton.js
@@ -0,0 +1,87 @@
+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';
+
+export default class manualAlarmButton 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.grouper = new Group({
+ id: this.model.code,
+ position: [this.model.point.x, this.model.point.y]
+ });
+ this.add(this.grouper);
+ this.rect = new Rect({
+ zlevel: this.model.zlevel,
+ z: this.model.z - 1,
+ shape: {
+ x: 0,
+ y: 0,
+ width: this.model.width,
+ height: this.model.width * 1.1
+ },
+ style: {
+ lineWidth: 1,
+ stroke: '#0F0'
+ }
+ });
+ this.grouper.add(this.rect);
+ this.text = new Text({
+ zlevel: this.model.zlevel,
+ z: this.model.z,
+ style: {
+ x: 0,
+ y: this.model.width * 2 / 5,
+ fontWeight: this.model.fontWeight || 300,
+ fontSize: this.model.fontSize || this.model.width,
+ fontFamily: this.model.fontFamily || 'consolas',
+ text: 'Y',
+ textStrokeWidth: this.model.textStrokeWidth,
+ textFill: this.model.textFill || '#0F0',
+ textAlign: this.model.textAlign,
+ textPosition: this.model.textPosition || 'inside',
+ textVerticalAlign: this.model.textVerticalAlign || null,
+ textLineHeight: this.model.fontSize || 14
+ }
+ });
+ this.grouper.add(this.text);
+ this.circleOutside = new Circle({
+ zlevel: this.model.zlevel,
+ z: this.model.z,
+ shape: {
+ cx: this.model.width * 2 / 3,
+ cy: this.model.width * 2.2 / 3,
+ r: this.model.width / 4
+ },
+ style: {
+ fill: '#0f0'
+ }
+ });
+ this.grouper.add(this.circleOutside);
+ this.circleInside = new Circle({
+ zlevel: this.model.zlevel,
+ z: this.model.z,
+ shape: {
+ cx: this.model.width * 2 / 3,
+ cy: this.model.width * 2.2 / 3,
+ r: this.model.width / 10
+ },
+ style: {
+ fill: '#000'
+ }
+ });
+ this.grouper.add(this.circleInside);
+ }
+ setModel(dx, dy) {
+ this.model.point.x += dx;
+ this.model.point.y += dy;
+ }
+}
diff --git a/src/iscs/shape/psd/platformScreenDoor.js b/src/iscs/shape/psd/platformScreenDoor.js
new file mode 100644
index 000000000..c0fa4c9ec
--- /dev/null
+++ b/src/iscs/shape/psd/platformScreenDoor.js
@@ -0,0 +1,100 @@
+import Group from 'zrender/src/container/Group';
+import Text from 'zrender/src/graphic/Text';
+import Rect from 'zrender/src/graphic/shape/Rect';
+import Line from 'zrender/src/graphic/shape/Line';
+import PsdClose from './psdClose';
+import PsdOpen from './psdOpen';
+import UnknownState from './unknownState';
+
+export default class PlatformScreenDoor extends Group {
+ constructor(device) {
+ super();
+ this.model = device.model;
+ this.zlevel = device.model.zlevel;
+ this.z = device.z;
+ this._type = device.model._type;
+ this._code = device.model.code;
+ this.create();
+ }
+ create() {
+ this.grouper = new Group({
+ id: this.model.code,
+ position: [this.model.point.x, this.model.point.y]
+ });
+ this.add(this.grouper);
+ this.glass = new Rect({
+ zlevel: this.zlevel,
+ z: this.z,
+ shape: {
+ x: 0,
+ y: 0,
+ width: this.model.width,
+ height: this.model.width / 2
+ },
+ style: {
+ fill: '#FFFFFF'
+ }
+ });
+ this.glassTopLine = new Line({
+ zlevel: this.zlevel,
+ z: this.z,
+ shape: {
+ x1: 0,
+ y1: this.model.width * 5 / 16,
+ x2: this.model.width,
+ y2: this.model.width * 5 / 16
+ },
+ style: {
+ lineWidth: 2,
+ stroke: '#CBCBCB'
+ }
+ });
+ this.glassBottomLine = new Line({
+ zlevel: this.zlevel,
+ z: this.z,
+ shape: {
+ x1: 0,
+ y1: this.model.width * 7 / 16,
+ x2: this.model.width,
+ y2: this.model.width * 7 / 16
+ },
+ style: {
+ lineWidth: 2,
+ stroke: '#CBCBCB'
+ }
+ });
+ this.psdClose = new PsdClose({
+ model: {
+ zlevel: this.zlevel,
+ z: this.z + 1,
+ width: this.model.width
+ }
+ });
+ this.psdOpen = new PsdOpen({
+ model: {
+ zlevel: this.zlevel,
+ z: this.z + 1,
+ width: this.model.width
+ }
+ });
+ this.unknownState = new UnknownState({
+ model: {
+ zlevel: this.zlevel,
+ z: this.z + 1,
+ width: this.model.width
+ }
+ });
+ this.grouper.add(this.glass);
+ this.grouper.add(this.glassTopLine);
+ this.grouper.add(this.glassBottomLine);
+ this.grouper.add(this.psdClose);
+ this.grouper.add(this.psdOpen);
+ this.grouper.add(this.unknownState);
+ this.unknownState.hide();
+ this.psdOpen.hide();
+ }
+ setModel(dx, dy) {
+ this.model.point.x += dx;
+ this.model.point.y += dy;
+ }
+}
diff --git a/src/iscs/shape/psd/psdClose.js b/src/iscs/shape/psd/psdClose.js
new file mode 100644
index 000000000..367d2a4c6
--- /dev/null
+++ b/src/iscs/shape/psd/psdClose.js
@@ -0,0 +1,104 @@
+import Group from 'zrender/src/container/Group';
+import Line from 'zrender/src/graphic/shape/Line';
+import Rect from 'zrender/src/graphic/shape/Rect';
+
+export default class PsdClose extends Group {
+ constructor(device) {
+ super();
+ this.model = device.model;
+ this.zlevel = device.model.zlevel;
+ this.z = device.model.z;
+ this.create();
+ }
+ create() {
+ this.door = new Rect({
+ zlevel: this.zlevel,
+ z: this.z,
+ shape: {
+ x: this.model.width / 4,
+ y: 0,
+ width: this.model.width / 2,
+ height: this.model.width / 2
+ },
+ style: {
+ fill: '#0F0'
+ }
+ });
+ this.doorLeftLine1 = new Line({
+ zlevel: this.zlevel,
+ z: this.z + 1,
+ shape: {
+ x1: this.model.width / 4 + 2,
+ y1: 2,
+ x2: this.model.width / 4 + 2,
+ y2: this.model.width / 2
+ },
+ style: {
+ stroke: '#000',
+ lineWidth: 0.5
+ }
+ });
+ this.doorLeftLine2 = new Line({
+ zlevel: this.zlevel,
+ z: this.z + 1,
+ shape: {
+ x1: this.model.width / 4 + 2,
+ y1: 2,
+ x2: this.model.width / 2 - 2,
+ y2: 2
+ },
+ style: {
+ stroke: '#000',
+ lineWidth: 0.5
+ }
+ });
+ this.doorRightLine1 = new Line({
+ zlevel: this.zlevel,
+ z: this.z + 1,
+ shape: {
+ x1: this.model.width / 2 + 2,
+ y1: 2,
+ x2: this.model.width * 3 / 4 - 2,
+ y2: 2
+ },
+ style: {
+ stroke: '#000',
+ lineWidth: 0.5
+ }
+ });
+ this.doorRightLine2 = new Line({
+ zlevel: this.zlevel,
+ z: this.z + 1,
+ shape: {
+ x1: this.model.width * 3 / 4 - 2,
+ y1: 2,
+ x2: this.model.width * 3 / 4 - 2,
+ y2: this.model.width / 2
+ },
+ style: {
+ stroke: '#000',
+ lineWidth: 0.5
+ }
+ });
+ this.doorCrack = new Line({
+ zlevel: this.zlevel,
+ z: this.z + 1,
+ shape: {
+ x1: this.model.width / 2,
+ y1: 2,
+ x2: this.model.width / 2,
+ y2: this.model.width / 2
+ },
+ style: {
+ stroke : '#000',
+ lineWidth: 2
+ }
+ });
+ this.add(this.door);
+ this.add(this.doorLeftLine1);
+ this.add(this.doorLeftLine2);
+ this.add(this.doorRightLine1);
+ this.add(this.doorRightLine2);
+ this.add(this.doorCrack);
+ }
+}
diff --git a/src/iscs/shape/psd/psdOpen.js b/src/iscs/shape/psd/psdOpen.js
new file mode 100644
index 000000000..da3417db2
--- /dev/null
+++ b/src/iscs/shape/psd/psdOpen.js
@@ -0,0 +1,98 @@
+import Group from 'zrender/src/container/Group';
+import Line from 'zrender/src/graphic/shape/Line';
+import Rect from 'zrender/src/graphic/shape/Rect';
+import Polygon from 'zrender/src/graphic/shape/Polygon';
+
+export default class PsdOpen extends Group {
+ constructor(device) {
+ super();
+ this.model = device.model;
+ this.zlevel = device.model.zlevel;
+ this.z = device.model.z;
+ this.create();
+ }
+ create() {
+ this.bgRect = new Rect({
+ zlevel: this.zlevel,
+ z: this.z - 1,
+ shape: {
+ x: this.model.width / 4,
+ y: 0,
+ width: this.model.width / 2,
+ height: this.model.width / 2
+ },
+ style: {
+ fill: '#000'
+ }
+ });
+ this.doorLeftFrame = new Line({
+ zlevel: this.zlevel,
+ z: this.z,
+ shape: {
+ x1: this.model.width / 4,
+ y1: 0,
+ x2: this.model.width / 4,
+ y2: this.model.width / 2
+ },
+ style: {
+ lineWidth: this.model.width / 40,
+ stroke: '#10F19A'
+ }
+ });
+ this.doorTopFrame = new Line({
+ zlevel: this.zlevel,
+ z: this.z,
+ shape: {
+ x1: this.model.width / 4,
+ y1: this.model.width / 80,
+ x2: this.model.width * 3 / 4,
+ y2: this.model.width / 80
+ },
+ style: {
+ lineWidth: this.model.width / 40,
+ stroke: '#10F19A'
+ }
+ });
+ this.doorRightFrame = new Line({
+ zlevel: this.zlevel,
+ z: this.z,
+ shape: {
+ x1: this.model.width * 3 / 4,
+ y1: 0,
+ x2: this.model.width * 3 / 4,
+ y2: this.model.width / 2
+ },
+ style: {
+ lineWidth: this.model.width / 40,
+ stroke: '#10F19A'
+ }
+ });
+ this.leftPolygon = new Polygon({
+ zlevel: this.zlevel,
+ z: this.z,
+ shape: {
+ points: [[this.model.width * 21 / 80, this.model.width * 3 / 80], [this.model.width * 5 / 12, this.model.width / 8], [this.model.width * 5 / 12, this.model.width * 37 / 80], [this.model.width * 21 / 80, this.model.width * 37 / 80]]
+ },
+ style: {
+ fill: '#00CC33'
+ }
+ });
+ this.rightPolygon = new Polygon({
+ zlevel: this.zlevel,
+ z: this.z,
+ shape: {
+ points: [
+ [this.model.width * 7 / 12, this.model.width / 8], [this.model.width * 59 / 80, this.model.width * 3 / 80], [this.model.width * 59 / 80, this.model.width * 37 / 80], [this.model.width * 7 / 12, this.model.width * 37 / 80]]
+ },
+ style: {
+ fill: '#00CC33'
+ }
+ });
+ this.add(this.bgRect);
+ this.add(this.doorLeftFrame);
+ this.add(this.doorRightFrame);
+ this.add(this.doorTopFrame);
+ this.add(this.leftPolygon);
+ this.add(this.rightPolygon);
+ }
+}
diff --git a/src/iscs/shape/psd/unknownState.js b/src/iscs/shape/psd/unknownState.js
new file mode 100644
index 000000000..0d918c0a2
--- /dev/null
+++ b/src/iscs/shape/psd/unknownState.js
@@ -0,0 +1,45 @@
+import Group from 'zrender/src/container/Group';
+import Rect from 'zrender/src/graphic/shape/Rect';
+import Line from 'zrender/src/graphic/shape/Line';
+
+export default class UnknownState extends Group {
+ constructor(device) {
+ super();
+ this.model = device.model;
+ this.zlevel = device.model.zlevel;
+ this.z = device.model.z;
+ this.create();
+ }
+ create() {
+ this.doorFrame = new Rect({
+ zlevel: this.zlevel,
+ z: this.z,
+ shape: {
+ x: this.model.width / 4,
+ y: 0,
+ width: this.model.width / 2,
+ height: this.model.width / 2
+ },
+ style: {
+ stroke: '#10F19A',
+ fill: '#B5B201'
+ }
+ });
+ this.doorCrack = new Line({
+ zlevel: this.zlevel,
+ z: this.z + 1,
+ shape: {
+ x1: this.model.width / 2,
+ y1: 0,
+ x2: this.model.width / 2,
+ y2: this.model.width / 2
+ },
+ style: {
+ lineWidth: 2,
+ stroke: '#10F19A'
+ }
+ });
+ this.add(this.doorFrame);
+ this.add(this.doorCrack);
+ }
+}
diff --git a/src/iscs/shape/smokeDetector.js b/src/iscs/shape/smokeDetector.js
new file mode 100644
index 000000000..72829f275
--- /dev/null
+++ b/src/iscs/shape/smokeDetector.js
@@ -0,0 +1,59 @@
+import Group from 'zrender/src/container/Group';
+import Circle from 'zrender/src/graphic/shape/Circle';
+import Text from 'zrender/src/graphic/Text';
+
+export default class SmokeDetector extends Group {
+ constructor(device) {
+ super();
+ this.model = device.model;
+ this.zlevel = device.model.zlevel;
+ this.z = device.z;
+ this._type = device.model._type;
+ this._code = device.model.code;
+ this.create();
+ }
+ create() {
+ this.grouper = new Group({
+ id: this.model.code,
+ position: [this.model.point.x, this.model.point.y]
+ });
+ this.add(this.grouper);
+ this.circle = new Circle({
+ zlevel: this.zlevel,
+ z: this.z,
+ shape: {
+ cx: this.model.width / 2,
+ cy: this.model.width / 2,
+ r: this.model.width / 2
+ },
+ style: {
+ lineWidth: 1,
+ stroke: '#0F0'
+ }
+ });
+ this.grouper.add(this.circle);
+ this.text = new Text({
+ zlevel: this.model.zlevel,
+ z: this.model.z,
+ style: {
+ x: this.model.width / 4,
+ y: 0,
+ fontWeight: 300,
+ fontSize: this.model.width,
+ fontFamily: 'Consolas',
+ text: 'Y',
+ textFill: this.model.textFill || '#0F0',
+ textPosition: this.model.textPosition || 'inside',
+ textLineHeight: this.model.fontSize || 14
+ }
+ });
+ const boundingRect = this.text.getBoundingRect();
+ const distance = this.model.width / 2 - boundingRect.y - boundingRect.height / 2;
+ this.text.setStyle('y', distance);
+ this.grouper.add(this.text);
+ }
+ setModel(dx, dy) {
+ this.model.point.x += dx;
+ this.model.point.y += dy;
+ }
+}
diff --git a/src/iscs/shape/stateTable.js b/src/iscs/shape/stateTable.js
new file mode 100644
index 000000000..00773fd59
--- /dev/null
+++ b/src/iscs/shape/stateTable.js
@@ -0,0 +1,38 @@
+import Group from 'zrender/src/container/Group';
+const mean = {
+ slidingDoorEmergencyDoorOpenMalfunction : '滑动门&应急门开门故障',
+ slidingDoorEmergencyDoorCloseMalfunction: '滑动门&应急门关门故障',
+ slidingDoorsInterlockAllClear: '滑动门互锁解除报警',
+ emergencyControlPanelOperation: '紧急控制盘操作',
+ emergencyControlPanelOperationOpenCommand: '紧急控制盘操作开门命令',
+ emergencyControlPanelOperationCloseCommand: '紧急控制盘操作关门命令',
+ localControlPanelOperation: '就地控制盘操作',
+ localControlPanelOperationOpenCommand: '就地控制盘操作开门命令',
+ localControlPanelOperationCloseCommand: '就地控制盘操作关门命令',
+ automaticOpenOrder: '自动开门命令',
+ automaticCloseOrder: '自动开门命令',
+ allDoorsOpenInPlace: '所有门开到位',
+ allDoorsCloseInPlace: '所有门关到位',
+ systemDrivePowerFailure: '系统驱动电源故障',
+ systemControlPowerFailure: '系统控制电源故障',
+ monitorPowerFailure: '监视电源故障'
+
+};
+export default class StateTable extends Group {
+ constructor(device) {
+ super();
+ this.model = device.model;
+ this.zlevel = device.model.zlevel;
+ this.z = device.model.z;
+ this._type = device.model._type;
+ this._code = device.model.code;
+ this.create();
+ }
+ cerate() {
+ // this.header =
+ }
+ setModel(dx, dy) {
+ this.model.point.x += dx;
+ this.model.point.y += dy;
+ }
+}
diff --git a/src/iscs/shape/temperatureDetector.js b/src/iscs/shape/temperatureDetector.js
new file mode 100644
index 000000000..cf52a7f3b
--- /dev/null
+++ b/src/iscs/shape/temperatureDetector.js
@@ -0,0 +1,59 @@
+import Group from 'zrender/src/container/Group';
+import Circle from 'zrender/src/graphic/shape/Circle';
+import Text from 'zrender/src/graphic/Text';
+
+export default class TemperatureDetector extends Group {
+ constructor(device) {
+ super();
+ this.model = device.model;
+ this.zlevel = device.model.zlevel;
+ this.z = device.z;
+ this._type = device.model._type;
+ this._code = device.model.code;
+ this.create();
+ }
+ create() {
+ this.grouper = new Group({
+ id: this.model.code,
+ position: [this.model.point.x, this.model.point.y]
+ });
+ this.add(this.grouper);
+ this.circle = new Circle({
+ zlevel: this.zlevel,
+ z: this.z,
+ shape: {
+ cx: this.model.width / 2,
+ cy: this.model.width / 2,
+ r: this.model.width / 2
+ },
+ style: {
+ lineWidth: 1,
+ stroke: '#0F0'
+ }
+ });
+ this.grouper.add(this.circle);
+ this.text = new Text({
+ zlevel: this.model.zlevel,
+ z: this.model.z,
+ style: {
+ x: this.model.width / 4,
+ y: 0,
+ fontWeight: 300,
+ fontSize: this.model.width,
+ fontFamily: 'Consolas',
+ text: 'W',
+ textFill: this.model.textFill || '#0F0',
+ textPosition: this.model.textPosition || 'inside',
+ textLineHeight: this.model.fontSize || 14
+ }
+ });
+ const boundingRect = this.text.getBoundingRect();
+ const distance = this.model.width / 2 - boundingRect.y - boundingRect.height / 2;
+ this.text.setStyle('y', distance);
+ this.grouper.add(this.text);
+ }
+ setModel(dx, dy) {
+ this.model.point.x += dx;
+ this.model.point.y += dy;
+ }
+}
diff --git a/src/iscs/transformHandle.js b/src/iscs/transformHandle.js
new file mode 100644
index 000000000..3ff3ab22a
--- /dev/null
+++ b/src/iscs/transformHandle.js
@@ -0,0 +1,90 @@
+import deviceType from './constant/deviceType';
+import {createTransform, createBoundingRect} from './utils/parser';
+
+class TransformHandle {
+ constructor(painter) {
+ this.$painter = painter;
+
+ this.parentLevel = painter.getParentLevel();
+
+ this.rect = { x: 0, y: 0, width: 0, height: 0 };
+
+ this.transform = createTransform({ scaleRate: 1, offsetX: 0, offsetY: 0 });
+ }
+
+ checkVisible(view) {
+ return createBoundingRect(view).intersect(this.rect);
+ }
+
+ revisibleView(view) {
+ if (this.checkVisible(view) || view._type === deviceType.Background) {
+ view.show();
+ } else {
+ view.hide();
+ }
+
+ view.dirty();
+ }
+
+ // 视图进行缩放/平移
+ transformView(view) {
+ if (view) {
+ view.transform = this.transform;
+ view.decomposeTransform();
+ this.revisibleView(view);
+ view.transform = '';
+ }
+ }
+
+ // 处理所有视图缩放/平移
+ transformAll() {
+ this.traverse(this.transformView, this);
+ }
+
+ // 重新计算显示图形
+ revisibleAll() {
+ this.traverse(this.revisibleView, this);
+ }
+
+ // 更新偏移量
+ updateTransform(opts, canvasSize) {
+ if (canvasSize) {
+ const elRect = this.parentLevel.getBoundingRect();
+ const zrRect = this.rect;
+ if (canvasSize.x - opts.offsetX > 0) {
+ opts.offsetX = -elRect.x;
+ }
+
+ if (canvasSize.y - opts.offsetY > 0) {
+ opts.offsetY = -elRect.y;
+ }
+
+ if (elRect.x + canvasSize.width < zrRect.width) {
+ opts.offsetX -= zrRect.width - (elRect.x + canvasSize.width);
+ }
+
+ if (elRect.y + canvasSize.height < zrRect.height) {
+ opts.offsetY -= zrRect.height - (elRect.y + canvasSize.height);
+ }
+ }
+ this.transform = createTransform(opts);
+ this.transformAll();
+ }
+
+ // 更新画布尺寸
+ updateZrSize(opts) {
+ this.rect = { x: 0, y: 0, width: opts.width, height: opts.height };
+ this.revisibleAll();
+ }
+
+ // 遍历group执行回调
+ traverse(cb, context) {
+ this.parentLevel.eachChild(level => {
+ level.eachChild((view) => {
+ cb.call(context, view);
+ }, context);
+ }, context);
+ }
+}
+
+export default TransformHandle;
diff --git a/src/iscs/utils/parser.js b/src/iscs/utils/parser.js
new file mode 100644
index 000000000..5af3c0889
--- /dev/null
+++ b/src/iscs/utils/parser.js
@@ -0,0 +1,130 @@
+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) {
+ zrUtil.each(data.manualAlarmButtonList || [], elem => {
+ iscsDevice[elem.code] = deviceFactory(deviceType.ManualAlarmButton, elem);
+ }, this);
+ zrUtil.each(data.vidiconList || [], elem => {
+ iscsDevice[elem.code] = deviceFactory(deviceType.vidiconList, elem);
+ }, this);
+ zrUtil.each(data.vidiconCloudList || [], elem => {
+ iscsDevice[elem.code] = deviceFactory(deviceType.vidiconCloudList, elem);
+ }, this);
+ zrUtil.each(data.frozenPumpList || [], elem => {
+ iscsDevice[elem.code] = deviceFactory(deviceType.FrozenPump, elem);
+ }, this);
+ zrUtil.each(data.fireHydranAlarmButtonList || [], elem => {
+ iscsDevice[elem.code] = deviceFactory(deviceType.FireHydranAlarmButton, elem);
+ }, this);
+
+ zrUtil.each(data.gasFireControlList || [], elem => {
+ iscsDevice[elem.code] = deviceFactory(deviceType.GasFireControl, elem);
+ }, this);
+
+ zrUtil.each(data.smokeDetectorList || [], elem => {
+ iscsDevice[elem.code] = deviceFactory(deviceType.SmokeDetector, elem);
+ }, this);
+
+ zrUtil.each(data.temperatureDetectorList || [], elem => {
+ iscsDevice[elem.code] = deviceFactory(deviceType.TemperatureDetector, elem);
+ });
+
+ zrUtil.each(data.platformScreenDoorList || [], elem =>{
+ iscsDevice[elem.code] = deviceFactory(deviceType.PlatformScreenDoor, elem);
+ });
+
+ zrUtil.each(data.endDoorList || [], elem =>{
+ iscsDevice[elem.code] = deviceFactory(deviceType.EndDoor, 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.vidiconList :
+ updateIscsListByDevice(iscsData, 'vidiconList', device);
+ break;
+ case deviceType.vidiconCloudList :
+ updateIscsListByDevice(iscsData, 'vidiconCloudList', device);
+ break;
+ case deviceType.ManualAlarmButton :
+ updateIscsListByDevice(iscsData, 'manualAlarmButtonList', device);
+ break;
+ case deviceType.FireHydranAlarmButton:
+ updateIscsListByDevice(iscsData, 'fireHydranAlarmButtonList', device);
+ break;
+ case deviceType.GasFireControl:
+ updateIscsListByDevice(iscsData, 'gasFireControlList', device);
+ break;
+ case deviceType.SmokeDetector:
+ updateIscsListByDevice(iscsData, 'smokeDetectorList', device);
+ break;
+ case deviceType.TemperatureDetector:
+ updateIscsListByDevice(iscsData, 'temperatureDetectorList', device);
+ break;
+ case deviceType.PlatformScreenDoor:
+ updateIscsListByDevice(iscsData, 'platformScreenDoorList', device);
+ break;
+ case deviceType.FrozenPump :
+ updateIscsListByDevice(iscsData, 'frozenPumpList', device);
+ break;
+ case deviceType.EndDoor:
+ updateIscsListByDevice(iscsData, 'endDoorList', device);
+ break;
+ }
+
+ store.dispatch('iscs/setIscsData', iscsData);
+}
diff --git a/src/router/index.js b/src/router/index.js
index 95004d338..bdb6affc0 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -33,6 +33,8 @@ 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 IscsDesign = () => import('@/views/system/iscsDesign/index');
const News = () => import('@/views/system/news/index');
const CommandDictionary = () => import('@/views/system/commandDictionary/index');
const CommandDictionaryDetail = () => import('@/views/system/commandDictionary/edit');
@@ -767,6 +769,20 @@ export const asyncRouter = [
i18n: 'router.ibpDraw'
}
},
+ {
+ path:'iscs/design',
+ component: IscsDesign,
+ meta: {
+ i18n: 'router.iscsDraw'
+ },
+ children: [
+ {
+ path: 'edit/:id/:mode',
+ component: IscsDraw,
+ hidden: true
+ }
+ ]
+ },
{
path: 'dictionary',
component: Dictionary,
diff --git a/src/store/index.js b/src/store/index.js
index 6feaf3b5f..a994e562f 100644
--- a/src/store/index.js
+++ b/src/store/index.js
@@ -15,6 +15,7 @@ import socket from './modules/socket';
import scriptRecord from './modules/scriptRecord';
import ibp from './modules/ibp';
import order from './modules/order';
+import iscs from './modules/iscs';
import getters from './getters';
@@ -36,7 +37,8 @@ const store = new Vuex.Store({
socket,
scriptRecord,
ibp,
- order
+ order,
+ iscs
},
getters
});
diff --git a/src/store/modules/iscs.js b/src/store/modules/iscs.js
new file mode 100644
index 000000000..70df69726
--- /dev/null
+++ b/src/store/modules/iscs.js
@@ -0,0 +1,93 @@
+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;
+ },
+ vidiconList: (state) => {
+ if (state.iscs && state.iscs.vidiconList) {
+ return state.iscs.vidiconList;
+ } else {
+ return [];
+ }
+ },
+ vidiconCloudList: (state) => {
+ if (state.iscs && state.iscs.vidiconCloudList) {
+ return state.iscs.vidiconCloudList;
+ } else {
+ return [];
+ }
+ }
+ },
+
+ 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;
diff --git a/src/utils/baseUrl.js b/src/utils/baseUrl.js
index 1e9afea51..79d1c6346 100644
--- a/src/utils/baseUrl.js
+++ b/src/utils/baseUrl.js
@@ -3,11 +3,11 @@ export function getBaseUrl() {
let BASE_API;
if (process.env.NODE_ENV === 'development') {
// BASE_API = 'https://joylink.club/jlcloud';
- BASE_API = 'https://test.joylink.club/jlcloud';
+ // BASE_API = 'https://test.joylink.club/jlcloud';
// BASE_API = 'http://192.168.3.5:9000'; // 袁琪
// BASE_API = 'http://192.168.3.6:9000'; // 旭强
// BASE_API = 'http://192.168.3.41:9000'; // 张赛
- // BASE_API = 'http://192.168.3.82:9000'; // 杜康
+ BASE_API = 'http://192.168.3.82:9000'; // 杜康
} else {
BASE_API = process.env.VUE_APP_BASE_API;
}
diff --git a/src/views/iscsSystem/index.vue b/src/views/iscsSystem/index.vue
new file mode 100644
index 000000000..258d39306
--- /dev/null
+++ b/src/views/iscsSystem/index.vue
@@ -0,0 +1,209 @@
+
+