增加 iscs

This commit is contained in:
ival 2021-03-26 17:09:11 +08:00
parent ea85ed29ae
commit 6b16e3d488
83 changed files with 12098 additions and 0 deletions

View File

@ -0,0 +1,40 @@
import mask from '@/assets/map/tpsq/image-mask.jpg';
export default class defaultStyle {
constructor() {
/** 透明填充 颜色*/
this.transparentColor = 'rgba(0,0,0,0)';
/** 默认背景 颜色*/
this.backgroundColor = '#000000';
/** 默认字体 族类*/
this.fontFamily = '黑体,Times New Roman';
/** 默认字体 大小*/
this.fontSize = 12;
/** 图片高亮遮罩*/
this.maskHover2Image = mask;
/** 文字高亮遮罩*/
this.textHover2Color = '#1477e5';
/** 管道高亮遮罩*/
this.pipeHover2Color = '#ffff00'; // '#ff5f5f'
this.pipeHover2ColorDef = '#fff';
/** 图形高亮遮罩*/
this.graphHover2Color = '#62ff00';
/** 测量高亮遮罩*/
this.measureHover2Color = '#6000ff';
/** 选中透明度*/
this.maskOpacity = 0.8;
/** 提亮度*/
this.liftLevel = 0.5;
}
}

View File

@ -0,0 +1,117 @@
import defaultStyle from './defaultStyle';
import graphType from '../constant/graphType';
class SkinCode extends defaultStyle {
constructor() {
super();
this[graphType.Text] = {
text: {
fontWeight: 'normal'
}
};
this[graphType.Table] = {
header: {
height: 40,
fontWeight: 'bold',
fontSize: 18
}
};
this[graphType.Resource] = {
warning: {
r: 5,
fill: 'red',
offset: { x: 0, y: 0}
},
hover: {
lineWidth: 1
}
};
this[graphType.LinePipe] = {
line: {
lineWidth: 2
},
arrow: {
lineWidth: 1
}
};
this[graphType.Measure] = {
};
this[graphType.Warning] = {
circle: {
lineWidth: 0,
stroke: '#eee'
},
text: {
fontWeight: 'bold',
fontSize: 16,
textFill: 'red'
}
};
this[graphType.Switching] = {
text: {
fontWeight: 'normal'
},
button: {
lineWidth: 0.5,
stroke: '#666',
fill: '#d1d1d1'
}
};
this[graphType.Popup] = {
text: {
fontWeight: 'normal'
},
button: {
lineWidth: 0.5,
stroke: '#666',
fill: '#d1d1d1'
}
};
this[graphType.ProgramControl] = {
button: {
lineWidth: 3,
stroke: '#fff',
width: 72,
height: 24
},
line: {
lineWidth: 1,
stroke: '#fff'
},
block: {
lineWidth: 1,
stroke: '#888',
fill: '#d1d1d1',
shadowColor: '#000',
shadowOffsetX: 1,
shadowOffsetY: 1
},
indicate: {
fill: '#000'
}
};
this[graphType.Pid] = {
text: {
fontWeight: 'normal'
},
button: {
lineWidth: 0.5,
stroke: '#666',
fill: '#d1d1d1'
}
};
}
}
export default new SkinCode();

View File

@ -0,0 +1,117 @@
import defaultStyle from './defaultStyle';
import panelType from '../constant/panelType';
class SkinCode extends defaultStyle {
constructor() {
super();
this[panelType.Text] = {
text: {
fontWeight: 'normal'
}
};
this[panelType.Table] = {
header: {
height: 40,
fontWeight: 'bold',
fontSize: 18
}
};
this[panelType.Resource] = {
warning: {
r: 5,
fill: 'red',
offset: { x: 0, y: 0}
},
hover: {
lineWidth: 1
}
};
this[panelType.LinePipe] = {
line: {
lineWidth: 2
},
arrow: {
lineWidth: 1
}
};
this[panelType.Measure] = {
};
this[panelType.Warning] = {
circle: {
lineWidth: 0,
stroke: '#eee'
},
text: {
fontWeight: 'bold',
fontSize: 16,
textFill: 'red'
}
};
this[panelType.Switching] = {
text: {
fontWeight: 'normal'
},
button: {
lineWidth: 0.5,
stroke: '#666',
fill: '#d1d1d1'
}
};
this[panelType.Popup] = {
text: {
fontWeight: 'normal'
},
button: {
lineWidth: 0.5,
stroke: '#666',
fill: '#d1d1d1'
}
};
this[panelType.ProgramControl] = {
button: {
lineWidth: 3,
stroke: '#fff',
width: 72,
height: 24
},
line: {
lineWidth: 1,
stroke: '#fff'
},
block: {
lineWidth: 1,
stroke: '#888',
fill: '#d1d1d1',
shadowColor: '#000',
shadowOffsetX: 1,
shadowOffsetY: 1
},
indicate: {
fill: '#000'
}
};
this[panelType.Pid] = {
text: {
fontWeight: 'normal'
},
button: {
lineWidth: 0.5,
stroke: '#666',
fill: '#d1d1d1'
}
};
}
}
export default new SkinCode();

View File

@ -0,0 +1,39 @@
import defaultStyle from './defaultStyle';
import STLBg from '@/assets/map/stl_bg.png';
import STLPilotLamp from '@/assets/map/stl_pilot_lamp.png';
import STLButton from '@/assets/map/stl_button.png';
import graphType from '../constant/graphType';
import resourceType from '../constant/resourceType';
class SkinCode extends defaultStyle {
constructor() {
super();
this[graphType.Resource] = {
warning: {
r: 5,
fill: 'red',
offset: { x: 0, y: 0}
},
hover: {
lineWidth: 2
},
Bg: {
image: STLBg
},
PilotLamp: {
image: STLPilotLamp
},
Button: {
image: STLButton
}
};
this[resourceType.Button] = {
text: {
fontSize: 14,
fontWeight: 'bold'
}
};
}
}
export default new SkinCode();

View File

@ -0,0 +1,10 @@
import GraphStyle from './graphStyle';
import PanelStyle from './panelStyle';
import ResourceStyle from './resourceStyle';
export default {
...GraphStyle,
...PanelStyle,
...ResourceStyle
};

View File

@ -0,0 +1,65 @@
import graphType from './graphType';
const graphRender = {};
graphRender[graphType.Text] = {
_type: graphType.Text,
zlevel: 1,
z: 9
};
graphRender[graphType.Table] = {
_type: graphType.Table,
zlevel: 1,
z: 4
};
graphRender[graphType.Resource] = {
_type: graphType.Resource,
zlevel: 1,
z: 8
};
graphRender[graphType.LinePipe] = {
_type: graphType.LinePipe,
zlevel: 1,
z: 4
};
graphRender[graphType.Measure] = {
_type: graphType.Measure,
zlevel: 1,
z: 9
};
graphRender[graphType.Warning] = {
_type: graphType.Warning,
zlevel: 1,
z: 9
};
graphRender[graphType.Switching] = {
_type: graphType.Switching,
zlevel: 1,
z: 9
};
graphRender[graphType.Popup] = {
_type: graphType.Popup,
zlevel: 1,
z: 9
};
graphRender[graphType.ProgramControl] = {
_type: graphType.ProgramControl,
zlevel: 1,
z: 9
};
graphRender[graphType.Pid] = {
_type: graphType.Pid,
zlevel: 1,
z: 9
};
export default graphRender;

View File

@ -0,0 +1,15 @@
const graphType = {
Text: 'text',
Table: 'table',
Table1: 'Table1',
Resource: 'resource',
LinePipe: 'linePipe',
Measure: 'measure',
Warning: 'warning',
Switching: 'switching', // 投切按钮
Popup: 'popup', // 弹窗按钮
ProgramControl: 'programControl', // 程制按钮
Pid: 'pid' // Pid按钮
};
export default graphType;

View File

@ -0,0 +1,65 @@
import panelType from './panelType';
const panelRender = {};
panelRender[panelType.Text] = {
_type: panelType.Text,
zlevel: 1,
z: 9
};
panelRender[panelType.Table] = {
_type: panelType.Table,
zlevel: 1,
z: 4
};
panelRender[panelType.Resource] = {
_type: panelType.Resource,
zlevel: 1,
z: 4
};
panelRender[panelType.LinePipe] = {
_type: panelType.LinePipe,
zlevel: 1,
z: 4
};
panelRender[panelType.Measure] = {
_type: panelType.Measure,
zlevel: 1,
z: 9
};
panelRender[panelType.Warning] = {
_type: panelType.Warning,
zlevel: 1,
z: 9
};
panelRender[panelType.Switching] = {
_type: panelType.Switching,
zlevel: 1,
z: 9
};
panelRender[panelType.Popup] = {
_type: panelType.Popup,
zlevel: 1,
z: 9
};
panelRender[panelType.ProgramControl] = {
_type: panelType.ProgramControl,
zlevel: 1,
z: 9
};
panelRender[panelType.Pid] = {
_type: panelType.Pid,
zlevel: 1,
z: 9
};
export default panelRender;

View File

@ -0,0 +1,14 @@
const panelType = {
Text: 'panel-text',
Table: 'panel-table',
Resource: 'panel-resource',
LinePipe: 'panel-linePipe',
Measure: 'panel-measure',
Warning: 'panel-warning',
Switching: 'panel-switching', // 投切按钮
Popup: 'panel-popup', // 弹窗按钮
ProgramControl: 'panel-programControl', // 程制按钮
Pid: 'panel-pid' // Pid按钮
};
export default panelType;

View File

@ -0,0 +1,32 @@
import resourceType from './resourceType';
const resourceRender = {};
resourceRender[resourceType.Background] = {
_type: resourceType.Background,
zlevel: 1,
z: 9,
z2: 1
};
resourceRender[resourceType.Button] = {
_type: resourceType.Button,
zlevel: 1,
z: 9,
z2: 1
};
resourceRender[resourceType.PilotLamp] = {
_type: resourceType.PilotLamp,
zlevel: 1,
z: 9,
z2: 1
};
resourceRender[resourceType.Display] = {
_type: resourceType.Display,
zlevel: 1,
z: 9,
z2: 1
};
export default resourceRender;

View File

@ -0,0 +1,8 @@
const resourceType = {
Button: 'res-button',
Display: 'res-display',
PilotLamp: 'res-pilotLamp',
Background: 'res-background'
};
export default resourceType;

387
src/iscs_new/controller.js Normal file
View File

@ -0,0 +1,387 @@
import * as eventTool from 'zrender/src/core/event';
import * as utils from './utils/utils.js';
import Storage from './utils/container/Storage';
import graphType from './constant/graphType';
import panelType from './constant/panelType';
import resourceType from './constant/resourceType';
import Eventful from 'zrender/src/mixin/Eventful';
import DragHandle from './dragHandle';
import SelectingHandle from './selectingHandle';
import SelectHandle from './selectHandle';
import KeyBoardHandle from './keyboardHandle';
class MapEvent {
constructor(e) {
this.clientX = e.event.clientX;
this.clientY = e.event.clientY;
let view = e.target;
while (view) {
if ([
...Object.values(graphType),
...Object.values(panelType),
...Object.values(resourceType)
].includes(view._type)) {
this.shapeCode = view._code;
this.graphType = view._type;
break;
}
if (view._subType) {
this.subType = view._subType;
}
if (view._val) {
this.val = view._val;
}
view = view.parent;
}
}
}
class Controller extends Eventful {
constructor(map) {
super();
this.$map = map;
this.events = map.getEvents();
this.dragHandle = new DragHandle(map, this);
this.selectingHandle = new SelectingHandle(map, this);
this.selectHandle = new SelectHandle(map, this);
this.keyBoardHandle = new KeyBoardHandle(map, this);
this._pan =false;
this._isNotLeftMouse = false;
this._shortcuts = '';
this._distance = 0;
this._target = null;
this.initData();
this.initHandler();
}
initData() {
this.storage = new Storage();
}
initHandler() {
const zr = this.$map.getZr();
const keyupHandle = this.onKeyup.bind(this);
const keydownHandle = this.onKeydown.bind(this);
const dragStartHandle = this.dragHandle.onDragStart;
const draggingHandle = this.dragHandle.onDragging;
const dragEndHandle = this.dragHandle.onDragEnd;
const selectStartHandle = this.selectingHandle.onSelectStart;
const selectingHandle = this.selectingHandle.onSelecting;
const selectEndHandle = this.selectingHandle.onSelectEnd;
const selectedHandle = this.selectHandle.onSelected;
const boardKeyupHandle = this.keyBoardHandle.onKeyup;
const boardKeydownHandle = this.keyBoardHandle.onKeydown;
this.on(this.events.__DragStart, dragStartHandle, this.dragHandle); // 单个元素拖拽
this.on(this.events.__Dragging, draggingHandle, this.dragHandle);
this.on(this.events.__DragEnd, dragEndHandle, this.dragHandle);
this.on(this.events.__SelectStart, selectStartHandle, this.selectingHandle);
this.on(this.events.__Selecting, selectingHandle, this.selectingHandle);
this.on(this.events.__SelectEnd, selectEndHandle, this.selectingHandle);
this.on(this.events.__Selected, selectedHandle, this.selectHandle);
this.enable = function (opts={}) {
const zr = this.$map.getZr();
this._panEnable = opts.panEnable || false;
this._zoomEnable = opts.zoomEnable || false;
this._keyEnable = opts.keyEnable || false;
this._dragEnable = opts.draggle || false;
this._areaSelectEnable = opts.selecting || false;
this._selectEnable = opts.selectable || false;
this._reflectEnable = opts.reflectable || false;
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('globalout', this.mouseup, this);
zr.on('mousewheel', this.mousewheel, this);
zr.dom.addEventListener('keyup', keyupHandle, false);
zr.dom.addEventListener('keydown', keydownHandle, false);
zr.dom.focus();
this.on(this.events.Keyup, boardKeyupHandle, this.keyBoardHandle);
this.on(this.events.Keydown, boardKeydownHandle, this.keyBoardHandle);
};
this.disable = function () {
zr.off('mousedown', this.mousedown);
zr.off('mousemove', this.mousemove);
zr.off('mouseup', this.mouseup);
zr.off('globalout', this.mouseup);
zr.off('mousewheel', this.mousewheel);
zr.dom.removeEventListener('keyup', keyupHandle, false);
zr.dom.removeEventListener('keydown', keydownHandle, false);
this.off(this.events.Keyup, boardKeyupHandle);
this.off(this.events.Keydown, boardKeydownHandle);
};
this.dispose = function () {
zr.off('click', this.click);
zr.off('contextmenu', this.contextmenu);
this.off(this.events.__DragStart, dragStartHandle);
this.off(this.events.__Dragging, draggingHandle);
this.off(this.events.__DragEnd, dragEndHandle);
this.off(this.events.__SelectStart, selectStartHandle);
this.off(this.events.__Selecting, selectingHandle);
this.off(this.events.__SelectEnd, selectEndHandle);
this.off(this.events.__Selected, selectedHandle);
this.disable();
};
zr.on('click', this.click, this);
zr.on('contextmenu', this.contextmenu, this);
}
getKeyStr() {
return this._shortcuts;
}
isSpecialEl(e) {
return ['dragEl', 'selectingEl'].includes(e.subType);
}
limitDrag(e) {
const dx2 = Math.pow(e.dx, 2);
const dy2 = Math.pow(e.dy, 2);
const scale = this.$map.$options.getScaleRate();
const diff = Math.ceil(Math.sqrt(dx2+dy2));
if (scale > 1) {
return true;
} else if (diff > 2/scale) {
return true;
}
return false;
}
mousedown(e) {
const event = new MapEvent(e);
const target = this.$map.getShapeByCode(event.shapeCode);
const zr = this.$map.getZr();
this._x = e.offsetX;
this._y = e.offsetY;
this._pan = false;
this._target = target;
zr.dom.focus();
if (utils.isMobile()) {
if (e.event.touches.length == 1 && this._dragEnable && target) {
this.trigger(this.events.__DragStart, { x: e.offsetX, y: e.offsetY, target });
} else if (e.event.touches.length >= 2) {
const touches = e.event.touches;
const powX = Math.pow(touches[1].clientX-touches[0].clientX, 2);
const powY = Math.pow(touches[1].clientY-touches[0].clientY, 2);
this._distance = Math.sqrt(powX + powY);
}
} else {
this._isNotLeftMouse = eventTool.isMiddleOrRightButtonOnMouseUpDown(e);
if (this._isNotLeftMouse) { // 非左键点击
this.$map.setCursorStyle('grab'); // 鼠标状态
} else {
this.selectingHandle.clear(e);
if (this.isSpecialEl(event)) { return; }
if (this._dragEnable && target) {
this.trigger(this.events.__DragStart, { x: e.offsetX, y: e.offsetY, target });
} else if (this._areaSelectEnable && !event.graphType) {
this.trigger(this.events.__SelectStart, { x: e.offsetX, y: e.offsetY});
}
}
}
}
mousemove(e) {
const oldX = this._x;
const oldY = this._y;
const dx = Math.round(e.offsetX - this._x);
const dy = Math.round(e.offsetY - this._y);
const target = this._target;
this._x = e.offsetX;
this._y = e.offsetY;
this._preventDefaultMouseMove && eventTool.stop(e.event);
if (utils.isMobile()) {
if (target && e.event.touches.length == 1) {
if (this._dragEnable && this.dragHandle.isDragging()) {
if (this.limitDrag({dx, dy})) {
this.trigger(this.events.__Dragging, { dx, dy });
if (this._reflectEnable) {
this.trigger(this.events.Reflect, {dx, dy});
}
} else {
this._x = oldX;
this._y = oldY;
}
}
} else if (e.event.touches.length == 2) {
const touches = e.event.touches;
const powX = Math.pow(touches[1].clientX-touches[0].clientX, 2);
const powY = Math.pow(touches[1].clientY-touches[0].clientY, 2);
const distance = Math.sqrt(powX + powY);
const wheelDelta = distance - this._distance;
const originX = Math.ceil((touches[1].clientX+touches[0].clientX)/2);
const originY = Math.ceil((touches[1].clientY+touches[0].clientY)/2);
if (Math.abs(wheelDelta) >= 10) {
const scale = wheelDelta > 0? 1: -1;
this.trigger(this.events.__Zoom, {type: this.events.__Zoom, scale, originX, originY });
}
this._distance = distance;
} else if (e.event.touches.length > 2) {
if (this._panEnable) {
if (dx**2+dy**2 > 8) {
this._pan = true;
}
this.$map.setCursorStyle('grabbing');
this.trigger(this.events.__Pan, { dx, dy, oldX, oldY, newX: this._x, newY: this._y });
}
}
} else {
if (this._isNotLeftMouse) {
if (this._panEnable) {
if (dx**2+dy**2 > 8) {
this._pan = true;
}
this.$map.setCursorStyle('grabbing');
this.trigger(this.events.__Pan, { dx, dy, oldX, oldY, newX: this._x, newY: this._y });
}
} else {
if (this._target && this._dragEnable && this.dragHandle.isDragging()) {
if (this.limitDrag({dx, dy})) {
this.trigger(this.events.__Dragging, { dx, dy });
if (this._reflectEnable) {
this.trigger(this.events.Reflect, {dx, dy});
}
} else {
this._x = oldX;
this._y = oldY;
}
} else if (this._areaSelectEnable && this.selectingHandle.isSelecting()) {
this.trigger(this.events.__Selecting, { x: e.offsetX, y: e.offsetY });
}
}
}
}
mouseup(e) {
const target = this._target;
if (this._isNotLeftMouse) {
this._isNotLeftMouse = false;
this.$map.setCursorStyle('default');
} else {
if (this._dragEnable && this.dragHandle.isDragging()) {
this.trigger(this.events.__DragEnd, {x: e.offsetX, y: e.offsetY});
} else if (this._areaSelectEnable && this.selectingHandle.isSelecting()) {
this.trigger(this.events.__SelectEnd, { x: e.offsetX, y: e.offsetY });
}
if (this._selectEnable && target) {
this.trigger(this.events.__Selected, {target });
}
}
this._target = null;
}
mousewheel(e) {
const zoomEnable = this._zoomEnable;
const wheelDelta = e.wheelDelta;
const originX = Math.ceil(e.offsetX);
const originY = Math.ceil(e.offsetY);
if (wheelDelta === 0 || !zoomEnable) {
return;
}
if (zoomEnable) {
eventTool.stop(e.event);
let scale = 1;
if (wheelDelta > 0) {
scale = 1;
this.$map.setCursorStyle('zoom-in');
} else if (wheelDelta < 0) {
scale = -1;
this.$map.setCursorStyle('zoom-out');
}
this.trigger(this.events.__Zoom, {type: this.events.__Zoom, scale, originX, originY });
}
}
click(e) {
const event = new MapEvent(e);
if (!event.graphType) {
this.selectHandle.clear();
this.selectingHandle.clear();
this.clear();
}
this.trigger(this.events.Selected, event);
}
contextmenu(e) {
eventTool.stop(e.event);
const event = new MapEvent(e);
if (!this._pan) {
this.trigger(this.events.ContextMenu, event);
}
this._pan = false;
}
onKeydown(e) {
let shortcuts = e.key;
if (e.altKey && e.key != 'Alt') {
shortcuts = `Alt_${shortcuts}`;
}
if (e.shiftKey && e.key != 'Shift') {
shortcuts = `Shift_${shortcuts}`;
}
if (e.ctrlKey && e.key != 'Control') {
shortcuts = `Control_${shortcuts}`;
}
this._shortcuts = shortcuts;
this.trigger(this.events.Keydown, {key: shortcuts});
}
onKeyup(e) {
this._shortcuts = '';
}
clear() {
this.storage.clear();
this.storage.clearClipboard();
this._pan =false;
}
}
export default Controller;

View File

@ -0,0 +1,55 @@
export default class DragHandle {
constructor(map, controller) {
this.$zr = map.getZr();
this.$controller = controller;
this.$options = map.getOptions();
this.$painter = map.getPainter();
this.dragging = false;
}
isDragging() {
return this.dragging;
}
onDragStart(e) {
if (e.target && this.$controller.storage.has(e.target.model.code)) {
this.dragging = true;
}
}
onDragging(e) {
const dx = e.dx;
const dy = e.dy;
const scaleRate = this.$options.getScaleRate();
e.dx = dx / scaleRate;
e.dy = dy / scaleRate;
if (this.dragging) {
this.$controller.storage.values().forEach(dragTarget => {
if (dragTarget) {
if (dragTarget.hover) {
this.$painter.hoverLevel.remove(dragTarget.hover);
dragTarget.hover = null;
}
if (dragTarget.instance.doInactive) {
dragTarget.instance.doInactive(this.$zr);
}
if (dragTarget.instance.dragging) {
dragTarget.instance.dragging(e);
}
if (dragTarget.instance.doActive) {
dragTarget.instance.doActive(this.$zr);
}
}
});
}
}
onDragEnd(e) {
this.dragging = false;
}
}

View File

@ -0,0 +1,127 @@
import _ from 'lodash';
import * as graphic from '../graph/graphic';
import * as eventTool from 'zrender/src/core/event';
import panelType from '../constant/panelType';
export default class ImageDraggable extends graphic.Group {
constructor(handle, draggle=false) {
super();
this.draggle = draggle;
this.handle = handle;
this.style = handle.$map.getDefaultStyleDict();
this.invTransform = [1, 0, 0, 1, 0, 0];
this.target = null;
this.shapes = [];
this.offset = null;
this.r = 2;
if (this.draggle &&
this.handle.e.target &&
this.handle.e.target.instance) {
const bound = this.handle.e.target.instance.getBoundingRect();
const r = (this.handle.e.target.model.width||this.r)+3;
this.shapes.push(this.newShape({ cx: bound.x, cy: bound.y, r}));
this.shapes.push(this.newShape({ cx: bound.x+bound.width, cy: bound.y, r}));
this.shapes.push(this.newShape({ cx: bound.x+bound.width, cy: bound.y+bound.height, r}));
this.shapes.push(this.newShape({ cx: bound.x, cy: bound.y+bound.height, r}));
this.shapes.forEach(shape => { this.add(shape); });
}
}
newShape(shape) {
return new graphic.Circle({
_subType: 'dragEl',
zlevel: 1,
z: 999999,
draggable: false,
cursor: 'crosshair',
shape,
style: {
opacity: 0.5,
fill: '#0000ff'
},
onmousedown: this.mousedown.bind(this),
onmousemove: _.throttle(this.mousemove.bind(this), 100),
onmouseup: this.mouseup.bind(this)
});
}
updateShapeRect(dx, dy) {
const index = this.shapes.indexOf(this.target);
if (index >= 0) {
this.shapes[(3-index)%4].setShape({cx: this.shapes[(3-index)%4].shape.cx+dx});
this.shapes[(5-index)%4].setShape({cy: this.shapes[(5-index)%4].shape.cy+dy});
}
return this.getBoundingRect().clone();
}
updateModel(target, bound) {
target.model.width = bound.width-this.r*2;
target.model.height = bound.height-this.r*2;
}
setShape(dx, dy) {
const bound = this.updateShapeRect(dx, dy);
if (this.handle.e.target &&
this.handle.e.target.instance) {
this.handle.e.target.model.point = { x: bound.x+this.r, y: bound.y+this.r };
this.handle.e.target.instance.doInactive(this.handle.$zr);
this.handle.e.target.instance.setShape(this.handle.e.target.model);
this.handle.e.target.instance.doActive(this.handle.$zr);
}
}
mousedown(e) {
if (e.target && ['dragEl'].includes(e.target._subType)) {
if (!eventTool.isMiddleOrRightButtonOnMouseUpDown(e)) {
this.target = e.target;
this.offset = {x: e.offsetX, y: e.offsetY};
this.setDraggable(true);
}
}
}
mousemove(e) {
eventTool.stop(e.event);
if (this.target &&
this.handle.e.target &&
this.offset) {
if (!eventTool.isMiddleOrRightButtonOnMouseUpDown(e)) {
const type = this.handle.e.target.model._type;
const dx = Math.round(e.offsetX-this.offset.x);
const dy = Math.round(e.offsetY-this.offset.y);
this.setShape(...this.handle.normalizedDiff(dx, [panelType.Resource].includes(type)? dx:dy));
this.handle.$controller.trigger(this.handle.$controller.events.Reflect, {dx, dy});
this.offset = {x: e.offsetX, y: e.offsetY};
}
}
}
mouseup(e) {
if (this.target &&
this.handle.e.target &&
this.offset) {
const type = this.handle.e.target.model._type;
const dx = Math.round(e.offsetX-this.offset.x);
const dy = Math.round(e.offsetY-this.offset.y);
this.setShape(...this.handle.normalizedDiff(dx, [panelType.Resource].includes(type)? dx:dy));
this.handle.$controller.trigger(this.handle.$controller.events.Reflect, {dx, dy});
this.setDraggable(false);
this.offset = null;
this.target = null;
}
}
setDraggable(draggable) {
this.shapes.forEach(shape => {
shape.attr('draggable', draggable);
});
}
}

View File

@ -0,0 +1,118 @@
import _ from 'lodash';
import * as graphic from '../graph/graphic';
import * as eventTool from 'zrender/src/core/event';
import panelType from '../constant/panelType';
export default class LineDraggable extends graphic.Group {
constructor(handle, draggle=true) {
super();
this.draggle = draggle;
this.handle = handle;
this.style = handle.$map.getDefaultStyleDict();
this.invTransform = [1, 0, 0, 1, 0, 0];
this.target = null;
this.shapes = [];
this.line = null;
this.r = 2;
this.offset = null;
if (this.draggle && this.handle.e.target && this.handle.e.target.model.points) {
this.handle.e.target.model.points.forEach((elem, index) => {
const r = (this.handle.e.target.model.width||this.r)+1;
this.shapes.push(this.newShape({ cx: elem.x, cy: elem.y, r }));
this.add(this.shapes[index]);
});
this.line = new graphic.Line({
_subType: 'dragEl',
zlevel: 1,
z: 999990,
shape: {x1: 0, y1: 0, x2: 0, y2: 0 },
style: {
opacity: 0.8,
lineWidth: this.style[panelType.LinePipe].line.lineWidth,
stroke: '#ff0000'
}
});
this.add(this.line);
}
}
newShape(shape) {
return new graphic.Circle({
_subType: 'dragEl',
zlevel: 1,
z: 999999,
draggable: false,
cursor: 'crosshair',
shape,
style: {
opacity: 0.5,
fill: '#0000ff'
},
onmousedown: this.mousedown.bind(this),
onmousemove: _.throttle(this.mousemove.bind(this), 100),
onmouseup: this.mouseup.bind(this)
});
}
setShape(e) {
const dx = Math.round(e.offsetX-this.offset.x);
const dy = Math.round(e.offsetY-this.offset.y);
if (this.handle.e.target && this.handle.e.target.instance) {
this.offset = {x: e.offsetX, y: e.offsetY};
this.handle.e.target.instance.doInactive(this.handle.$zr);
this.handle.e.target.instance.setShape(this.handle.e.target.model);
this.handle.e.target.instance.doActive(this.handle.$zr);
this.handle.$controller.trigger(this.handle.$controller.events.Reflect, {dx, dy});
}
}
mousedown(e) {
this.offset = {x: e.offsetX, y: e.offsetY};
if (e.target && ['dragEl'].includes(e.target._subType)) {
this.target = e.target;
if (!eventTool.isMiddleOrRightButtonOnMouseUpDown(e)) {
this.setDraggable(true);
}
}
}
mousemove(e) {
eventTool.stop(e.event);
if (this.target && this.handle.e.target) {
if (!eventTool.isMiddleOrRightButtonOnMouseUpDown(e) ) {
this.handle.e.target.model.points = this.shapes.map(elem => {
const position = elem.position || [0, 0];
const x = elem.shape.cx + position[0];
const y = elem.shape.cy + position[1];
return {x, y};
});
this.setShape(e);
}
}
}
mouseup(e) {
if (this.target && this.handle.e.target) {
this.handle.e.target.model.points = this.shapes.map(elem => {
const position = elem.position || [0, 0];
const x = elem.shape.cx + position[0];
const y = elem.shape.cy + position[1];
return {x, y};
});
this.setShape(e);
this.setDraggable(false);
this.line.setShape({x1: 0, y1: 0, x2: 0, y2: 0 });
this.target = null;
}
}
setDraggable(draggable) {
this.shapes.forEach(shape => {
shape.attr('draggable', draggable);
});
}
}

View File

@ -0,0 +1,73 @@
import * as graphic from '../graphic';
class Parser {
constructor(graph) {
this.__graph = graph;
}
createShape(model, opts) {
const option = Object.assign(opts, {
zlevel: model.zlevel,
z: model.z,
z2: (model.layer || model.z2) + opts.z2,
silent: opts.silent || false,
cursor: opts.cursor ? opts.cursor : this.__graph._is ? 'default' : 'pointer'
});
const shape = new graphic[opts.type](option);
this.__graph.add(shape);
return shape;
}
isShapeLeaf(obj) {
return obj && obj.name && obj.type && Object.keys(graphic).includes(obj.type);
}
buildSTL(model, template, out = {}) {
Object.keys(template).forEach(attr => {
if (!['__ctx'].includes(attr)) {
const leaf = template[attr];
if (leaf instanceof Function) {
out[attr] = leaf(model);
} else if (leaf instanceof Array) {
out[attr] = leaf.map(el => {
return el instanceof Array
? this.buildSTL(model, el, [])
: el instanceof Object
? this.buildSTL(model, el, {})
: el;
});
} else if (leaf instanceof Object) {
out[attr] = this.buildSTL(model, leaf, {});
} else {
out[attr] = leaf;
}
}
});
return out;
}
parse2Shape(model, stl, out = {}) {
if (stl instanceof Array) {
stl.forEach(elem => {
const shape = this.parse2Shape(model, elem, out);
out[shape.name] = shape;
});
} else if (Object instanceof Object) {
if (this.isShapeLeaf(stl)) {
return this.createShape(model, stl);
} else {
Object.keys(stl || {}).forEach(attr => { out[attr] = this.parse2Shape(model, stl[attr]); });
}
}
return out;
}
parse(template, model) {
return this.parse2Shape(model, this.buildSTL(model, template));
}
}
export default Parser;

View File

@ -0,0 +1,85 @@
import * as graphic from '../graphic';
class State extends graphic.Group {
constructor(shape, is) {
super();
if (is) {
this._subType = shape.model._type;
this._val = shape.model.code;
} else {
this._code = shape.model.code;
this._type = shape.model._type;
}
this._caches = {};
this._shape = shape;
this._is = is;
this._origin = null;
this._rotation = null;
this._scale = [1, 1];
}
onFrame(delta) {
}
setShape(model) {
this.removeAll();
this.parser.parse(this.$template, model, this.$elMap);
this.transformed(model);
}
setState(state) {
if (this.$template.__ctx && this.$template.__ctx.$doUpdate) {
this.$template.__ctx.$doUpdate({model: this._shape.model, state});
}
}
doActive(zr) {
if (this.$template.__ctx && this.$template.__ctx.$doActive) {
this.$template.__ctx.$doActive(zr);
}
}
doInactive(zr) {
if (this.$template.__ctx && this.$template.__ctx.$doInactive) {
this.$template.__ctx.$doInactive(zr);
}
}
dragging(e) {
if (this.$template.__ctx && this.$template.__ctx.$doDragging) {
this.$template.__ctx.$doDragging(this._shape.model);
}
this.setShape(this._shape.model);
}
transformed({origin, rotation, scale}) {
this._origin = origin;
this._rotation = rotation;
this._scale = scale||[1, 1];
this.traverse(el => {
if (!(el instanceof graphic.Group)) {
el.attr('origin', origin);
el.attr('rotation', rotation);
el.attr('scale', scale);
}
}, this);
}
traversed(elMap, cb) {
Object.values(elMap).forEach(el => {
if (el) {
if (this.parser.isShapeLeaf(el)) {
cb(el);
} else {
this.traversed(el, cb);
}
}
});
}
}
export default State;

View File

@ -0,0 +1,81 @@
// import Animation from 'zrender/src/animation/Animation';
import Parser from './core/parser';
import State from './core/state';
const lifeCycleHookList = ['onload', 'reload'];
const actionHookList = ['doUpdate', 'doActive', 'doInactive'];
function noop () {}
class Graph extends State {
constructor(options, shape, is) {
super(shape, is);
this.invTransform = [1, 0, 0, 1, 0, 0];
this.parser = new Parser(this);
this.reload(options);
// this.$animation = new Animation({onFrame: this.onFrame });
// this.$animation.start();
if (this.$template.__ctx.$onload) this.$template.__ctx.$onload();
}
reload(options) {
const index = options.cacheId;
const cache = this._caches[index]; // 获取缓存
const shapes = [];
this.removeAll();
if (cache) {
this.$template = cache.template;
this.$elMap = cache.elMap;
cache.shapes.forEach(shape => { this.add(shape); });
} else {
this.$template = this.defineTemplate(options); // 生成模板
this.$elMap = this.compile(this.$template, this._shape);
this.traverse(shape=> { shapes.push(shape); }, this);
this._caches[index] = { template: this.$template, elMap: this.$elMap, shapes };
}
this.transformed(this._shape.model);
// this.setState(this._shape._state);
if (this.$template.__ctx.$reload) this.$template.__ctx.$reload();
}
defineTemplate (options) {
const template = options.template;
const methods = options.methods||{};
const incidents = options.incidents||{};
const actions = options.actions||{};
const ctx = Object.create(Object.assign(options.data(), {$vm: this}));
Object.keys(methods).forEach(name => {
ctx[name] = (methods[name] || noop).bind(ctx);
});
Object.keys(incidents).forEach(name => {
ctx[`$${name}`] = (incidents[name] || noop).bind(ctx);
});
actionHookList.forEach(name => {
ctx[`$${name}`] = (actions[name] || noop).bind(ctx);
});
lifeCycleHookList.forEach(name => {
ctx[`$${name}`] = (options[name] || noop).bind(ctx);
});
return Object.assign(template.apply(ctx), { __ctx: ctx });
}
compile(template, shape) {
return this.parser.parse(template, shape.model, {});
}
}
export default Graph;

View File

@ -0,0 +1,32 @@
export {default as Group} from 'zrender/src/container/Group';
export {default as Image} from 'zrender/src/graphic/Image';
export {default as Text} from 'zrender/src/graphic/Text';
export {default as Arc} from 'zrender/src/graphic/shape/Arc';
export {default as BezierCurve} from 'zrender/src/graphic/shape/BezierCurve';
export {default as Circle} from 'zrender/src/graphic/shape/Circle';
export {default as Droplet} from 'zrender/src/graphic/shape/Droplet';
export {default as Ellipse} from 'zrender/src/graphic/shape/Ellipse';
export {default as Heart} from 'zrender/src/graphic/shape/Heart';
export {default as Isogon} from 'zrender/src/graphic/shape/Isogon';
export {default as Line} from 'zrender/src/graphic/shape/Line';
export {default as Polygon} from 'zrender/src/graphic/shape/Polygon';
export {default as Polyline} from 'zrender/src/graphic/shape/Polyline';
export {default as Rect} from 'zrender/src/graphic/shape/Rect';
export {default as Ring} from 'zrender/src/graphic/shape/Ring';
export {default as Rose} from 'zrender/src/graphic/shape/Rose';
export {default as Sector} from 'zrender/src/graphic/shape/Sector';
export {default as Star} from 'zrender/src/graphic/shape/Star';
export {default as Trochoid} from 'zrender/src/graphic/shape/Trochoid';
export {default as Hover} from './shape/Hover';
export {default as Digit} from './shape/Digit';
export {default as Arrow} from './shape/Arrow';
export {default as ArrowLine} from './shape/ArrowLine';
export {default as Sausage} from './shape/Sausage';
export {default as Pointer} from './shape/Pointer';
export {default as Table} from './shape/Table/table';
export {default as CurvedScale} from './shape/CurvedScale/curvedScale';
export {default as LinearScale} from './shape/LinearScale/linearScale';
export {default as Coordinate} from './shape/Coordinate/Coordinate';
export {default as Svg} from './shape/Svg';

View File

@ -0,0 +1,49 @@
import Path from 'zrender/src/graphic/Path';
export default Path.extend({
type: 'arrow',
shape: {
x: 0,
y: 0,
w: 3,
r: 6,
toward: null
},
style: {
stroke: '#000',
fill: null
},
buildPath: function (ctx, shape) {
var x = shape.x;
var y = shape.y;
var r = shape.r;
var w = shape.w;
switch (shape.toward) {
case 'up':
ctx.moveTo(x - w, y + r);
ctx.lineTo(x - w, y);
ctx.lineTo(x - w - r, y);
ctx.lineTo(x, y - r);
ctx.lineTo(x + w + r, y);
ctx.lineTo(x + w, y);
ctx.lineTo(x + w, y + r);
ctx.closePath();
break;
case 'down':
ctx.moveTo(x - w, y - r);
ctx.lineTo(x - w, y);
ctx.lineTo(x - w - r, y);
ctx.lineTo(x, y + r);
ctx.lineTo(x + w + r, y);
ctx.lineTo(x + w, y);
ctx.lineTo(x + w, y - r);
ctx.closePath();
break;
}
}
});

View File

@ -0,0 +1,48 @@
import Path from 'zrender/src/graphic/Path';
export default Path.extend({
type: 'arrow-line',
shape: {
x: 0,
y: 0,
l: 15,
r: 5,
isLeft: true,
toLeft: true
},
style: {
stroke: '#000',
fill: null
},
buildPath: function (ctx, shape) {
var x = shape.x;
var y = shape.y;
var l = shape.l;
var r = shape.r;
var d = shape.toLeft ? 1: -1;
if (shape.isLeft && shape.toLeft || !shape.isLeft && !shape.toLeft) {
ctx.moveTo(x, y);
ctx.lineTo(x, y - r);
ctx.lineTo(x - l*d, y - r);
ctx.lineTo(x - l*d - r*d, y);
ctx.lineTo(x - l*d, y + r);
ctx.lineTo(x, y + r);
ctx.closePath();
}
if (shape.isLeft && !shape.toLeft || !shape.isLeft && shape.toLeft) {
ctx.moveTo(x, y);
ctx.lineTo(x + r*d, y - r);
ctx.lineTo(x + r*d + l*d, y - r);
ctx.lineTo(x + r*d + l*d, y + r);
ctx.lineTo(x + r*d, y + r);
ctx.closePath();
}
}
});

View File

@ -0,0 +1,395 @@
import * as graphic from '../../graphic';
import LineView from './lineView';
export default class LineCoordinate extends graphic.Group {
constructor(option) {
super();
this._option = {
zlevel: option.zlevel || 0,
z: option.z || 0,
z2: option.z2 || 0,
shape: {
x: 0,
y: 0,
xLength: 100,
yLength: 60,
...option.shape
},
style: {
globalStyle: {
lineWidth: 0.2,
color: '#000',
...option.style.globalStyle
},
xAxis: {
show: true,
type: 'category',
boundaryGap: 2,
name: option.style.xAxis.name,
nameGap: {
left: 8,
...option.style.xAxis.nameGap
},
axisLine: {
symbol: true,
style: {
},
...option.style.xAxis.axisLine
},
axisTick: {
show: true,
splitNumber: 0,
inside: true,
style: {
},
...option.style.xAxis.axisTick
},
axisLabel: {
show: true,
distance: 4,
verticalAlign: 'top',
style: {
},
...option.style.xAxis.axisLabel
},
data: option.style.xAxis.data||[]
},
yAxis: {
show: true,
type: 'category',
name: option.style.yAxis.name,
boundaryGap: 3,
nameGap: {
left: 2,
...option.style.yAxis.nameGap
},
axisLine: {
symbol: true,
style: {
},
...option.style.yAxis.axisLine
},
axisTick: {
show: true,
splitNumber: 5,
inside: true,
style: {
},
...option.style.yAxis.axisTick
},
axisLabel: {
show: true,
distance: 2,
verticalAlign: 'top',
style: {
},
...option.style.yAxis.axisLabel
},
data: option.style.yAxis.data||[]
},
series: {
type: 'line',
data: [],
style: {
},
...option.style.series
}
}
};
this.lineView = new LineView(this);
this.render();
}
render() {
this.removeAll();
this._createCoordinate(this._option);
this._createXTicks(this._option);
this._createYTicks(this._option);
this._createData(this._option);
}
_createCoordinate(option) {
const {shape, style} = option;
var xAxis = style.xAxis;
var yAxis = style.yAxis;
var xLength = shape.xLength;
var yLength = shape.yLength;
var x = shape.x;
var y = shape.y;
if (xAxis.show) {
const line = new graphic.Line({
zlevel: this._option.zlevel,
z: this._option.z,
z2: this._option.z2,
...this._transformation(),
shape: {
x1: x,
y1: y,
x2: x + xLength,
y2: y
}
});
line.setStyle({lineCap: 'square', ...style.globalStyle, ...xAxis.axisLine });
this.add(line);
}
if (yAxis.show) {
const line = new graphic.Line({
zlevel: this._option.zlevel,
z: this._option.z,
z2: this._option.z2,
...this._transformation(),
shape: {
x1: x,
y1: y,
x2: x,
y2: y - yLength
}
});
line.setStyle({lineCap: 'square', ...style.globalStyle, ...yAxis.axisLine });
this.add(line);
}
}
_createXTicks(option) {
const {shape, style} = option;
const xAxis= style.yAxis;
if (xAxis.axisLine.symbol) {
const x = shape.x + shape.xLength;
const y = shape.y;
const arrows = new graphic.Polygon({
zlevel: this._option.zlevel,
z: this._option.z,
z2: this._option.z2,
...this._transformation(),
shape: {
points: [[x + 4, y], [x - 1, y + 1], [x, y], [x - 1, y- 1], [x + 4, y]],
smooth: 0
}
});
arrows.setStyle({ ...style.globalStyle, ...xAxis.axisTick.style });
this.add(arrows);
}
if (xAxis.name) {
const label = new graphic.Text({
zlevel: this._option.zlevel,
z: this._option.z,
z2: this._option.z2,
...this._transformation(),
style: {
textVerticalAlign: 'middle',
textAlign: 'left',
text: xAxis.name,
fontSize: 5,
x: shape.x + shape.xLength + xAxis.nameGap.left,
y: shape.y,
textFill: { ...style.globalStyle, ...xAxis.axisTick.style }
}
});
this.add(label);
}
const scale = (xAxis.data.length - 1) * xAxis.axisTick.splitNumber;
const dataNum = scale + xAxis.boundaryGap;
const num = shape.xLength / dataNum;
const x = shape.x;
const y = shape.y;
let dataIndex = 0;
for (let index = 0; index < dataNum; index++) {
if (xAxis.axisTick.show) {
const spliceLine = new graphic.Line({
zlevel: this._option.zlevel,
z: this._option.z,
z2: this._option.z2,
...this._transformation(),
shape: {
x1: x + (num * (index + 1)),
y1: y,
x2: x + (num * (index + 1)),
y2: y - 2
}
});
if (index <= scale) {
spliceLine.setStyle({ ...style.globalStyle, ...xAxis.axisTick.style });
} else {
spliceLine.setStyle({ lineWidth: 0 });
}
this.add(spliceLine);
}
if (xAxis.axisLabel.show &&
xAxis.axisTick.splitNumber && (
index % xAxis.axisTick.splitNumber) == 0) {
const label = new graphic.Text({
zlevel: this._option.zlevel,
z: this._option.z,
z2: this._option.z2,
...this._transformation(),
style: {
textVerticalAlign: 'middle',
textAlign: 'center',
text: xAxis.data[dataIndex],
fontSize: 5,
x: x + (num * (index + 1)),
y: y + xAxis.axisLabel.distance,
textFill: { ...style.globalStyle, ...xAxis.axisTick.style }
}
});
this.add(label);
dataIndex++;
}
}
}
_createYTicks(option) {
const {style, shape} = option;
const yAxis= style.yAxis;
if (yAxis.axisLine.symbol) {
const x = shape.x;
const y = shape.y - shape.yLength;
const arrows = new graphic.Polygon({
zlevel: this._option.zlevel,
z: this._option.z,
z2: this._option.z2,
...this._transformation(),
shape: {
points: [[x, y - 4], [x + 1, y + 1], [x, y], [x - 1, y + 1], [x, y - 4]],
smooth: 0
}
});
arrows.setStyle({ ...style.globalStyle, ...yAxis.axisTick.style});
this.add(arrows);
}
if (yAxis.name) {
const label = new graphic.Text({
zlevel: this._option.zlevel,
z: this._option.z,
z2: this._option.z2,
...this._transformation(),
style: {
textVerticalAlign: 'middle',
textAlign: 'left',
text: yAxis.name,
fontSize: 5,
x: shape.x + yAxis.nameGap.left,
y: shape.y - shape.yLength,
textFill: { ...style.globalStyle, ...yAxis.axisTick.style}
}
});
this.add(label);
}
const scale = (yAxis.data.length - 1) * yAxis.axisTick.splitNumber;
const dataNum = scale + yAxis.boundaryGap;
const num = shape.yLength / dataNum;
const x = shape.x;
const y = shape.y;
let dataIndex = 0;
for (let index = 0; index < dataNum; index++) {
if (yAxis.axisTick.show) {
const spliceLine = new graphic.Line({
zlevel: this._option.zlevel,
z: this._option.z,
z2: this._option.z2,
...this._transformation(),
shape: {
x1: x,
y1: y - (num * (index + 1)),
x2: x + 2,
y2: y - (num * (index + 1))
}
});
if (index <= scale) {
spliceLine.setStyle({ ...style.globalStyle, ...yAxis.axisTick.style });
} else {
spliceLine.setStyle({ lineWidth: 0 });
}
this.add(spliceLine);
}
if (yAxis.axisLabel.show &&
yAxis.axisTick.splitNumber && (
index % yAxis.axisTick.splitNumber) == 0) {
const label = new graphic.Text({
zlevel: this._option.zlevel,
z: this._option.z,
z2: this._option.z2,
...this._transformation(),
style: {
textVerticalAlign: 'middle',
textAlign: 'right',
text: yAxis.data[dataIndex],
fontSize: 5,
x: x - yAxis.axisLabel.distance,
y: y - (num * (index + 1)),
fill: { ...style.globalStyle, ...yAxis.axisTick.style }
}
});
this.add(label);
dataIndex++;
}
}
}
_createData(option) {
const series = option.style.series;
switch (series.type) {
case 'line': return this.lineView.render(option);
}
}
_transformation() {
var parent = this.parent||{};
var origin = parent._origin||null;
var rotation = parent._rotation||null;
var scale = parent._scale||[1, 1];
return { origin, rotation, scale };
}
_traverse(target, attr) {
for (var key in attr) {
if (!(attr[key] instanceof Object) || !attr[key]) {
target[key] = attr[key];
} else {
this._traverse(target[key], attr[key]);
}
}
}
setShape(objs) {
this._traverse(this._option.shape, objs);
this.render();
}
setStyle(objs) {
this._traverse(this._option.style, objs);
this.render();
}
dragging(e) {
this.traverse(el => {
if (el instanceof graphic.Text) {
el.setStyle({
x: el.style.x + e.dx,
y: el.style.y + e.dy
});
} else if (el instanceof graphic.Line) {
el.setShape({
x1: el.shape.x1 + e.dx,
y1: el.shape.y1 + e.dy,
x2: el.shape.x2 + e.dx,
y2: el.shape.y2 + e.dy
});
} else if (el instanceof graphic.Polygon) {
el.setShape({
points: el.shape.points.map(it => { return [it[0]+e.dx, it[1]+e.dy]; })
});
}
}, this);
}
}

View File

@ -0,0 +1,39 @@
import * as graphic from '../../graphic';
export default class LineView {
constructor(coordinate) {
this.coordinate = coordinate;
}
render(option) {
const {series, xAxis, yAxis, globalStyle} = option.style;
if (series.type == 'line') {
const shape = option.shape;
const dataList = [];
const scalex = (xAxis.data.length - 1) * xAxis.axisTick.splitNumber;
const dataNumx = scalex + xAxis.boundaryGap;
const numx = (shape.xLength / dataNumx);
const scaley = (yAxis.data.length - 1) * yAxis.axisTick.splitNumber;
const dataNumy = scaley + yAxis.boundaryGap;
const numy = shape.yLength / dataNumy;
const seriesStyle = series.style;
series.data.forEach(point => {
const data = [shape.x + (numx * ((point[0] * xAxis.axisTick.splitNumber) + 1)), shape.y - (numy * (point[1] + 1))];
dataList.push(data);
});
const line = new graphic.Polygon({
zlevel: option.zlevel,
z: option.z,
z2: option.z2,
...this.coordinate._transformation(),
shape: {
points: dataList,
smooth: 0
}
});
line.setStyle({ ...globalStyle, ...seriesStyle });
this.coordinate.add(line);
}
}
}

View File

@ -0,0 +1,457 @@
import * as graphic from '../../graphic';
export default class CurvedScale extends graphic.Group {
constructor(option) {
super();
this._option = {
zlevel: option.zlevel || 0,
z: option.z || 0,
z2: option.z2 || 0,
cursor: option.cursor||null,
silent: option.silent||false,
shape: {
cx: 0,
cy: 0,
r: 50,
min: 0,
max: 100,
startAngle: 0,
endAngle: Math.PI,
splitNumber: 10,
clockwise: false,
value: 0,
...option.shape
},
style: {
axisLine: {
show: true,
lineStyle: {
color: [[0.2, '#91c7ae'], [0.8, '#63869e'], [1, '#c23531']],
width: 2,
shadowColor: '#fff',
shadowBlur: 10
},
...option.style.axisLine
},
splitLine: {
show: true,
length: 30,
lineStyle: {
width: 2,
stroke: 'auto'
},
...option.style.splitLine
},
axisTick: {
show: true,
splitNumber: 5,
length: 8,
lineStyle: {
width: 1,
stroke: 'auto',
shadowColor: '#fff',
shadowBlur: 10
},
...option.style.axisTick
},
axisLabel: {
show: true,
distance: 5,
textStyle: {
fontSize: 18,
textFill: 'auto'
},
...option.style.axisLabel
},
pointer: {
show: true,
width: 8,
length: '80%',
fill: 'auto',
...option.style.pointer
}
}
};
this.render();
}
render() {
this.removeAll();
var axisLine = this._option.style.axisLine;
var showAxis = axisLine.show;
var axisLineStyle = axisLine.lineStyle;
var axisColorList = axisLineStyle.color;
var axisLineWidth = axisLineStyle.width;
var shape = this._option.shape;
var clockwise = shape.clockwise;
var startAngle = -shape.startAngle / 180 * Math.PI;
var endAngle = -shape.endAngle / 180 * Math.PI;
var angleRangeSpan = (endAngle - startAngle) % (Math.PI * 2);
var prevEndAngle = startAngle;
if (showAxis) {
for (var i = 0; i < axisColorList.length; i++) {
var percent = Math.min(Math.max(axisColorList[i][0], 0), 1);
var angle = startAngle + angleRangeSpan * percent;
var sector = new graphic.Sector({
zlevel: this._option.zlevel,
z: this._option.z,
z2: this._option.z2,
cursor: this._option.cursor,
silent: this._option.silent,
...this._transformation(),
shape: {
startAngle: prevEndAngle,
endAngle: angle,
cx: shape.cx,
cy: shape.cy,
clockwise: false,
r0: shape.r - axisLineWidth,
r: shape.r
}
});
sector.setStyle({
fill: axisColorList[i][1],
color: axisLine.color,
borderWidth: axisLine.borderWidth,
borderColor: axisLine.borderColor
});
this.add(sector);
prevEndAngle = angle;
}
}
var getColor = function (percent) {
percent = clockwise? percent : 1 - percent;
if (percent <= 0) {
return axisColorList[0][1];
}
for (var i = 0; i < axisColorList.length; i++) {
if (axisColorList[i][0] >= percent &&
(i === 0 ? 0 : axisColorList[i - 1][0]) < percent
) {
return axisColorList[i][1];
}
}
return axisColorList[i - 1][1];
};
if (!clockwise) {
[startAngle, endAngle] = [endAngle, startAngle];
}
this._createTicks({startAngle, endAngle, getColor});
this._createPointer({startAngle, endAngle, getColor});
}
_createTicks({startAngle, endAngle, getColor}) {
var shape = this._option.shape;
var x = shape.cx;
var y = shape.cy;
var r = shape.r;
var minVal = parseFloat(shape.min);
var maxVal = parseFloat(shape.max);
var splitNumber = shape.splitNumber;
var axisLabel = this._option.style.axisLabel;
var axisLabelShow = axisLabel.show;
var axisLabelDistance = axisLabel.distance;
var axisLabelStyle = axisLabel.textStyle;
var axisTick = this._option.style.axisTick;
var axisTickLen = parsePercent(axisTick.length, r);
var axisTickLineStyle = axisTick.lineStyle;
var axisTickShow = axisTick.show;
var subSplitNumber = axisTick.splitNumber;
var splitLine = this._option.style.splitLine;
var splitLineLen = parsePercent(splitLine.length, r);
var splitLineStyle = splitLine.lineStyle;
var splitLineShow = splitLine.show;
var angle = startAngle;
var step = (endAngle - startAngle) / splitNumber;
var subStep = step / subSplitNumber;
for (var i = 0; i <= splitNumber; i++) {
const unitX = Math.cos(angle);
const unitY = Math.sin(angle);
if (splitLineShow) {
const line = new graphic.Line({
zlevel: this._option.zlevel,
z: this._option.z,
z2: this._option.z2,
cursor: this._option.cursor,
silent: this._option.silent,
...this._transformation(),
shape: {
x1: unitX * r + x,
y1: unitY * r + y,
x2: unitX * (r - splitLineLen) + x,
y2: unitY * (r - splitLineLen) + y
},
style: splitLineStyle
});
if (splitLineStyle.stroke === 'auto') {
line.setStyle({ stroke: getColor(i / splitNumber) });
}
this.add(line);
}
if (axisLabelShow) {
var label = new graphic.Text({
zlevel: this._option.zlevel,
z: this._option.z,
z2: this._option.z2,
cursor: this._option.cursor,
silent: this._option.silent,
...this._transformation(),
style: {
...axisLabelStyle,
text: formatLabel(
round(i / splitNumber * (maxVal - minVal) + minVal),
axisLabel.formatter || null
),
x: unitX * (r - splitLineLen - axisLabelDistance) + x,
y: unitY * (r - splitLineLen - axisLabelDistance) + y,
textVerticalAlign: unitY < -0.4 ? 'top' : (unitY > 0.4 ? 'bottom' : 'middle'),
textAlign: unitX < -0.4 ? 'left' : (unitX > 0.4 ? 'right' : 'center')
}
});
if (axisLabelStyle.textFill == 'auto') {
label.setStyle({ textFill: getColor(i / splitNumber) });
}
this.add(label);
}
if (axisTickShow && i !== splitNumber) {
for (var j = 0; j <= subSplitNumber; j++) {
const unitX = Math.cos(angle);
const unitY = Math.sin(angle);
const tickLine = new graphic.Line({
zlevel: this._option.zlevel,
z: this._option.z,
z2: this._option.z2,
cursor: this._option.cursor,
silent: this._option.silent,
...this._transformation(),
shape: {
x1: unitX * r + x,
y1: unitY * r + y,
x2: unitX * (r - axisTickLen) + x,
y2: unitY * (r - axisTickLen) + y
},
style: axisTickLineStyle
});
if (axisTickLineStyle.stroke === 'auto') {
tickLine.setStyle({ stroke: getColor((i + j / subSplitNumber) / splitNumber) });
}
this.add(tickLine);
angle += subStep;
}
angle -= subStep;
} else {
angle += step;
}
}
}
_createPointer({startAngle, endAngle, getColor}) {
var shape = this._option.shape;
var minVal = parseFloat(shape.min);
var maxVal = parseFloat(shape.max);
var value = parseFloat(shape.value);
var pointerStyle = this._option.style.pointer;
var pointerShow = pointerStyle.show;
var pointerLength = pointerStyle.length;
var pointerWidth = pointerStyle.width;
if (pointerShow) {
var valueExtent = [minVal, maxVal];
var angleExtent = [startAngle, endAngle];
var pointer = new graphic.Pointer({
zlevel: this._option.zlevel,
z: this._option.z,
z2: this._option.z2,
cursor: this._option.cursor,
silent: this._option.silent,
...this._transformation(),
shape: {
x: shape.cx,
y: shape.cy,
width: parsePercent(pointerWidth, shape.r),
r: parsePercent(pointerLength, shape.r),
angle: linearMap(value, valueExtent, angleExtent, true)
},
style: pointerStyle
});
if (pointer.style.fill === 'auto') {
pointer.setStyle('fill', getColor(linearMap(value, valueExtent, [0, 1], true)));
}
this.add(pointer);
}
}
_traverse(target, attr) {
for (var key in attr) {
if (!(attr[key] instanceof Object) || !attr[key]) {
target[key] = attr[key];
} else {
this._traverse(target[key], attr[key]);
}
}
}
_transformation() {
var parent = this.parent||{};
var origin = parent._origin||null;
var rotation = parent._rotation||null;
var scale = parent._scale||[1, 1];
return { origin, rotation, scale };
}
dragging(e) {
this.traverse(el => {
if (el instanceof graphic.Text) {
el.setStyle({
x: el.style.x + e.dx,
y: el.style.y + e.dy
});
} else if (el instanceof graphic.Sector) {
el.setShape({
cx: el.shape.cx + e.dx,
cy: el.shape.cy + e.dy
});
} else if (el instanceof graphic.Line) {
el.setShape({
x1: el.shape.x1 + e.dx,
y1: el.shape.y1 + e.dy,
x2: el.shape.x2 + e.dx,
y2: el.shape.y2 + e.dy
});
} else if (el instanceof graphic.Pointer) {
el.setShape({
x: el.shape.x + e.dx,
y: el.shape.y + e.dy
});
}
}, this);
}
setShape(objs) {
this._traverse(this._option.shape, objs);
this.render();
}
setStyle(objs) {
this._traverse(this._option.style, objs);
this.render();
}
}
function formatLabel(label, labelFormatter) {
if (labelFormatter) {
if (typeof labelFormatter === 'string') {
label = labelFormatter.replace('{value}', label != null ? label : '');
} else if (typeof labelFormatter === 'function') {
label = labelFormatter(label);
}
}
return label;
}
function round(x, precision, returnStr) {
if (precision == null) {
precision = 10;
}
precision = Math.min(Math.max(0, precision), 20);
x = (+x).toFixed(precision);
return returnStr ? x : +x;
}
function parsePercent(percent, all) {
switch (percent) {
case 'center':
case 'middle':
percent = '50%';
break;
case 'left':
case 'top':
percent = '0%';
break;
case 'right':
case 'bottom':
percent = '100%';
break;
}
if (typeof percent === 'string') {
if (percent.trim().match(/%$/)) {
return parseFloat(percent) / 100 * all;
}
return parseFloat(percent);
}
return percent == null ? NaN : +percent;
}
function linearMap(val, domain, range, clamp) {
var subDomain = domain[1] - domain[0];
var subRange = range[1] - range[0];
if (subDomain === 0) {
return subRange === 0
? range[0]
: (range[0] + range[1]) / 2;
}
if (clamp) {
if (subDomain > 0) {
if (val <= domain[0]) {
return range[0];
} else if (val >= domain[1]) {
return range[1];
}
} else {
if (val >= domain[0]) {
return range[0];
} else if (val <= domain[1]) {
return range[1];
}
}
} else {
if (val === domain[0]) {
return range[0];
}
if (val === domain[1]) {
return range[1];
}
}
return (val - domain[0]) / subDomain * subRange + range[0];
}

View File

@ -0,0 +1,115 @@
import Path from 'zrender/src/graphic/Path';
import * as polyHelper from 'zrender/src/graphic/helper/poly';
/**
* - 1
* | | 4 5
* - 2
* | | 6 7
* - 3
*/
export default Path.extend({
type: 'Digit',
dightMap: {
'0': [1, 3, 4, 5, 6, 7],
'1': [5, 7],
'2': [1, 2, 3, 5, 6],
'3': [1, 2, 3, 5, 7],
'4': [2, 4, 5, 7],
'5': [1, 2, 3, 4, 7],
'6': [1, 2, 3, 4, 6, 7],
'7': [1, 5, 7],
'8': [1, 2, 3, 4, 5, 6, 7],
'9': [1, 2, 3, 4, 5, 7],
'.': [10],
'°': [1, 2, 4, 5],
'*': [1, 2, 4, 5],
'C': [1, 3, 4, 6],
'L': [3, 4, 6]
},
shape: {
x: 0,
y: 0,
l: 4,
r: 2,
v: '8',
dx: 0.5,
dy: 0
},
getVPoints(shape, dx, dy) {
return [
[shape.x+dx, shape.y+shape.r*1.5+dy],
[shape.x+shape.r+dx, shape.y+shape.r*2.5+dy],
[shape.x+shape.r+dx, shape.y+shape.r*2.5+shape.l+dy],
[shape.x+dx, shape.y+shape.r*3.5+shape.l+dy],
[shape.x-shape.r+dx, shape.y+shape.r*2.5+shape.l+dy],
[shape.x-shape.r+dx, shape.y+shape.r*2.5+dy]
];
},
getLPoints(shape, dx, dy) {
return [
[shape.x+dx, shape.y+shape.r+dy],
[shape.x+shape.r+dx, shape.y+dy],
[shape.x+shape.r+shape.l+dx, shape.y+dy],
[shape.x+shape.r*2+shape.l+dx, shape.y+shape.r+dy],
[shape.x+shape.r+shape.l+dx, shape.y+shape.r*2+dy],
[shape.x+shape.r+dx, shape.y+shape.r*2+dy]
];
},
buildPath: function (ctx, shape) {
const list = this.dightMap[shape.v]||[];
if (list.includes(1)) {
const model = {
points: this.getLPoints(shape, 0, 0)
};
polyHelper.buildPath(ctx, model, true);
}
if (list.includes(2)) {
const model = {
points: this.getLPoints(shape, 0, shape.l+shape.r*3+shape.dy*2)
};
polyHelper.buildPath(ctx, model, true);
}
if (list.includes(3)) {
const model = {
points: this.getLPoints(shape, 0, shape.l*2+shape.r*6+shape.dy*2)
};
polyHelper.buildPath(ctx, model, true);
}
if (list.includes(4)) {
const model = {
points: this.getVPoints(shape, -shape.dx, +shape.dy)
};
polyHelper.buildPath(ctx, model, true);
}
if (list.includes(5)) {
const model = {
points: this.getVPoints(shape, shape.l+shape.r*2+shape.dx, +shape.dy)
};
polyHelper.buildPath(ctx, model, true);
}
if (list.includes(6)) {
const model = {
points: this.getVPoints(shape, -shape.dx, shape.l+shape.r*3+shape.dy*2)
};
polyHelper.buildPath(ctx, model, true);
}
if (list.includes(7)) {
const model = {
points: this.getVPoints(shape, shape.l+shape.r*2+shape.dx, shape.l+shape.r*3+shape.dy*2)
};
polyHelper.buildPath(ctx, model, true);
}
}
});

View File

@ -0,0 +1,44 @@
import Path from 'zrender/src/graphic/Path';
export default Path.extend({
type: 'hover',
shape: {
padding: 2,
x: 0,
y: 0,
with: 0,
height: 0
},
style: {
stroke: '#fff',
fill: null
},
buildPath: function (ctx, shape) {
var x = shape.x - this.shape.padding;
var y = shape.y - this.shape.padding;
var w = shape.width + this.shape.padding * 2;
var h = shape.height + this.shape.padding * 2;
var ph = Math.min(h, w) / 4;
var pw = Math.min(h, w) / 4;
ctx.moveTo(x, y + ph);
ctx.lineTo(x, y);
ctx.lineTo(x + pw, y);
ctx.moveTo(x + w - pw, y);
ctx.lineTo(x + w, y);
ctx.lineTo(x + w, y + ph);
ctx.moveTo(x, y + h - ph);
ctx.lineTo(x, y + h);
ctx.lineTo(x + pw, y + h);
ctx.moveTo(x + w, y + h - ph);
ctx.lineTo(x + w, y + h);
ctx.lineTo(x + w - pw, y + h);
}
});

View File

@ -0,0 +1,423 @@
import * as graphic from '../../graphic';
import * as color from 'zrender/src/tool/color';
export default class LinearScale extends graphic.Group {
constructor(option) {
super();
this._option = {
zlevel: option.zlevel || 0,
z: option.z || 0,
z2: option.z2 || 0,
cursor: option.cursor||null,
silent: option.silent||false,
shape: {
x: 0,
y: 0,
min: 0,
max: 100,
tickStart: 0,
tickEnd: 200,
angle: Math.PI,
splitNumber: 10,
value: 0,
...option.shape
},
style: {
axisLine: {
show: true,
lineStyle: {
color: [[0.2, '#91c7ae'], [0.8, '#63869e'], [1, '#c23531']],
lineWidth: 3
},
...option.style.axisLine
},
splitLine: {
show: true,
length: 8,
distance: -6.5,
lineStyle: {
width: 1,
stroke: 'auto'
},
...option.style.splitLine
},
axisTick: {
show: true,
length: 3,
distance: -4.5,
splitNumber: 5,
lineStyle: {
width: 1,
stroke: 'auto',
shadowColor: '#fff',
shadowBlur: 10
},
...option.style.axisTick
},
axisLabel: {
show: true,
distance: -25,
textStyle: {
fontSize: 6,
textFill: 'auto'
},
...option.style.axisLabel
},
pointer: {
show: true,
lineWidth: 3,
stroke: 'auto',
lineCap: 'round',
...option.style.pointer
}
}
};
this.render();
}
render() {
this.removeAll();
var axisLine = this._option.style.axisLine;
var showAxis = axisLine.show;
var axisLineStyle = axisLine.lineStyle;
var axisColorList = axisLineStyle.color;
var axisLineWidth = axisLineStyle.lineWidth;
var shape = this._option.shape;
var angle = shape.angle;
var minTick = shape.tickStart;
var maxTick = shape.tickEnd;
var lineRangeSpan = (maxTick - minTick);
var prevEndLine = 0;
var x = shape.x;
var y = shape.y;
if (showAxis) {
for (var i = 0; i < axisColorList.length; i++) {
var percent = Math.min(Math.max(axisColorList[i][0], 0), 1);
var lineLen = lineRangeSpan * percent - prevEndLine;
var px = lineLen * Math.cos(angle);
var py = lineLen * Math.sin(angle);
var line = new graphic.Line({
zlevel: this._option.zlevel,
z: this._option.z,
z2: this._option.z2,
cursor: this._option.cursor,
silent: this._option.silent,
...this._transformation(),
shape: {
x1: x,
y1: y,
x2: x + px,
y2: y + py
}
});
line.setStyle({ stroke: axisColorList[i][1], lineWidth: axisLineWidth });
this.add(line);
x += px;
y += py;
prevEndLine = lineRangeSpan * percent;
}
}
var getColor = function (percent) {
if (percent <= 0) {
return axisColorList[0][1];
}
for (var i = 0; i < axisColorList.length; i++) {
if (axisColorList[i][0] >= percent &&
(i === 0 ? 0 : axisColorList[i - 1][0]) < percent
) {
return axisColorList[i][1];
}
}
return axisColorList[i - 1][1];
};
this._createTicks({getColor});
this._createPointer({getColor});
}
_createTicks({getColor}) {
var shape = this._option.shape;
var x = shape.x;
var y = shape.y;
var minTick = shape.tickStart;
var maxTick = shape.tickEnd;
var minVal = parseFloat(shape.min);
var maxVal = parseFloat(shape.max);
var splitNumber = shape.splitNumber;
var angle = shape.angle;
var axisLabel = this._option.style.axisLabel;
var axisLabelShow = axisLabel.show;
var axisLabelDistance = axisLabel.distance;
var axisLabelStyle = axisLabel.textStyle;
var axisTick = this._option.style.axisTick;
var axisTickShow = axisTick.show;
var axisTickLen = axisTick.length;
var axisTickDistance = axisTick.distance;
var axisTickLineStyle = axisTick.lineStyle;
var subSplitNumber = axisTick.splitNumber;
var splitLine = this._option.style.splitLine;
var splitLineShow = splitLine.show;
var splitLineLen = splitLine.length;
var splitLineDistance = splitLine.distance;
var splitLineStyle = splitLine.lineStyle;
var step = (maxTick - minTick) / splitNumber;
var subStep = step / subSplitNumber;
for (var i = 0; i <= splitNumber; i++) {
const unitX = Math.cos(angle);
const unitY = Math.sin(angle);
if (splitLineShow) {
const line = new graphic.Line({
zlevel: this._option.zlevel,
z: this._option.z,
z2: this._option.z2,
cursor: this._option.cursor,
silent: this._option.silent,
...this._transformation(),
shape: {
x1: x + unitX * step * i + unitY * (splitLineLen + splitLineDistance),
y1: y + unitY * step * i - unitX * (splitLineLen + splitLineDistance),
x2: x + unitX * step * i - unitY * (splitLineLen - splitLineDistance),
y2: y + unitY * step * i + unitX * (splitLineLen - splitLineDistance)
},
style: splitLineStyle
});
if (splitLineStyle.stroke === 'auto') {
line.setStyle({ stroke: getColor(i / splitNumber) });
}
this.add(line);
}
if (axisLabelShow) {
const label = new graphic.Text({
zlevel: this._option.zlevel,
z: this._option.z,
z2: this._option.z2,
cursor: this._option.cursor,
silent: this._option.silent,
...this._transformation(),
style: {
textVerticalAlign: unitX < -0.4 ? 'bottom' : (unitX > 0.4 ? 'top' : 'middle'),
textAlign: unitY < -0.4 ? 'left' : (unitY > 0.4 ? 'right' : 'center'),
...axisLabelStyle,
text: formatLabel(
round(i / splitNumber * (maxVal - minVal) + minVal),
axisLabel.formatter || null
),
x: x + unitX * step * i + unitY * (splitLineLen + axisLabelDistance),
y: y + unitY * step * i - unitX * (splitLineLen + axisLabelDistance)
}
});
if (axisLabelStyle.textFill === 'auto') {
label.setStyle({ textFill: getColor(i / splitNumber) });
}
this.add(label);
}
if (axisTickShow && i !== splitNumber) {
for (var j = 1; j < subSplitNumber; j++) {
const unitX = Math.cos(angle);
const unitY = Math.sin(angle);
const tickLine = new graphic.Line({
zlevel: this._option.zlevel,
z: this._option.z,
z2: this._option.z2,
cursor: this._option.cursor,
silent: this._option.silent,
...this._transformation(),
shape: {
x1: x + unitX * (step * i + subStep * j) + unitY * (axisTickLen + axisTickDistance),
y1: y + unitY * (step * i + subStep * j) - unitX * (axisTickLen + axisTickDistance),
x2: x + unitX * (step * i + subStep * j) - unitY * (axisTickLen - axisTickDistance),
y2: y + unitY * (step * i + subStep * j) + unitX * (axisTickLen - axisTickDistance)
},
style: axisTickLineStyle
});
if (axisTickLineStyle.stroke === 'auto') {
tickLine.setStyle({ stroke: getColor((i + j / subSplitNumber) / splitNumber) });
}
this.add(tickLine);
}
}
}
}
_createPointer({getColor}) {
var shape = this._option.shape;
var x = shape.x;
var y = shape.y;
var minVal = parseFloat(shape.min);
var maxVal = parseFloat(shape.max);
var value = parseFloat(shape.value) || 0;
var minTick = shape.tickStart;
var maxTick = shape.tickEnd;
var angle = shape.angle;
var pointerStyle = this._option.style.pointer;
var pointerShow = pointerStyle.show;
var pointerLineWidth = pointerStyle.lineWidth;
var pointerLineCap = pointerStyle.lineCap;
if (pointerShow) {
var valueExtent = [minVal, maxVal];
var angleExtent = [minTick, maxTick];
var unitX = Math.cos(angle);
var unitY = Math.sin(angle);
var valueLen = linearMap(value, valueExtent, angleExtent, true);
var specialStyleList = ['round', 'square'];
var pointer = new graphic.Line({
zlevel: this._option.zlevel,
z: this._option.z,
z2: this._option.z2,
cursor: this._option.cursor,
silent: this._option.silent,
...this._transformation(),
shape: {
x1: x,
y1: y,
x2: x + unitX * (valueLen - (specialStyleList.includes(pointerLineCap)? pointerLineWidth/2:0)),
y2: y + unitY * (valueLen - (specialStyleList.includes(pointerLineCap)? pointerLineWidth/2:0))
},
style: pointerStyle
});
if (pointerStyle.stroke === 'auto') {
pointer.setStyle('stroke', color.lift(getColor(linearMap(value, valueExtent, [0, 1], true)), 0.3));
}
this.add(pointer);
}
}
_traverse(target, attr) {
for (var key in attr) {
if (!(attr[key] instanceof Object) || !attr[key]) {
target[key] = attr[key];
} else {
this._traverse(target[key], attr[key]);
}
}
}
_transformation() {
var parent = this.parent||{};
var origin = parent._origin||null;
var rotation = parent._rotation||null;
var scale = parent._scale||[1, 1];
return { origin, rotation, scale };
}
dragging(e) {
this.traverse(el => {
if (el instanceof graphic.Text) {
el.setStyle({
x: el.style.x + e.dx,
y: el.style.y + e.dy
});
} else if (el instanceof graphic.Line) {
el.setShape({
x1: el.shape.x1 + e.dx,
y1: el.shape.y1 + e.dy,
x2: el.shape.x2 + e.dx,
y2: el.shape.y2 + e.dy
});
}
}, this);
}
setShape(objs) {
this._traverse(this._option.shape, objs);
this.render();
}
setStyle(objs) {
this._traverse(this._option.style, objs);
this.render();
}
}
function formatLabel(label, labelFormatter) {
if (labelFormatter) {
if (typeof labelFormatter === 'string') {
label = labelFormatter.replace('{value}', label != null ? label : '');
} else if (typeof labelFormatter === 'function') {
label = labelFormatter(label);
}
}
return label;
}
function round(x, precision, returnStr) {
if (precision == null) {
precision = 10;
}
precision = Math.min(Math.max(0, precision), 20);
x = (+x).toFixed(precision);
return returnStr ? x : +x;
}
function linearMap(val, domain, range, clamp) {
var subDomain = domain[1] - domain[0];
var subRange = range[1] - range[0];
if (subDomain === 0) {
return subRange === 0
? range[0]
: (range[0] + range[1]) / 2;
}
if (clamp) {
if (subDomain > 0) {
if (val <= domain[0]) {
return range[0];
} else if (val >= domain[1]) {
return range[1];
}
} else {
if (val >= domain[0]) {
return range[0];
} else if (val <= domain[1]) {
return range[1];
}
}
} else {
if (val === domain[0]) {
return range[0];
}
if (val === domain[1]) {
return range[1];
}
}
return (val - domain[0]) / subDomain * subRange + range[0];
}

View File

@ -0,0 +1,45 @@
import Path from 'zrender/src/graphic/Path';
export default Path.extend({
type: 'Pointer',
shape: {
angle: 0,
width: 10,
r: 10,
x: 0,
y: 0
},
buildPath: function (ctx, shape) {
var mathCos = Math.cos;
var mathSin = Math.sin;
var r = shape.r;
var width = shape.width;
var angle = shape.angle;
var x = shape.x - mathCos(angle) * width * (width >= r / 3 ? 1 : 2);
var y = shape.y - mathSin(angle) * width * (width >= r / 3 ? 1 : 2);
angle = shape.angle - Math.PI / 2;
ctx.moveTo(x, y);
ctx.lineTo(
shape.x + mathCos(angle) * width,
shape.y + mathSin(angle) * width
);
ctx.lineTo(
shape.x + mathCos(shape.angle) * r,
shape.y + mathSin(shape.angle) * r
);
ctx.lineTo(
shape.x - mathCos(angle) * width,
shape.y - mathSin(angle) * width
);
ctx.lineTo(x, y);
}
});

View File

@ -0,0 +1,66 @@
import Path from 'zrender/src/graphic/Path';
/**
* Sausage: similar to sector, but have half circle on both sides
* @public
*/
export default Path.extend({
type: 'sausage',
shape: {
cx: 0,
cy: 0,
r0: 0,
r: 0,
startAngle: 0,
endAngle: Math.PI * 2,
clockwise: true
},
buildPath: function (ctx, shape) {
var x = shape.cx;
var y = shape.cy;
var r0 = Math.max(shape.r0 || 0, 0);
var r = Math.max(shape.r, 0);
var dr = (r - r0) * 0.5;
var rCenter = r0 + dr;
var startAngle = shape.startAngle;
var endAngle = shape.endAngle;
var clockwise = shape.clockwise;
var unitStartX = Math.cos(startAngle);
var unitStartY = Math.sin(startAngle);
var unitEndX = Math.cos(endAngle);
var unitEndY = Math.sin(endAngle);
var lessThanCircle = clockwise
? endAngle - startAngle < Math.PI * 2
: startAngle - endAngle < Math.PI * 2;
if (lessThanCircle) {
ctx.moveTo(unitStartX * r0 + x, unitStartY * r0 + y);
ctx.arc(
unitStartX * rCenter + x, unitStartY * rCenter + y, dr,
-Math.PI + startAngle, startAngle, !clockwise
);
}
ctx.arc(x, y, r, startAngle, endAngle, !clockwise);
ctx.moveTo(unitEndX * r + x, unitEndY * r + y);
ctx.arc(
unitEndX * rCenter + x, unitEndY * rCenter + y, dr,
endAngle - Math.PI * 2, endAngle - Math.PI, !clockwise
);
if (r0 !== 0) {
ctx.arc(x, y, r0, endAngle, startAngle, clockwise);
ctx.moveTo(unitStartX * r0 + x, unitEndY * r0 + y);
}
ctx.closePath();
}
});

View File

@ -0,0 +1,26 @@
import zrender from 'zrender';
export default class Svg extends zrender.Path {
constructor(opts) {
super(zrender.path.createFromString(opts.shape.path, {
...opts,
type: 'Svg'
}));
super.attr('position', [opts.shape.x, opts.shape.y]);
}
setShape(shape) {
super.setShape(shape);
this.attr('position', [shape.x, shape.y]);
}
setStyle(style) {
super.setStyle(style);
}
attr(key, value) {
super.attr(key, value);
}
}

View File

@ -0,0 +1,275 @@
import * as graphic from '../../../graph/graphic';
import Button from '@/assets/map/button.png';
const cellStyle = {
text: {
fontSize: 14,
fontWeight: 'normal',
fontFamily: '微软雅黑,Arial',
textFill: '#000',
textAlign: 'center',
textVerticalAlign: 'middle',
textPadding: null,
rich: {
sup: {
textVerticalAlign: 'top',
fontSize: 8
},
sub: {
textVerticalAlign: 'bottom',
fontSize: 8
}
}
},
order: {
r: 10,
lineWidth: 1,
stroke: '#F0F0f0',
fill: '#EFA5FF',
fontSize: 24,
fontWeight: 'bold',
fontFamily: '微软雅黑,Arial',
textFill: '#000',
textAlign: 'center',
textVerticalAlign: 'middle',
textPadding: null,
rich: {
sup: {
textVerticalAlign: 'top',
fontSize: 12
},
sub: {
textVerticalAlign: 'bottom',
fontSize: 12
}
}
},
button: {
url: Button,
width: 60,
height: 25,
fill: '#ffffff',
fontSize: 24,
fontWeight: 'bold',
fontFamily: '微软雅黑,Arial',
textFill: '#000',
textAlign: 'center',
textVerticalAlign: 'middle',
textPadding: null,
rich: {
sup: {
textVerticalAlign: 'top',
fontSize: 12
},
sub: {
textVerticalAlign: 'bottom',
fontSize: 12
}
}
}
};
export default class Cell extends graphic.Group {
constructor(option) {
super();
this._elMap = {
text: null,
order: null,
circle: null,
button: null
};
this._option = {
zlevel: option.zlevel,
z: option.z,
z2: option.z2,
cursor: option.cursor,
silent: option.silent,
shape: {
x: 0,
y: 0,
...option.shape
},
style: {
...option.style
}
};
this.render();
}
render() {
var shape = this._option.shape;
var style = this._option.style;
var x = shape.x;
var y = shape.y;
var w = shape.width;
var h = shape.height;
switch (style.type) {
case 'order': this._createOrder(shape); break;
case 'text': this._createTextModel(shape); break;
case 'button': this._createButton({
x: x - w / 2,
y: y - h / 2,
w,
h
}); break;
}
}
_createTextModel(shape) {
const zlevel = this._option.zlevel;
const z = this._option.z;
const z2 = this._option.z2;
const style = this._option.style;
const cursor = this._option.cursor;
const silent = this._option.silent;
this._elMap.text = new graphic.Text({
zlevel: zlevel,
z: z,
z2: z2+1,
cursor,
silent,
style: {
x: shape.x,
y: shape.y,
fontSize: style.fontSize || cellStyle.text.fontSize,
fontWeight: style.fontWeight || cellStyle.text.fontWeight,
fontFamily: style.fontFamily || cellStyle.text.fontFamily,
textFill: style.textFill || cellStyle.text.textFill,
textAlign: style.textAlign || cellStyle.text.textAlign,
textVerticalAlign: style.textVerticalAlign || cellStyle.text.textVerticalAlign,
textPadding: style.textPadding|| cellStyle.text.textPadding,
text: style.text || '',
rich: style.rich || cellStyle.text.rich
}
});
this.add(this._elMap.text);
}
_createOrder(shape) {
const zlevel = this._option.zlevel;
const z = this._option.z;
const z2 = this._option.z2;
const style = this._option.style;
const cursor = this._option.cursor;
const silent = this._option.silent;
this._elMap.order = new graphic.Circle({
zlevel: zlevel,
z: z,
z2: z2+1,
cursor,
silent,
shape: {
cx: shape.x,
cy: shape.y,
r: shape.r || cellStyle.order.r
},
style: {
lineWidth: style.lineWidth || cellStyle.order.lineWidth,
stroke: style.stroke || cellStyle.order.stroke,
fill: style.fill || cellStyle.order.fill
}
});
this._elMap.text = new graphic.Text({
zlevel: zlevel,
z: z,
z2: z2+1,
style: {
x: shape.x,
y: shape.y,
fontSize: style.fontSize || cellStyle.order.fontSize,
fontWeight: style.fontWeight || cellStyle.order.fontWeight,
fontFamily: style.fontFamily || cellStyle.order.fontFamily,
textFill: style.textFill || cellStyle.order.textFill,
textAlign: style.textAlign || cellStyle.order.textAlign,
textVerticalAlign: style.textVerticalAlign || cellStyle.order.textVerticalAlign,
textWidth: style.width || cellStyle.order.width,
textPadding: style.textPadding || cellStyle.order.textPadding,
textBorderWidth: style.textBorderWidth || cellStyle.order.textBorderWidth,
textBorderColor: style.textBorderColor || cellStyle.order.textBorderColor,
textBackgroundColor: cellStyle.order.textBackgroundColor,
rich: style.rich || cellStyle.order.rich,
text: style.text || ''
}
});
this.add(this._elMap.order);
this.add(this._elMap.text);
}
_createButton(shape) {
const zlevel = this._option.zlevel;
const z = this._option.z;
const z2 = this._option.z2;
const style = this._option.style;
const width = style.width || cellStyle.button.width;
const height = style.height ||cellStyle.button.height;
const image = style.url || cellStyle.button.url;
this._elMap.button = new graphic.Image({
zlevel: zlevel,
z: z,
z2: z2+1,
style: {
x: shape.x + (shape.w - width)/2,
y: shape.y + (shape.h - height)/2,
width: width,
height: height,
image: image
}
});
this._elMap.text = new graphic.Text({
zlevel: zlevel,
z: z,
z2: z2+1,
position: [shape.w/2, shape.h/2],
style: {
x: shape.x,
y: shape.y,
fontSize: style.fontSize || cellStyle.button.fontSize,
fontWeight: style.fontWeight || cellStyle.button.fontWeight,
fontFamily: style.fontFamily || cellStyle.button.fontFamily,
textFill: style.textFill || cellStyle.button.textFill,
textAlign: style.textAlign || cellStyle.button.textAlign,
textVerticalAlign: style.textVerticalAlign || cellStyle.button.textVerticalAlign,
textWidth: style.textWidth || cellStyle.button.width,
textPadding: style.textPadding || cellStyle.button.textPadding,
textBorderWidth: style.textBorderWidth || cellStyle.button.textBorderWidth,
textBorderColor: style.textBorderColor || cellStyle.button.textBorderColor,
textBackgroundColor: style.textBackgroundColor || cellStyle.button.textBackgroundColor,
rich: style.rich || cellStyle.button.rich,
text: style.text || ''
}
});
this.add(this._elMap.button);
this.add(this._elMap.text);
}
dragging(e) {
this.traverse(el => {
if (el instanceof graphic.Text) {
el.setStyle({
x: el.style.x + e.dx,
y: el.style.y + e.dy
});
} else if (el instanceof graphic.Image) {
el.setStyle({
x: el.style.x + e.dx,
y: el.style.y + e.dy
});
} else if (el instanceof graphic.Circle) {
el.setShape({
cx: el.shape.cx + e.dx,
cy: el.shape.cy + e.dy
});
}
}, this);
}
}

View File

@ -0,0 +1,200 @@
import * as graphic from '../../graphic';
import Cell from './cell';
export default class Table extends graphic.Group {
constructor(option) {
super();
this.invTransform = [1, 0, 0, 1, 0, 0];
this._elMap = {
rowLines: [],
colLines: [],
cellArrs: [],
bg: null
};
this._option = {
zlevel: option.zlevel || 0,
z: option.z || 0,
z2: option.z || 0,
cursor: option.cursor||null,
silent: option.silent||false,
shape: {
dataSource: option.shape.dataSource || [],
wList: option.shape.wList || [],
hList: option.shape.hList || [],
point: option.shape.point || {x: 0, y: 0}
},
style: {
backgroundColor: option.style.backgroundColor,
lineWidth: option.style.lineWidth || 1,
stroke: option.style.stroke || '#000000'
}
};
this.render();
}
render() {
this.removeAll();
this._createLineModels();
this._createCells();
}
_createLineModels() {
const zlevel = this._option.zlevel;
const z = this._option.z;
const z2 = this._option.z2;
const cursor = this._option.cursor;
const shape = this._option.shape;
const style = this._option.style;
const x = shape.point.x;
const y = shape.point.y;
const rowLen = shape.hList.length;
const colLen = shape.wList.length;
const sumW = colLen==0? 0: shape.wList.reduce((pre, item) => { return pre + item; });
const sumH = rowLen==0? 0: shape.hList.reduce((pre, item) => { return pre + item; });
for (let i = 1; i < rowLen; i++) {
const line = new graphic.Line({
zlevel: zlevel,
z: z,
z2: z2,
cursor,
shape: {
x1: x,
y1: y + shape.hList.reduce((pre, item, idx) => { return pre + (idx < i ? item || style.rowHeight: 0); }),
x2: x + sumW,
y2: y + shape.hList.reduce((pre, item, idx) => { return pre + (idx <i ? item || style.rowHeight: 0); })
},
style: {
lineWidth: style.lineWidth,
stroke: style.stroke
}
});
this._elMap.rowLines.push(line);
this.add(line);
}
for (let i = 1; i < colLen; i++) {
const line = new graphic.Line({
zlevel: zlevel,
z: z,
z2: z2,
cursor,
shape: {
x1: x + shape.wList.reduce((pre, item, idx) => { return pre + (idx < i ? item || style.columnWidth: 0); }),
y1: y,
x2: x + shape.wList.reduce((pre, item, idx) => { return pre + (idx < i ? item || style.columnWidth: 0); }),
y2: y + sumH
},
style: {
lineWidth: style.lineWidth,
stroke: style.stroke
}
});
this._elMap.colLines.push(line);
this.add(line);
}
this._elMap.bg = new graphic.Rect({
zlevel: zlevel,
z: z,
z2: z2-1,
cursor,
shape: {
x: x,
y: y,
width: sumW,
height: sumH
},
style: {
lineWidth: style.lineWidth,
stroke: style.stroke,
fill: style.backgroundColor
}
});
this.add(this._elMap.bg);
}
_createCells() {
const zlevel = this._option.zlevel;
const z = this._option.z;
const z2 = this._option.z2;
const cursor = this._option.cursor;
const silent = this._option.silent;
const shape = this._option.shape;
const style = this._option.style;
const x = shape.point.x;
const y = shape.point.y;
this._elMap.cellArrs = [];
shape.dataSource.forEach((rowList, i) => {
const list = [];
if (rowList instanceof Array) {
rowList.forEach((elem, j) => {
const cell = new Cell({
zlevel: zlevel,
z: z,
z2: z2+1,
cursor: cursor,
silent: silent,
shape: Object.assign({
x: x + shape.wList.reduce((pre, item, idx) => { return pre + (idx <= j ? item || style.columnWidth: 0); }) - (shape.wList[j] || style.columnWidth) /2,
y: y + shape.hList.reduce((pre, item, idx) => { return pre + (idx <= i ? item || style.rowHeight: 0); }) - (shape.hList[i] || style.rowHeight) /2,
width: shape.wList[j] || style.cell.width,
height: shape.hList[i] || style.cell.Height
}),
style: elem || {}
});
list.push(cell);
this.add(cell);
});
}
this._elMap.cellArrs.push(list);
});
}
_traverse(target, attr) {
for (var key in attr) {
if (!(attr[key] instanceof Object) || !attr[key]) {
target[key] = attr[key];
} else {
this._traverse(target[key], attr[key]);
}
}
}
setShape(objs) {
this._traverse(this._option.shape, objs);
this.render();
}
setStyle(objs) {
this._traverse(this._option.style, objs);
this.render();
}
dragging(e) {
[...this._elMap.rowLines, ...this._elMap.colLines].forEach(elem => {
elem.setShape({
x1: elem.shape.x1 + e.dx,
y1: elem.shape.y1 + e.dy,
x2: elem.shape.x2 + e.dx,
y2: elem.shape.y2 + e.dy
});
});
this._elMap.cellArrs.forEach(list => {
list.forEach(elem => {
elem.dragging(e);
});
});
this._elMap.bg.setShape({
x: this._elMap.bg.shape.x + e.dx,
y: this._elMap.bg.shape.y + e.dy
});
}
}

View File

@ -0,0 +1,33 @@
export default class KeyBoardHandle {
constructor(map, controller) {
this.$map = map;
this.$controller = controller;
this.keyStr = '';
}
execFunc(moduleName, funcName, args) {
const module = this.$controller[moduleName]||{};
const func = module[funcName];
if (func instanceof Function) {
func.apply(module, args);
}
}
onKeydown(e) {
switch (e.key) {
case 'v':
this.execFunc('selectHandle', 'setDraggable', ['vertical']);
break;
case 'h':
this.execFunc('selectHandle', 'setDraggable', ['horizontal']);
break;
case 'Escape':
this.execFunc('selectHandle', 'setDraggable', [true]);
break;
}
}
onKeyup(e) {
}
}

512
src/iscs_new/map.js Normal file
View File

@ -0,0 +1,512 @@
import _ from 'lodash';
// import * as zrUtil from 'zrender/src/core/util';
import * as utils from './utils/utils';
import Caches from './utils/container/Caches'; // 缓存模块
import zrender from 'zrender';
import Painter from './painter';
import SubMap from './subMap/subMap';
import Options from './options';
import Controller from './controller'; // 事件集合
import Style from './config/style'; // 样式集合
import graphType from './constant/graphType';
const renderer = 'canvas';
const devicePixelRatio = 1;
const localStore = { caches: null, cachesDraft: null };
class Jlmap {
constructor(opts) {
// 回调事件
this.methods = opts.methods;
// 鼠标事件
this.events = {
__Pan: '_pan',
__Zoom: '_zoom',
__DragStart: '_dragStart',
__Dragging: '_draging',
__DragEnd: '_dragEnd',
__SelectStart: '_selectStart',
__Selecting: '_selecting',
__SelectEnd: '_selectEnd',
__Selected: '_selected',
Reflect: 'reflect',
Selected: 'selected',
ContextMenu: 'contextmenu',
DataZoom: 'dataZoom',
Keydown: 'keydown',
Keyup: 'keyup',
Keypress: 'keypress'
};
// 状态对象
this.state = {
mapShape: {},
mapEntity: {},
mapLink: {},
parser: {}
};
// 缓存模块
if (opts.isDraw) {
localStore.caches = null;
localStore.cachesDraft = null;
this.caches = new Caches(this);
this.cachesDraft = {};
} else {
this.caches = localStore.caches ? localStore.caches : new Caches(this);
this.cachesDraft = localStore.cachesDraft ? localStore.cachesDraft : {};
}
// 子图模块
this.subMap = new SubMap(this);
// 数据依赖关系
this.mapDependency = {};
// 默认状态
this.defaultStateDict = this.loadDefaultState();
// 默认皮肤
this.defaultStyleDict = this.loadDefaultStyle();
// 是否绘制
this.draw = false;
// 是否可拖拽
this.draggle = false;
this.initMapInstance(opts);
}
// 初始化属性有鼠标事件 缩放等
initMapInstance(opts) {
const width = opts.dom.clientWidth;
const height = opts.dom.clientHeight;
const optionsHandler = this.setOptions.bind(this);
this.$zr = zrender.init(opts.dom, { renderer, devicePixelRatio, width, height, ...utils.deepClone(opts.config||{})});
this.$zr.dom.setAttribute('tabIndex', -1);
this.$zr.dom.style.cursor = 'auto';
this.$options = new Options({ scaleRate: 1, offsetX: 0, offsetY: 0, ...utils.deepClone(opts.options||{})}, (dataZoom) => { this.$controller.trigger(this.events.DataZoom, dataZoom); }); // 缩放
this.$painter = new Painter(this);
this.$painter.updateZrSize({width: this.$zr.getWidth(), height: this.$zr.getHeight()});
this.$painter.updateTransform(this.$options);
this.$controller = new Controller(this);
this.$controller.enable({draggle: this.draggle, panEnable: this.panEnable, zoomEnable: this.zoomEnable, keyEnable: this.keyEnable, selectable: this.selectable, selecting: this.selecting, reflectable: this.draw});
this.$controller.on(this.events.__Pan, optionsHandler);
this.$controller.on(this.events.__Zoom, optionsHandler);
this.disable = function() {
this.off(this.events.Pan, optionsHandler);
this.off(this.events.Zoom, optionsHandler);
};
}
loadDefaultState() {
return {};
}
loadDefaultStyle() {
return Style;
}
setMap({state, draggle, panEnable, zoomEnable, keyEnable, selectable, selecting, draw}) {
// 是否可拖拽
this.draggle = draggle;
// 鼠标移动
this.panEnable = panEnable;
// 视图缩放
this.zoomEnable = zoomEnable;
// 键盘事件
this.keyEnable = keyEnable;
// 选择事件
this.selectable = selectable;
// 区域选择
this.selecting = selecting;
// 是否绘图
this.draw = state.isDraw = draw;
// 解析模块
this.parser = state.parser;
// 状态对象
this.state = state;
if (state.dataZoom) {
this.$options.scaleRate = state.dataZoom.scaleRate || 1;
this.$options.offsetX = state.dataZoom.offsetX || 0;
this.$options.offsetY = state.dataZoom.offsetY || 0;
}
// 分析依赖关系
this.mapDependency = this.parser.analysis ? this.parser.analysis(state) : {};
// 绑定事件
this.$controller.enable({draggle: this.draggle, panEnable: this.panEnable, zoomEnable: this.zoomEnable, keyEnable: this.keyEnable, selectable: this.selectable, selecting: this.selecting, reflectable: this.draw});
// 更新视图位置
this.$painter.updateTransform({ scaleRate: this.$options.scaleRate, offsetX: this.$options.offsetX, offsetY: this.$options.offsetY });
// 数据加载完成 回调
if (this.methods.dataLoaded instanceof Function) { this.methods.dataLoaded(this.state.mapShape); }
// 初次渲染视图
this.repaint();
// 视图加载完成 回调
if (this.methods.viewLoaded instanceof Function) { this.methods.viewLoaded(this.state.mapShape); }
// 设置默认状态
this.setDefaultState();
// 返回视图缩放偏移
this.$options.trigger(this.$options);
}
setDefaultState() {
if (this.methods.stateLoaded instanceof Function) { this.methods.stateLoaded(); }
}
setOptions(opts) {
const options = this.pullBack(opts);
this.$options.update(options);
this.$painter.updateTransform(this.$options);
this.$controller.disable();
this.$controller.enable({...opts, draggle: this.draggle, panEnable: this.panEnable, zoomEnable: this.zoomEnable, keyEnable: this.keyEnable, selectable: this.selectable, selecting: this.selecting, reflectable: this.draw});
if (this.methods.optionsUpdate instanceof Function) { this.methods.optionsUpdate(this.$options); }
}
setDragging(e) {
if (e.dragTarget) {
const scaleRate = this.$options.getScaleRate();
e.dx /= scaleRate;
e.dy /= scaleRate;
e.dragTarget.instance.dragging(e);
}
}
setCenter(shapeCode) {
const shape = this.state.mapShape[shapeCode];
if (shape && shape.instance) {
var rect = utils.createBoundingRect(shape.instance);
var center = utils.calculateDCenter(rect, { width: this.$zr.getWidth(), height: this.$zr.getHeight() });
this.setOptions(center);
}
}
setBackgroundColor(color) {
this.$zr.setBackgroundColor(color);
}
setCursorStyle(cursorStyle) {
this.$zr.setCursorStyle(cursorStyle);
}
buildShape(elem, shape) {
return Object.assign(shape, {model: Object.assign(shape.model, elem), style: this.defaultStyleDict, draw: this.draw});
}
// 初次渲染
repaint() {
this.$painter.clear();
Object.values(this.state.mapShape).forEach(shape => {
this.$painter.add(this.buildShape({}, shape));
});
}
restate() {
Object.values(this.state.mapShape).forEach(shape => {
this.$painter.update(shape);
});
}
render(list) {
(list||[]).forEach(elem => {
const code = elem.code;
const type = elem._type;
const entity = this.getEntityByModel(elem)||{};
const mapShape = this.state.mapShape||{};
const oShape = mapShape[code] || this.parser.newShape(entity, type, elem);
this.$painter.delete(oShape);
if (elem._dispose) {
delete mapShape[code];
} else {
const nShape = this.buildShape(elem, oShape);
mapShape[code] = nShape;
this.$painter.add(nShape);
}
});
if (this.methods.viewUpdate instanceof Function) { this.methods.viewUpdate(list); }
}
update(list) {
(list||[]).forEach(elem => {
this.$painter.update(elem); // 更新设备状态
});
if (this.methods.stateUpdate instanceof Function) { this.methods.stateUpdate(list); }
}
pullBack(payload) {
if (payload.type == this.events.__Zoom) {
const zrWidth = this.$zr.getWidth();
const zrHeight = this.$zr.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||{};
}
isDraw() {
return this.draw;
}
isHover(code) {
return this.$controller
? this.$controller.storage.has(code)
: false;
}
// 设置图层显示
setLayerVisible(parserType, typeList) {
this.$painter.setLayerVisible(parserType, typeList);
}
// 设置资源显示
setVisible4Resource(types) {
Object.values(this.state.mapShape).filter(({model}) => { return model._type == graphType.Resource; }).forEach(({model, instance}) => {
const entity = this.getEntityByModel(model);
if (instance && entity && entity.type) {
this.$painter.setResourceVisible(instance, types.includes(entity.type));
}
});
}
getZr() {
return this.$zr;
}
getOptions() {
return this.$options;
}
getPainter() {
return this.$painter;
}
getController() {
return this.$controller;
}
getEvents() {
return this.events;
}
getState() {
return this.state;
}
getMapDependency() {
return this.mapDependency;
}
getMapShape() {
return this.state.mapShape;
}
getMapEntity() {
return this.state.mapEntity;
}
getMapLink() {
return this.state.mapLink;
}
getDefaultStateDict() {
return this.defaultStateDict;
}
getDefaultStyleDict() {
return this.defaultStyleDict;
}
getViewTipsPoint(step) {
const shape = this.state.mapShape[step.code];
if (shape) {
return this.$painter.getViewTipsPoint(step);
} else {
return this.subMap.getViewTipsPoint(step);
}
}
getEntityByModel(model) {
return utils.getEntityByModel(this.state.mapEntity, this.state.mapLink, model);
}
getShapeByCode(code) {
return this.state.mapShape[code];
}
getLinkByModel(model) {
return utils.getLinkByModel(this.state.mapLink, model);
}
resize(opt) {
this.$zr.resize(opt);
this.$painter.updateZrSize(opt);
}
refresh() {
this.$painter.refresh();
}
// 清除缓存
clearCaches() {
localStore.caches = null;
this.caches.clear();
}
// 清除草稿缓存
clearCachesDraft() {
localStore.cachesDraft = null;
this.cachesDraft = null;
}
clear() {
this.state.mapShape = {};
this.$controller.clear();
this.$painter.clear();
}
// 设置画面缓存
cache(state) {
const source = state.source;
if (source && source.id) {
this.caches.set(source.id, {...state});
}
}
// 设置草稿画面缓存
handleCachesDraft(key, state) {
if (key) {
if (this.cachesDraft && this.cachesDraft[key]) {
const data = this.cachesDraft[key];
if (!data[state.id]) {
const source = JSON.parse(JSON.stringify(state.value));
delete source.mapEntity;
data[state.id] = source;
}
} else {
this.cachesDraft = {};
// const map = new Map();
// const data = map.set(state.id, state.value);
// this.cachesDraft.set(key, data);
const source = JSON.parse(JSON.stringify(state.value));
delete source.mapEntity;
this.cachesDraft[key] = {
[state.id]: source,
mapEntity: state.value.mapEntity
};
}
}
}
dispose() {
this.disable();
this.clear();
this.$controller.dispose();
this.$painter.dispose();
localStore.caches = this.caches;
if (this.$zr) {
this.$zr.dispose();
}
}
on(name, cb, context) {
const idx = Object.values(this.events).indexOf(name);
if (idx >= 0) {
switch (name) {
case this.events.Reflect:
this.$controller.on(this.events.Reflect, _.throttle(cb, 200), context);
break;
case this.events.Selected:
this.$controller.on(this.events.Selected, cb, context);
break;
case this.events.ContextMenu:
this.$controller.on(this.events.ContextMenu, cb, context);
break;
case this.events.DataZoom:
this.$controller.on(this.events.DataZoom, cb, context);
break;
case this.events.Keydown:
this.$controller.on(this.events.Keydown, cb, context);
break;
case this.events.Keypress:
this.$controller.on(this.events.Keypress, cb, context);
break;
case this.events.Keyup:
this.$controller.on(this.events.Keyup, cb, context);
break;
}
}
}
off(name, cb) {
const idx = Object.values(this.events).indexOf(name);
if (idx >= 0) {
switch (name) {
case this.events.Reflect:
this.$controller.on(this.events.Reflect, _.throttle(cb, 200));
break;
case this.events.Selected:
this.$controller.off(this.events.Selected, cb);
break;
case this.events.ContextMenu:
this.$controller.off(this.events.ContextMenu, cb);
break;
case this.events.DataZoom:
this.$controller.off(this.events.DataZoom, cb);
break;
case this.events.Keydown:
this.$controller.off(this.events.Keydown, cb);
break;
case this.events.Keypress:
this.$controller.off(this.events.Keypress, cb);
break;
case this.events.Keyup:
this.$controller.off(this.events.Keyup, cb);
break;
}
}
}
}
export default Jlmap;

990
src/iscs_new/mapper.js Normal file
View File

@ -0,0 +1,990 @@
import graphType from './constant/graphType';
// import * as utils from './utils/utils';
import store from '@/store';
import { MapTypeEnum, DcsModeEnum } from '@/scripts/ConstDic';
class Mapper {
constructor() {
this.__Dialog = {};
this.__mapper = {};
this.loadDialogData();
this.loadMapper();
}
loadDialogData() {
this.__Dialog['tpsq'] = {
ElectricGlobeValve: {
DCS: {
Left: {
command: 'ElectricGlobeValve',
dialogName: 'Adjust-Power'
},
Right: []
}
},
ElectricPlowUnloader: { // 犁
DCS: {
Left: {
command: 'ElectricPlowUnloader',
dialogName: 'Adjust-Powload'
},
Right: []
}
},
MagneticGlobeValve: {
DCS: {
Left: {
command: 'MagneticGlobeValve',
dialogName: 'Adjust-Power'
},
Right: []
}
},
PneumaticGlobeValve: {
DCS: {
Left: {
command: 'PneumaticGlobeValve',
dialogName: 'Adjust-Power'
},
Right: []
}
},
Motor: {
DCS: {
Left: {
command: 'Motor',
dialogName: 'Adjust-Power'
},
Right: []
}
},
Burner: {
DCS: {
Left: {
command: 'Burner',
dialogName: 'Adjust-Power'
},
Right: []
}
},
ElectricControlValve: {
DCS: {
Left: {
command: 'ElectricControlValve',
dialogName: 'Adjust-Setting'
},
Right: []
}
},
FrequencyConverter: {
DCS: {
Left: {
command: 'FrequencyConverter',
dialogName: 'Adjust-Setting'
},
Right: []
}
},
ManualGlobeValve: {
DCS: {
Left: {
command: 'ManualGlobeValve',
dialogName: 'Hand-Switch-Power'
},
Right: []
}
},
ThreePortValve: { // 三通阀
DCS: {
Left: {
command: 'ThreePortValve',
dialogName: 'Hand-Side-Forward'
},
Right: []
}
},
[graphType.Popup]: {
DCS: {
Left: {
command: 'Popup',
dialogName: 'Popup-Panel'
},
Right: []
}
},
[graphType.Pid]: {
DCS: {
Left: {
command: 'Pid',
dialogName: 'Popup-Pid-Panel'
},
Right: []
}
},
[graphType.ProgramControl]: {
DCS: {
Left: {
command: 'ProgramControl',
dialogName: 'Popup-Program-Panel'
},
Right: []
}
},
[graphType.Switching]: {
DCS: {
Left: {
command: 'Switching',
dialogName: 'Switching'
},
Right: []
}
}
};
this.__Dialog['neepu'] = {
// N质量流量控制器
NMassFlowController: {
DCS: {
Left: {},
Right: [
{
name: '自动调节',
sign: 'AUTO_REGULATING',
dialogName: 'Auto-Regulating'
}
]
},
Site: {
Left: {},
Right: [
{
name: '自动调节',
sign: 'AUTO_REGULATING',
dialogName: 'Auto-Regulating'
}
]
}
},
// 报警温度计
NAlarmThermometer: {
System: {
Left: {},
Right: [
{
name: '清除报警',
sign: 'CANCEL_WARNING',
command: 'CANCEL_WARNING'
}
]
}
},
// 恒温装置
NThermostat: {
System: {
Left: {},
Right: [
{
name: '启动/停止',
sign: 'SWITCH_TO',
dialogName: 'Switch-Power',
signParams: {
open: 'OPEN',
close: 'CLOSE'
}
}
]
}
},
// N辅助油泵
NAuxiliaryOilPump: {
DCS: {
Left: {},
Right: [
{
name: '启动/停止',
dialogName: 'Switch-Power',
signParams: {
open: 'OPEN',
close: 'CLOSE'
}
}
]
}
},
// N凝结水泵
NCondensatePump: {
DCS: {
Left: {},
Right: [
{
name: '启动/停止',
dialogName: 'Switch-Power',
signParams: {
open: 'OPEN',
close: 'CLOSE'
}
}
]
}
},
// N计量泵
NDosingPump: {
DCS: {
Left: {},
Right: [
{
name: '启动/停止',
sign: 'SWITCH_TO',
dialogName: 'Switch-Power',
signParams: {
open: 'OPEN',
close: 'CLOSE'
},
isShow: (el) => { return el.controlMode === 'Remote'; }
},
{
name: '设置频率',
sign: 'SET_FREQ',
dialogName: 'Frequency-Input',
isShow: (el) => { return el.controlMode === 'Remote'; }
},
{
name: 'PID调节',
sign: 'PID_REGULATING',
dialogName: 'Dosing-Pump-Target',
isShow: (el) => { return el.controlMode === 'Remote'; }
}
]
},
Site: {
Left: {},
Right: [
{
name: '手动冲程',
sign: 'SET_STROKE',
dialogName: 'Frequency-Setting'
}
]
}
},
// N搅拌电机
NMixingMotor: {
DCS: {
Left: {},
Right: [
{
name: '启动/停止',
dialogName: 'Switch-Power',
signParams: {
open: 'OPEN',
close: 'CLOSE'
},
isShow: (el) => { return el.controlMode === 'Remote'; }
}
]
}
},
// N虚拟组合阀
NVirtualCombinationValve: {
DCS: {
Left: {},
Right: [
{
name: '打开/关闭',
dialogName: 'Switch-Power',
signParams: {
open: 'OPEN',
close: 'CLOSE'
}
}
]
}
},
// 电动截止阀
ElectricGlobeValve: {
DCS: {
Left: {},
Right: [
{
name: '打开/关闭',
sign: 'SWITCH_TO',
dialogName: 'Switch-Power',
signParams: {
open: 'OPEN',
close: 'CLOSE'
},
isShow: (el) => { return el.controlMode == null || el.controlMode === 'Remote'; }
}
]
}
},
// 手动截止阀
ManualGlobeValve: {
Site: {
Left: {},
Right: [
{
name: '打开/关闭',
sign: 'SWITCH_TO',
dialogName: 'Switch-Power',
signParams: {
open: 'OPEN',
close: 'CLOSE'
}
}
]
},
System: {
Left: {},
Right: [
{
name: '打开/关闭',
sign: 'SWITCH_TO',
dialogName: 'Switch-Power',
signParams: {
open: 'OPEN',
close: 'CLOSE'
}
}
]
}
},
// N溶液箱
NStirredSolutionTank: {
DCS: {
Left: {},
Right: [
{
name: '设置为标液',
sign: 'SET_STANDARD',
dialogName: 'Standard-Input',
isShow: (el) => !el.solidDosing
},
{
name: '设置为标液',
sign: 'SET_STANDARD',
dialogName: 'Standard-Setting',
isShow: (el) => el.solidDosing
},
{
name: '取消设置',
sign: 'CANCEL_SET',
command: 'CANCEL_SET'
}
]
// SET_STANDARD({model, instance}) {
// const attrObj = utils.getObjFormListBySign(model.attrList, 'solidDosingDeviceCode');
// return attrObj && attrObj.val ? 'StandardSetting': 'StandardInput';
// }
},
Site: {
Left: {},
Right: [
{
name: '设置为标液',
sign: 'SET_STANDARD',
dialogName: 'Standard-Input',
isShow: (el) => !el.solidDosing
},
{
name: '设置为标液',
sign: 'SET_STANDARD',
dialogName: 'Standard-Setting',
isShow: (el) => el.solidDosing
},
{
name: '取消设置',
sign: 'CANCEL_SET',
command: 'CANCEL_SET'
}
]
// SET_STANDARD({model, instance}) {
// const attrObj = utils.getObjFormListBySign(model.attrList, 'solidDosingDeviceCode');
// return attrObj && attrObj.val ? 'StandardSetting': 'StandardInput';
// }
}
},
// N固体加药器
NSolidDoser: {
DCS: {
Left: {},
Right: [
{
name: '加药',
sign: 'DOSE',
dialogName: 'Solid-Dosing-Input'
}
]
},
Site: {
Left: {},
Right: [
{
name: '加药',
sign: 'DOSE',
dialogName: 'Solid-Dosing-Input'
}
]
}
},
// N带灯按钮
NIlluminatedButton: {
DCS: {
Left: {},
Right: []
},
Site: {
Left: {
command: 'CLICK'
},
Right: []
}
},
// 转换开关
NChangeoverSwitch: {
DCS: {},
Site: {
Left: {
command: 'CHANGE_OVER'
},
Right: []
}
},
// 手轮
NHandWheel: {
DCS: {},
Site: {
Left: {
command: 'ADJUST',
dialogName: 'Adjust-Opening'
},
Right: [
// {
// name: '调频',
// sign: 'ADJUST',
// dialogName: 'Adjust-Opening'
// }
]
}
}
};
}
loadMapper() {
this.__menus = {
// 质量流量控制器
MassFlowController: [
{
mode: 'Right',
name: '说明',
sign: 'MENU_EXPLAIN',
graphType: 'DCS'
},
{
mode: 'Right',
name: '说明',
sign: 'MENU_EXPLAIN',
graphType: 'Site'
}
]
};
}
filter(sign, node) { // 根据模式过滤菜单
const mapper = {
PID_REGULATING() {
return store.state.map.dcsMode == DcsModeEnum.Auto
? node : null;
},
AUTO_REGULATING() {
return store.state.map.dcsMode == DcsModeEnum.Auto || store.state.map.mapType == MapTypeEnum.Site
? node : null;
},
__default() {
return store.state.map.dcsMode == DcsModeEnum.Auto
? null: node;
}
};
return mapper[sign]? mapper[sign](): mapper.__default();
}
concat(menus, type) {
const _menus = this.__menus[type];
return _menus? menus.concat(_menus.map(el => { return Object.assign(el, {local: true}); })) : menus;
}
getPopUp({type, graphType, projectSign}, device, isLeft) {
const dialog = this.__Dialog[projectSign];
graphType = graphType || 'Other';
if (dialog[type] && dialog[type][graphType]) {
if (isLeft) {
return dialog[type][graphType]['Left'] ? dialog[type][graphType]['Left'] : null;
} else {
return dialog[type][graphType]['Right'];
}
}
}
}
export default new Mapper();
[
{
'name': '加药控制柜',
'type': 'DosingControlCabinet',
'operationList': [{
'id': '32',
'name': '切换控制模式',
'graphType': 'Site',
'sign': 'SWITCH_TO',
'mode': 'Other',
'param': '',
'popup': ''
}, {
'id': '33',
'name': '切换控制模式',
'graphType': 'DCS',
'sign': 'SWITCH_TO',
'mode': 'Other',
'param': '',
'popup': ''
}]
},
{
'name': '搅拌溶液箱',
'type': 'StirredSolutionTank',
'operationList': [{
'id': '28',
'name': '设置为标液',
'graphType': 'Site',
'sign': 'SET_STANDARD',
'mode': 'Right',
'param': '',
'popup': 'standard-setting'
}, {
'id': '29',
'name': '取消设置',
'graphType': 'Site',
'sign': 'CANCEL_SET',
'mode': 'Right',
'param': '',
'popup': ''
}, {
'id': '30',
'name': '设置为标液',
'graphType': 'DCS',
'sign': 'SET_STANDARD',
'mode': 'Right',
'param': '',
'popup': 'standard-setting'
}, {
'id': '31',
'name': '取消设置',
'graphType': 'DCS',
'sign': 'CANCEL_SET',
'mode': 'Right',
'param': '',
'popup': ''
}]
},
{
'id': '4',
'name': '手动球阀',
'type': 'ManualBallValve',
'operationList': [{
'id': '3',
'name': '打开/关闭',
'graphType': 'Site',
'sign': 'SWITCH_TO',
'mode': 'Right',
'param': '',
'popup': 'switch-status'
}, {
'id': '19',
'name': '打开/关闭',
'graphType': 'System',
'sign': 'SWITCH_TO',
'mode': 'Right',
'param': '',
'popup': 'switch-status'
}]
},
{
'id': '5',
'name': '电动球阀',
'type': 'ElectronicBallValve',
'operationList': [{
'id': '14',
'name': '打开',
'graphType': 'Site',
'sign': 'OPEN',
'mode': 'Other',
'param': '',
'popup': ''
}, {
'id': '15',
'name': '关闭',
'graphType': 'Site',
'sign': 'CLOSE',
'mode': 'Other',
'param': '',
'popup': ''
}, {
'id': '16',
'name': '打开/关闭',
'graphType': 'DCS',
'sign': 'SWITCH_TO',
'mode': 'Right',
'param': '',
'popup': 'power-status'
}]
},
{
'name': '搅拌电机',
'type': 'MixingMotor',
'operationList': [{
'id': '2',
'name': '启动/停止',
'graphType': 'DCS',
'sign': 'SWITCH_TO',
'mode': 'Right',
'param': '',
'popup': 'switch-status'
}, {
'id': '17',
'name': '启动',
'graphType': 'Site',
'sign': 'OPEN',
'mode': 'Other',
'param': '',
'popup': ''
}, {
'id': '18',
'name': '停止',
'graphType': 'Site',
'sign': 'CLOSE',
'mode': 'Other',
'param': '',
'popup': ''
}, {
'id': '22',
'name': '设置故障',
'graphType': 'DCS',
'sign': 'SET_FAULT',
'mode': 'Fault',
'param': '',
'popup': ''
}, {
'id': '23',
'name': '取消故障',
'graphType': 'DCS',
'sign': 'CANCEL_FAULT',
'mode': 'Fault',
'param': '',
'popup': ''
}]
},
{
'id': '8',
'name': '带灯按钮',
'type': 'IlluminatedButton',
'operationList': [{
'id': '5',
'name': '开/关',
'graphType': 'Site',
'sign': 'IlluminatedButton',
'mode': 'Left',
'param': '',
'popup': ''
}]
},
{
'name': '转换开关',
'type': 'ChangeoverSwitch',
'operationList': [{
'id': '4',
'name': '开/关',
'graphType': 'Site',
'sign': '{{mapMode}}',
'mode': 'Left',
'param': '',
'popup': ''
}]
},
{
'name': '电磁球阀',
'type': 'ElectromagneticBallValve',
'operationList': [{
'id': '48',
'name': '关闭',
'graphType': 'Site',
'sign': 'CLOSE',
'mode': 'Other',
'param': '',
'popup': ''
}, {
'id': '49',
'name': '打开',
'graphType': 'Site',
'sign': 'OPEN',
'mode': 'Other',
'param': '',
'popup': ''
}]
},
{
'name': '加药计量泵',
'type': 'DosingPump',
'operationList': [{
'id': '8',
'name': '启动',
'graphType': 'Site',
'sign': 'OPEN',
'mode': 'Other',
'param': '',
'popup': ''
}, {
'id': '9',
'name': '停止',
'graphType': 'Site',
'sign': 'CLOSE',
'mode': 'Other',
'param': '',
'popup': ''
}, {
'id': '13',
'name': '启动/停止',
'graphType': 'DCS',
'sign': 'SWITCH_TO',
'mode': 'Right',
'param': '',
'popup': 'switch-status'
}, {
'id': '24',
'name': '设置故障',
'graphType': 'Site',
'sign': 'SET_FAULT',
'mode': 'Fault',
'param': '',
'popup': ''
}, {
'id': '25',
'name': '取消故障',
'graphType': 'Site',
'sign': 'CANCEL_FAULT',
'mode': 'Fault',
'param': '',
'popup': ''
}, {
'id': '26',
'name': '设置频率',
'graphType': 'DCS',
'sign': 'SET_FREQ',
'mode': 'Right',
'param': '',
'popup': 'frequency-input'
}, {
'id': '27',
'name': '手动冲程',
'graphType': 'Site',
'sign': 'SET_STROKE',
'mode': 'Right',
'param': '',
'popup': 'frequency-setting'
}, {
'id': '51',
'name': 'PID调节',
'graphType': 'DCS',
'sign': 'PID_REGULATING',
'mode': 'Right',
'param': ''
}]
},
{
'name': '高温高压阀',
'type': 'ManualNeedleValve',
'operationList': [{
'id': '20',
'name': '打开/关闭',
'graphType': 'System',
'sign': 'SWITCH_TO',
'mode': 'Right',
'param': '',
'popup': 'switch-status'
}, {
'id': '21',
'name': '打开/关闭',
'graphType': 'Site',
'sign': 'SWITCH_TO',
'mode': 'Right',
'param': '',
'popup': 'switch-status'
}]
},
{
'name': '温度表',
'type': 'Thermometer',
'operationList': [{
'id': '38',
'name': '取消报警',
'graphType': 'System',
'sign': 'CANCEL_WARNING',
'mode': 'Right',
'param': '',
'popup': ''
}]
},
{
'name': '恒温装置',
'type': 'Thermostat',
'operationList': [{
'id': '36',
'name': '切换',
'graphType': 'Site',
'sign': 'SWITCH_TO',
'mode': 'Other',
'param': '',
'popup': ''
}]
},
{
'name': '固体加药器',
'type': 'SolidDoser',
'operationList': [{
'id': '34',
'name': '加药',
'graphType': 'Site',
'sign': 'DOSE',
'mode': 'Right',
'param': '',
'popup': 'solid-dosing-setting'
}, {
'id': '35',
'name': '加药',
'graphType': 'DCS',
'sign': 'DOSE',
'mode': 'Right',
'param': '',
'popup': 'solid-dosing-setting'
}]
},
{
'name': '虚拟组合阀',
'type': 'VirtualCombinationValve',
'operationList': [{
'id': '39',
'name': '打开/关闭',
'graphType': 'DCS',
'sign': 'SWITCH_TO',
'mode': 'Right',
'param': '',
'popup': 'switch-status'
}]
},
{
'name': '高压阀',
'type': 'HighPressureValve',
'operationList': [{
'id': '50',
'name': '调节',
'graphType': '',
'sign': 'ADJUST_OPENING',
'mode': 'Other',
'param': ''
}]
},
{
'name': '减压阀',
'type': 'ReductionValve',
'operationList': [{
'id': '43',
'name': '打开/关闭',
'graphType': 'Site',
'sign': 'SWITCH_TO',
'mode': 'Right',
'param': '',
'popup': 'switch-status'
}, {
'id': '44',
'name': '打开/关闭',
'graphType': 'System',
'sign': 'SWITCH_TO',
'mode': 'Right',
'param': '',
'popup': 'switch-status'
}]
},
{
'name': '止回阀',
'type': 'CheckValve',
'operationList': [{
'id': '45',
'name': '打开/关闭',
'graphType': 'Site',
'sign': 'SWITCH_TO',
'mode': 'Right',
'param': '',
'popup': 'switch-status'
}, {
'id': '46',
'name': '打开/关闭',
'graphType': 'System',
'sign': 'SWITCH_TO',
'mode': 'Right',
'param': '',
'popup': 'switch-status'
}]
},
{
'name': '质量流量控制器',
'type': 'MassFlowController',
'operationList': [{
'id': '52',
'name': '自动调节',
'graphType': 'Site',
'sign': 'AUTO_REGULATING',
'mode': 'Right',
'param': ''
}, {
'id': '53',
'name': '自动调节',
'graphType': 'DCS',
'sign': 'AUTO_REGULATING',
'mode': 'Right',
'param': ''
}]
},
{
'name': '调节阀',
'type': 'ControlValve',
'operationList': [{
'id': '47',
'name': '调节',
'graphType': '',
'sign': 'ADJUST_OPENING',
'mode': 'Other',
'param': ''
}]
},
{
'name': '加氧控制柜',
'type': 'OxygenationControlCabinet',
'operationList': [{
'id': '40',
'name': '切换控制模式',
'graphType': '',
'sign': 'SWITCH_TO',
'mode': 'Other',
'param': '',
'popup': ''
}, {
'id': '41',
'name': '切换控制模式',
'graphType': 'DCS',
'sign': 'SWITCH_TO',
'mode': 'Other',
'param': '',
'popup': ''
}]
}
];

128
src/iscs_new/maps.js Normal file
View File

@ -0,0 +1,128 @@
import * as utils from './utils/utils';
import * as Dom from './utils/dom';
import Emap from './map';
const DOM_ATTRIBUTE_KEY = '_maps_instance_';
class Emaps {
constructor() {
this._version = '1.1.1';
this.instances = {};
this.mapShape = {};
this.mapEntity = {};
this.mapLink = {};
}
init(opts) {
if (!opts) {
throw new Error('Initialize failed: invalid params.');
}
if (!opts.dom && opts.el) {
opts['dom'] = document.getElementById(opts.el);
}
if (!opts.dom) {
throw new Error('Initialize failed: invalid dom and el.');
}
const existInstance = this.getInstanceByDom(opts.dom);
if (existInstance) {
console.warn('There is a chart instance already initialized on the dom.');
return existInstance;
}
if (Dom.isDom(opts.dom) && opts.dom.nodeName.toUpperCase() !== 'CANVAS' &&
(
(!opts.dom.clientWidth && (!opts || opts.width == null)) ||
(!opts.dom.clientHeight && (!opts || opts.height == null))
)
) {
console.warn('Can\'t get DOM width or height. Please check ' +
'dom.clientWidth and dom.clientHeight. They should not be 0.' +
'For example, you may need to call this in the callback ' +
'of window.onload.');
}
const emap = new Emap(opts);
this.instances[opts.el] = emap;
Dom.setAttribute(opts.dom, DOM_ATTRIBUTE_KEY, opts.el);
return emap;
}
loadState(state) {
// 解析后的数据
this.mapShape = utils.assignByDeep(this.mapShape, state.mapShape||{}, 0);
// 实体数据
this.mapEntity = utils.assignByDeep(this.mapEntity, state.mapEntity||{}, 0);
// 实体关系
this.mapLink = utils.assignByDeep(this.mapLink, state.mapLink||{}, 1);
}
setMap(map, opts, judge = false) {
const { state } = opts;
if (!judge) {
this.loadState(state);
}
map.setMap(opts);
}
getVersion() {
return this._version;
}
getInstanceByDom(dom) {
return this.instances[Dom.getAttribute(dom, DOM_ATTRIBUTE_KEY)];
}
getInstanceById(el) {
return this.instances[el];
}
getMapShape() {
return this.mapShape;
}
getMapEntity() {
return this.mapEntity;
}
getMapLink() {
return this.mapLink;
}
getShapeByCode(code) {
return this.mapShape[code];
}
getEntityByModel(model) {
return utils.getEntityByModel(this.mapEntity, this.mapLink, model);
}
getLinkByModel(model) {
return utils.getLinkByModel(this.mapLink, model);
}
clearMapEntity() {
this.mapEntity = {};
}
dispose(emap) {
if (utils.isString(emap)) {
emap = this.instances[emap];
} else if (!utils.isInstanceOf(emap, Emap)) {
emap = this.getInstanceByDom(emap.getDom());
}
if (emap) {
emap.dispose();
}
}
}
export default Emaps;

101
src/iscs_new/options.js Normal file
View File

@ -0,0 +1,101 @@
class Options {
constructor(opts, trigger) {
this.scaleIndex = 0;
this.scaleList = [
0.2, 0.3, 0.4, 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.panEnable = true;
this.zoomEnable = 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.panEnable === true || payload.panEnable === false) {
this.panEnable = payload.panEnable;
}
if (payload.zoomEnable === true || payload.zoomEnable === false) {
this.zoomEnable = payload.zoomEnable;
}
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;

View File

@ -0,0 +1,623 @@
import * as graphic from '../../../graph/graphic';
import * as utils from '../../../utils/utils';
import RadialGradient from 'zrender/src/graphic/RadialGradient';
import LinearGradient from 'zrender/src/graphic/LinearGradient';
import panelType from '../../../constant/panelType';
import ConstSelect from '@/scripts/ConstConfig';
import { handleColor } from '@/map/utils/utils.js';
import store from '@/store';
import { MapTypeEnum } from '@/scripts/ConstDic.js';
import Vue from 'vue';
class Adaptor {
constructor({model}, state, graph) {
this.__graph = graph;
this.__model = model;
this.__state = state;
}
get() {
const model = this.__model;
const sceneType = this.__state.mapType;
const block = sceneType ? utils.getBlockBySceneType(model, sceneType) : null;
this.__graph._block = block;
return Object.assign(model, block);
}
}
export default class LinePipe extends graphic.Group {
constructor(painter, shape, state) {
super();
this._code = shape.model.code;
this._type = shape.model._type;
this._shape = shape;
this._painter = painter;
this._state = state;
this._block = null;
this._adaptor = new Adaptor(shape, state, this);
this._elMap = {
lines: [],
circles: [],
line: null,
flow: null,
lArrow: null,
rArrow: null,
lText: null,
rText: null
};
this.create();
this.on('mouseover', this.mouseover, this);
this.on('mouseout', this.mouseout, this);
}
mouseover(e) {
if (this._shape.draw) {
this.doActive(this.__zr);
}
}
mouseout(e) {
const map = this._painter.$map;
if (this._shape.draw && !map.isHover(this._code)) {
this.doInactive(this.__zr);
}
}
create() {
const mapType = store.state.map.mapType;
const model = this._adaptor.get();
const style = this._shape.style;
const draw = this._shape.draw;
const color = model.color;
const isVisible = this._state.isDraw
? true
: model.hasOwnProperty('visible') ? model.visible: true;
let modelData = {};
if (model.sceneTypes) {
const modelIndex = model.sceneTypes.indexOf(mapType);
modelData = model.graphList[modelIndex]; // 对应模式下数据
} else {
modelData = Object.assign(modelData, model);
}
if (isVisible && this._block) {
if (model && modelData.points && modelData.points.length >= 2) {
if (mapType == MapTypeEnum.Site) {
modelData.points.forEach((point, index) => {
if (index) {
const line = new graphic.Polyline({
zlevel: model.zlevel,
z: model.z,
z2: this.getZ2(index, mapType),
silent: !draw,
shape: {
smooth: model.smooth / 10
},
style: {
blend: 'source-over',
lineWidth: parseFloat(modelData.width),
stroke: this.getLinearGradient(color)
}
});
this._elMap.lines.push(utils.lineProxy(line, modelData.points[index-1], modelData.points[index]));
if (index > 0 && index < modelData.points.length-1) {
const circle = new graphic.Circle({
zlevel: model.zlevel,
z: model.z,
z2: model.layer || 0,
silent: !draw,
shape: {
cx: modelData.points[index].x,
cy: modelData.points[index].y,
r: parseFloat(modelData.width || 2) / 2
},
style: {
blend: 'source-over',
fill: this.getRadialGradient(color)
}
});
this._elMap.circles.push(circle);
}
}
});
} else {
this._elMap.line = new graphic.Polyline({
zlevel: model.zlevel,
z: model.z,
z2: model.layer || 0,
silent: !draw,
shape: {
points: modelData.points.map(elem => { return [elem.x, elem.y]; }),
smooth: model.smooth / 10
},
style: {
lineJoin: 'round',
lineWidth: parseFloat(modelData.width) || style[panelType.LinePipe].line.lineWidth,
stroke: color
}
});
}
// 文字和状态
if (!this._shape.draw) {
this._elMap.flow = new graphic.Polyline({
zlevel: model.zlevel,
// z: model.z,
// z2: model.layer + 5,
z: model.z + 1,
z2: model.layer || 0,
silent: true,
shape: {
points: modelData.points.map(elem => { return [elem.x, elem.y]; }),
smooth: model.smooth / 10
},
style: {
lineDash: [8, 8],
lineWidth: parseFloat(modelData.width) * (mapType == MapTypeEnum.Site? 0.8 : 1)
}
});
this._elMap.flow.hide();
}
const lradian = utils.getRadian(modelData.points[1], modelData.points[0]);
this._elMap.lText = new graphic.Text({
zlevel: model.zlevel,
z: model.z+9,
z2: (model.layer || 0),
silent: true,
style: {
x: modelData.points[0].x+Math.sin(lradian)*(parseFloat(modelData.width/2)+style.fontSize+5),
y: modelData.points[0].y+Math.cos(lradian)*(parseFloat(modelData.width/2)+style.fontSize+5),
fontWeight: 'normal',
fontSize: style.fontSize,
fontFamily: style.fontFamily,
text: 'A',
textFill: '#fff',
textAlign: 'left',
textVerticalAlign: 'top',
textPadding: [2, 2]
}
});
this._elMap.lText.hide();
const rradian = utils.getRadian(modelData.points[modelData.points.length-2], modelData.points[modelData.points.length-1]);
this._elMap.rText = new graphic.Text({
zlevel: model.zlevel,
z: model.z+9,
z2: (model.layer || 0),
silent: true,
style: {
x: modelData.points[modelData.points.length-1].x+Math.sin(rradian)*(parseFloat(modelData.width/2)+style.fontSize+5),
y: modelData.points[modelData.points.length-1].y+Math.cos(rradian)*(parseFloat(modelData.width/2)+style.fontSize+5),
fontWeight: 'normal',
fontSize: style.fontSize,
fontFamily: style.fontFamily,
text: 'B',
textFill: '#fff',
textAlign: 'right',
textVerticalAlign: 'bottom',
textPadding: [2, 2]
}
});
this._elMap.rText.hide();
// 左侧显示
if (['Inlet', 'Outlet'].includes(modelData.leftArrow)) {
if (mapType !== MapTypeEnum.Site) {
const dx = modelData.points[1].x - modelData.points[0].x;
const dy = modelData.points[1].y - modelData.points[0].y;
this._elMap.lArrow = new graphic.ArrowLine({
zlevel: model.zlevel,
z: model.z,
z2: model.layer || 0,
silent: true,
origin: [
modelData.points[0].x,
modelData.points[0].y
],
rotation: -Math.atan2(dy, dx),
shape: {
x: modelData.points[0].x,
y: modelData.points[0].y,
isLeft: true,
toLeft: modelData.leftArrow == 'Outlet'
},
style: {
lineWidth: style[panelType.LinePipe].arrow.lineWidth,
stroke: color
}
});
} else {
const circle = new graphic.Circle({
zlevel: model.zlevel,
z: model.z,
z2: model.layer || 0,
silent: !draw,
shape: {
cx: modelData.points[0].x,
cy: modelData.points[0].y,
r: parseFloat(modelData.width) / 2
},
style: {
blend: 'source-over',
fill: this.getRadialGradient(color)
}
});
this._elMap.circles.push(circle);
}
}
// 右侧显示
if (['Inlet', 'Outlet'].includes(modelData.rightArrow)) {
const arrowIndex = modelData.points.length - 1;
if (mapType !== MapTypeEnum.Site) {
const dx = modelData.points[arrowIndex].x - modelData.points[arrowIndex-1].x;
const dy = modelData.points[arrowIndex].y - modelData.points[arrowIndex-1].y;
this._elMap.rArrow = new graphic.ArrowLine({
zlevel: model.zlevel,
z: model.z,
z2: model.layer || 0,
silent: true,
origin: [
modelData.points[arrowIndex].x,
modelData.points[arrowIndex].y
],
rotation: -Math.atan2(dy, dx),
shape: {
x: modelData.points[arrowIndex].x,
y: modelData.points[arrowIndex].y,
isLeft: arrowIndex == 0,
toLeft: modelData.rightArrow == 'Inlet'
},
style: {
lineWidth: style[panelType.LinePipe].arrow.lineWidth,
stroke: color
}
});
} else {
const circle = new graphic.Circle({
zlevel: model.zlevel,
z: model.z,
z2: model.layer || 0,
silent: !draw,
shape: {
cx: modelData.points[arrowIndex].x,
cy: modelData.points[arrowIndex].y,
r: parseFloat(modelData.width) / 2
},
style: {
blend: 'source-over',
fill: this.getRadialGradient(color)
}
});
this._elMap.circles.push(circle);
}
}
if ((ConstSelect.ConstMap.LSvgs[modelData.leftArrow]||{}).path) {
const rotation = -Math.atan2(
modelData.points[1].y-modelData.points[0].y,
modelData.points[1].x-modelData.points[0].x
);
const path = ConstSelect.ConstMap.LSvgs[modelData.leftArrow].path;
this._elMap.lArrow = new graphic.Svg({
zlevel: model.zlevel,
z: model.z,
z2: (model.layer || 0),
origin: [0, 0],
rotation,
shape: {
x: modelData.points[0].x,
y: modelData.points[0].y,
path
},
style: {
lineWidth: style[panelType.LinePipe].arrow.lineWidth,
stroke: path.includes('stroke')? modelData.color: 'transparent ',
fill: path.includes('fill')? modelData.color: 'transparent '
}
});
}
if ((ConstSelect.ConstMap.RSvgs[modelData.rightArrow]||{}).path) {
const len = modelData.points.length-1;
const rotation = -Math.atan2(
modelData.points[len].y-modelData.points[len-1].y,
modelData.points[len].x-modelData.points[len-1].x
);
const path = ConstSelect.ConstMap.RSvgs[modelData.rightArrow].path;
this._elMap.rArrow = new graphic.Svg({
zlevel: model.zlevel,
z: model.z,
z2: (model.layer || 0),
origin: [0, 0],
rotation,
shape: {
x: modelData.points[len].x,
y: modelData.points[len].y,
path
},
style: {
lineWidth: style[panelType.LinePipe].arrow.lineWidth,
stroke: path.includes('stroke')? modelData.color: 'transparent ',
fill: path.includes('fill')? modelData.color: 'transparent '
}
});
}
if (this._elMap.lines) {
this._elMap.lines.forEach(item => {
item.setStyle('lineDash', {
'Solid': null, // 实线
'Dotted': [12, 6], // 虚线
'Point': [4, 4], // 点线
'DotPointA': [12, 4, 4, 4], // 一类虚点线
'DotPointB': [12, 4, 4, 4, 4, 4] // 二类虚点线
}[model.type]);
});
}
if (this._elMap.line) {
this._elMap.line.setStyle('lineDash', {
'Solid': null, // 实线
'Dotted': [12, 6], // 虚线
'Point': [4, 4], // 点线
'DotPointA': [12, 4, 4, 4], // 一类虚点线
'DotPointB': [12, 4, 4, 4, 4, 4] // 二类虚点线
}[model.type]);
}
}
}
this.setState(model);
Object.values(this._elMap).forEach(elem => { elem && elem instanceof Array? elem.forEach(el => this.add(el)): this.add(elem); });
}
getRadialGradient(color) {
return store.state.map.mapType == MapTypeEnum.Site
? new RadialGradient(0.5, 0.5, 0.5,
[
{offset: 0, color: '#FFFFFF'},
{offset: 1, color: color}
])
: color;
}
getLinearGradient(color) {
return store.state.map.mapType == MapTypeEnum.Site
? new LinearGradient(0, 0, 0, 1,
[
{offset: 0, color: color},
{offset: 0.5, color: '#FFFFFF'},
{offset: 1, color: color}
])
: color;
}
getZ2(index, mapType) {
const model = this._adaptor.get(mapType);
const layer = model.layer || 0;
const dx = model.points[index].x-model.points[index-1].x;
const dy = model.points[index].y-model.points[index-1].y;
return model.points.length>2? dx==0? layer : dy==0? layer+2 : layer+1 : layer+2;
}
setShape(model) {
const style = this._shape.style;
if (this._elMap.lines && this._elMap.lines.length) {
this._elMap.lines.forEach((line, index) => {
utils.lineProxy(line, model.points[index], model.points[index+1]);
});
}
if (this._elMap.circles && this._elMap.circles.length) {
this._elMap.circles.forEach((circle, index) => {
circle.setShape({
cx: model.points[index+1].x,
cy: model.points[index+1].y
});
});
}
if (this._elMap.lText) {
const lradian = utils.getRadian(model.points[1], model.points[0]);
this._elMap.lText.setStyle({
x: model.points[0].x + Math.sin(lradian) * (parseFloat(model.width/2) + style.fontSize + 5),
y: model.points[0].y + Math.cos(lradian) * (parseFloat(model.width/2) + style.fontSize + 5)
});
}
if (this._elMap.rText) {
const rradian = utils.getRadian(model.points[model.points.length-2], model.points[model.points.length-1]);
this._elMap.rText.setStyle({
x: model.points[model.points.length-1].x + Math.sin(rradian) * (parseFloat(model.width/2) + style.fontSize + 5),
y: model.points[model.points.length-1].y + Math.cos(rradian) * (parseFloat(model.width/2) + style.fontSize + 5)
});
}
if (model.graphList) {
const index = model.sceneTypes.findIndex(ele => ele == Vue.prototype.$map.state.mapType);
model.graphList[index].points = JSON.parse(JSON.stringify(model.points));
}
if (this._elMap.line) {
this._elMap.line.setShape({
points: model.points.map(elem => { return [elem.x, elem.y]; })
});
}
if (this._elMap.flow) {
this._elMap.flow.setShape({
points: model.points.map(elem => { return [elem.x, elem.y]; })
});
}
if (this._elMap.lArrow) {
const rotation = -Math.atan2(
model.points[1].y-model.points[0].y,
model.points[1].x-model.points[0].x
);
this._elMap.lArrow.attr('rotation', rotation);
this._elMap.lArrow.setShape({
x: model.points[0].x,
y: model.points[0].y
});
}
if (this._elMap.rArrow) {
const len = model.points.length-1;
const rotation = -Math.atan2(
model.points[len].y-model.points[len-1].y,
model.points[len].x-model.points[len-1].x
);
this._elMap.rArrow.attr('rotation', rotation);
this._elMap.rArrow.setShape({
x: model.points[len].x,
y: model.points[len].y
});
}
}
setState(model) {
const data = model.entity.data;
const mapType = store.state.map.mapType;
const pipeColorMap = store.state.map.pipeColorMap;
const projectSign = store.state.project.sign;
if (data && this._elMap.flow) {
if (data.filled) {
this._elMap.flow.show();
switch (data.from) {
case 'A': this.setFlowRun(data, true); break;
case 'B': this.setFlowRun(data, false); break;
default: this.setFlowStop(); break;
}
if (data.filler) {
if (projectSign == 'neepu') {
pipeColorMap[data.filler] && this._elMap.flow.setStyle({stroke: pipeColorMap[data.filler].name});
} else {
const stroke = model.color;
this._elMap.flow.setStyle({stroke});
}
if (mapType !== MapTypeEnum.Site) {
this._elMap.line.hide();
}
// this._elMap.line.hide();
}
} else {
this._elMap.flow.hide();
if (mapType !== MapTypeEnum.Site) {
this._elMap.line.show();
}
}
}
}
dragging(e) {
const model = this._shape.model;
model.points.map(elem => {
elem.x += e.dx;
elem.y += e.dy;
});
this.setShape(model);
}
setFlowRun(data, clockwise) {
const offsetMap = clockwise ? [32, 16, 0] : [0, 16, 32];
// const flowSpeed = Math.ceil(data.speed);
const flowSpeed = 5;
if (this._elMap.flow) {
this._elMap.flow.stopAnimation();
if (flowSpeed > 0) {
this._elMap.flow.animate('style', true)
.when(0, { lineDashOffset: offsetMap[0] * flowSpeed })
.when(1000, { lineDashOffset: offsetMap[1] * flowSpeed })
.when(2000, { lineDashOffset: offsetMap[2] * flowSpeed })
.start();
}
}
}
setFlowStop() {
if (this._elMap.flow) {
this._elMap.flow.stopAnimation();
}
}
setFlowClear() {
if (this._elMap.flow) {
this.remove(this._elMap.flow);
}
}
doActive(zr) {
if (zr||this.__zr) {
const style = this._shape.style;
const level = zr||this.__zr;
const falg = handleColor(this._shape.model.color, '#fff');
const stroke = falg ? style.pipeHover2Color : style.pipeHover2ColorDef;
if (this._elMap.line) {
level.addHover(this._elMap.line, { stroke });
}
this._elMap.lines.forEach(elem => {
if (elem) {
level.addHover(elem, { stroke });
}
});
this._elMap.lText && this._elMap.lText.show();
this._elMap.rText && this._elMap.rText.show();
if (!(
['Inlet', 'Outlet'].includes(this._shape.model.leftArrow) ||
['Inlet', 'Outlet'].includes(this._shape.model.rightArrow))) {
[this._elMap.lArrow, this._elMap.rArrow].forEach(el =>{
if (el) {
level.addHover(el, {
stroke: el.shape.path.includes('stroke')
? stroke
: 'transparent',
fill: el.shape.path.includes('fill')
? stroke
: 'transparent'
});
}
});
}
}
}
doInactive(zr) {
if (zr||this.__zr) {
const level = zr||this.__zr;
[this._elMap.line,
...this._elMap.lines,
this._elMap.lText,
this._elMap.rText,
this._elMap.lArrow,
this._elMap.rArrow
].forEach(elem => {
if (elem) {
level.removeHover(elem);
}
});
this._elMap.lText && this._elMap.lText.hide();
this._elMap.rText && this._elMap.rText.hide();
}
}
getViewTipsPoint() {}
}

View File

@ -0,0 +1,183 @@
import * as color from 'zrender/src/tool/color';
import * as graphic from '../../../graph/graphic';
import * as utils from '../../../utils/utils';
import Vue from 'vue';
import store from '@/store';
import ConstConfig from '@/scripts/ConstConfig';
class Adaptor {
constructor({model}, state, graph) {
this.__graph = graph;
this.__model = model;
this.__state = state;
}
get() {
const model = this.__model;
const sceneType = this.__state.mapType;
const block = sceneType ? utils.getBlockBySceneType(model, sceneType) : null;
this.__graph._block = block;
return Object.assign(model, block);
}
}
export default class Measure extends graphic.Group {
constructor(painter, shape, state) {
super();
this._code = shape.model.code;
this._type = shape.model._type;
this._shape = shape;
this._state = state;
this._painter = painter;
this._state = state;
this._block = null;
this._adaptor = new Adaptor(shape, state, this);
this._elMap = {
text: null
};
this.create();
this.on('mouseover', this.mouseover, this);
this.on('mouseout', this.mouseout, this);
}
mouseover(e) {
const model = this._shape.model;
if (this._shape.draw) {
this.doActive(this.__zr);
} else if (model.description) {
this._painter.$tipsHandle.trigger('show', {
x: e.offsetX,
y: e.offsetY,
text: model.description,
target: e.target
});
}
}
mouseout(e) {
const map = this._painter.$map;
if (this._shape.draw &&!map.isHover(this._code)) {
this.doInactive(this.__zr);
} else {
this._painter.$tipsHandle.trigger('hide');
}
}
create() {
const model = this._adaptor.get();
const modelLink = Vue.prototype.$maps.getLinkByModel(model); // 关联关系
let textFill = model.color || '#fff';
if (modelLink) {
textFill = modelLink.writable ? '#13f95a': model.color || '#fff';
}
if (this._block) {
this._elMap.text = new graphic.Text({
zlevel: model.zlevel,
z: model.z,
style: {
x: model.point.x,
y: model.point.y,
fontFamily: 'Times New Roman',
fontWeight: 'normal',
fontSize: model.size,
textVerticalAlign: 'middle',
textBackgroundColor: 'transparent',
text: this.format('--', model.unit),
textFill: model.color || '#fff',
textAlign: 'center',
textPadding: [3, 3, 1, 3],
rich: {
txt: {
fontSize: model.size,
textVerticalAlign: 'middle',
textFill: textFill
},
sup: {
fontSize: parseInt(model.size / 3),
textVerticalAlign: 'top'
},
sub: {
fontSize: parseInt(model.size / 3),
textVerticalAlign: 'bottom'
}
}
}
});
}
this.setState(model);
Object.values(this._elMap).forEach(elem => { elem && elem instanceof Array? elem.forEach(el => this.add(el)): this.add(elem); });
}
setShape(model) {
if (this._elMap.text) {
this._elMap.text.setStyle({
x: model.point.x,
y: model.point.y
});
}
}
setState(model) {
const data = model.entity.data ||{};
const decimalPlace = model.decimalPlace||0;
if (this._elMap.text && data) {
const value = data.value == undefined? '--' : Number(data.value||0).toFixed(decimalPlace);
this._elMap.text.setStyle({text: this.format(value, model.unit) });
}
}
format(value, unit) {
const projectSign = store.state.project.sign;
let msg = value;
if (projectSign != 'neepu') {
const obj = ConstConfig.ConstSelect.UnitTypeList.find(el => el.value == unit);
if (value != '--' && obj && obj.convert) {
msg = obj.convert(value);
}
return `{txt|${msg}} ${unit}`;
}
return `{txt|${msg}} ${unit}`;
}
dragging(e) {
const model = this._shape.model;
model.point.x += e.dx;
model.point.y += e.dy;
this.setShape(model);
}
doActive(zr) {
const style = this._shape.style;
const level = zr||this.__zr;
if (this._elMap.text && level) {
level.addHover(this._elMap.text, {
opacity: style.maskOpacity,
textBackgroundColor: color.lift(style.measureHover2Color, style.liftLevel)
});
}
}
doInactive(zr) {
const level = zr||this.__zr;
if (this._elMap.text &&level) {
level.removeHover(this._elMap.text);
}
}
getViewTipsPoint() {
const model = this._shape.model;
return {
x: model.point.x,
y: model.point.y
};
}
}

View File

@ -0,0 +1,159 @@
import * as color from 'zrender/src/tool/color';
import * as graphic from '../../../graph/graphic';
import panelType from '../../../constant/panelType';
export default class Pid extends graphic.Group {
constructor(painter, shape) {
super();
this._code = shape.model.code;
this._type = shape.model._type;
this._shape = shape;
this._painter = painter;
this._elMap = {
text: null,
button: null
};
this.create();
this.on('mouseover', this.mouseover, this);
this.on('mouseout', this.mouseout, this);
}
mouseover(e) {
const model = this._shape.model;
if (this._shape.draw) {
this._elMap.button.attr({cursor: 'pointer'});
this.doActive(this.__zr);
} else if (model.description) {
this._painter.$tipsHandle.trigger('show', {
x: e.offsetX,
y: e.offsetY,
text: model.description,
target: e.target
});
}
}
mouseout(e) {
const map = this._painter.$map;
if (this._shape.draw && !map.isHover(this._code)) {
this._elMap.button.attr({cursor: 'default'});
this.doInactive(this.__zr);
} else {
this._painter.$tipsHandle.trigger('hide');
}
}
create() {
const model = this._shape.model;
const style = this._shape.style;
this._elMap.button = new graphic.Rect({
zlevel: model.zlevel,
z: model.z,
shape: {
x: model.point.x-model.width/2,
y: model.point.y-model.height/2,
width: model.width,
height: model.height,
r: [1]
},
style: {
fill: style[panelType.Pid].button.fill,
stroke: style[panelType.Pid].button.stroke,
lineWidth: style[panelType.Pid].button.lineWidth,
shadowColor: '#dfdfdf',
shadowOffsetX: 1,
shadowOffsetY: 1
}
});
this._elMap.text = new graphic.Text({
zlevel: model.zlevel,
z: model.z,
z2: 2,
style: {
x: model.point.x,
y: model.point.y,
fontWeight: style[panelType.Pid].text.fontWeight,
fontFamily: style.fontFamily,
fontSize: model.fontSize,
text: model.text,
textFill: '#000',
textPadding: [4, 4],
textAlign: 'center',
textVerticalAlign: 'middle'
}
});
this.setState(model);
Object.values(this._elMap).forEach(elem => { elem && elem instanceof Array? elem.forEach(el => this.add(el)): this.add(elem); });
}
setShape(model) {
if (this._elMap.button) {
this._elMap.button.setShape({
x: model.point.x-model.width/2,
y: model.point.y-model.height/2
});
}
if (this._elMap.text) {
this._elMap.text.setStyle({
x: model.point.x,
y: model.point.y
});
}
}
setState(model) {}
dragging(e) {
const model = this._shape.model;
model.point.x += e.dx;
model.point.y += e.dy;
this.setShape(model);
}
doActive(zr) {
const style = this._shape.style;
const level = zr||this.__zr;
if (this._elMap.button && level) {
level.addHover(this._elMap.button, {
opacity: style.maskOpacity,
fill: color.lift(style.graphHover2Color, style.liftLevel)
});
}
if (this._elMap.text && level) {
level.addHover(this._elMap.text, {
opacity: style.maskOpacity,
textFill: color.lift(style.textHover2Color, style.liftLevel)
});
}
}
doInactive(zr) {
const level = zr||this.__zr;
if ( this._elMap.button && level) {
level.removeHover(this._elMap.button);
}
if ( this._elMap.text && level) {
level.removeHover(this._elMap.text);
}
}
getViewTipsPoint() {
if (this._elMap.button) {
const button = this._elMap.button.getBoundingRect();
return {
x: button.x + button.width/2,
y: button.y
};
}
}
}

View File

@ -0,0 +1,149 @@
import * as color from 'zrender/src/tool/color';
import * as graphic from '../../../graph/graphic';
import panelType from '../../../constant/panelType';
export default class Popup extends graphic.Group {
constructor(painter, shape) {
super();
this._code = shape.model.code;
this._type = shape.model._type;
this._shape = shape;
this._painter = painter;
this._elMap = {
text: null,
button: null
};
this.create();
this.on('mouseover', this.mouseover, this);
this.on('mouseout', this.mouseout, this);
}
mouseover(e) {
if (this._shape.draw) {
this._elMap.button.attr({cursor: 'pointer'});
this.doActive(this.__zr);
}
}
mouseout(e) {
const map = this._painter.$map;
if (this._shape.draw && !map.isHover(this._code)) {
this._elMap.button.attr({cursor: 'default'});
this.doInactive(this.__zr);
}
}
create() {
const model = this._shape.model;
const style = this._shape.style;
this._elMap.button = new graphic.Rect({
zlevel: model.zlevel,
z: model.z,
shape: {
x: model.point.x-model.width/2,
y: model.point.y-model.height/2,
width: model.width,
height: model.height,
r: [1]
},
style: {
fill: style[panelType.Popup].button.fill,
stroke: style[panelType.Popup].button.stroke,
lineWidth: style[panelType.Popup].button.lineWidth,
shadowColor: '#dfdfdf',
shadowOffsetX: 1,
shadowOffsetY: 1
}
});
this._elMap.text = new graphic.Text({
zlevel: model.zlevel,
z: model.z,
z2: 2,
style: {
x: model.point.x,
y: model.point.y,
fontWeight: style[panelType.Popup].text.fontWeight,
fontFamily: style.fontFamily,
fontSize: model.fontSize,
text: model.text,
textFill: '#000',
textPadding: [4, 4],
textAlign: 'center',
textVerticalAlign: 'middle'
}
});
this.setState(model);
Object.values(this._elMap).forEach(elem => { elem && elem instanceof Array? elem.forEach(el => this.add(el)): this.add(elem); });
}
setShape(model) {
if (this._elMap.button) {
this._elMap.button.setShape({
x: model.point.x-model.width/2,
y: model.point.y-model.height/2
});
}
if (this._elMap.text) {
this._elMap.text.setStyle({
x: model.point.x,
y: model.point.y
});
}
}
setState(model) {}
dragging(e) {
const model = this._shape.model;
model.point.x += e.dx;
model.point.y += e.dy;
this.setShape(model);
}
doActive(zr) {
const style = this._shape.style;
const level = zr||this.__zr;
if (this._elMap.button && level) {
level.addHover(this._elMap.button, {
opacity: style.maskOpacity,
fill: color.lift(style.graphHover2Color, style.liftLevel)
});
}
if (this._elMap.text && level) {
level.addHover(this._elMap.text, {
opacity: style.maskOpacity,
textFill: color.lift(style.textHover2Color, style.liftLevel)
});
}
}
doInactive(zr) {
const level = zr||this.__zr;
if ( this._elMap.button && level) {
level.removeHover(this._elMap.button);
}
if ( this._elMap.text && level) {
level.removeHover(this._elMap.text);
}
}
getViewTipsPoint() {
if (this._elMap.button) {
const button = this._elMap.button.getBoundingRect();
return {
x: button.x + button.width/2,
y: button.y
};
}
}
}

View File

@ -0,0 +1,308 @@
import * as color from 'zrender/src/tool/color';
import * as graphic from '../../../graph/graphic';
import panelType from '../../../constant/panelType';
export default class ProgramControl extends graphic.Group {
constructor(painter, shape) {
super();
this._code = shape.model.code;
this._type = shape.model._type;
this._shape = shape;
this._painter = painter;
this._elMap = {
line: null,
button: null,
blockStart: null,
blockReset: null,
blockStop: null,
start: null,
reset: null,
stop: null
};
this.create();
this.on('mouseover', this.mouseover, this);
this.on('mouseout', this.mouseout, this);
}
mouseover(e) {
const model = this._shape.model;
if (this._shape.draw) {
this._elMap.button.attr({cursor: 'pointer'});
this.doActive(this.__zr);
} else if (model.description) {
this._painter.$tipsHandle.trigger('show', {
x: e.offsetX,
y: e.offsetY,
text: model.description,
target: e.target
});
}
}
mouseout(e) {
const map = this._painter.$map;
if (this._shape.draw && !map.isHover(this._code)) {
this._elMap.button.attr({cursor: 'default'});
this.doInactive(this.__zr);
} else {
this._painter.$tipsHandle.trigger('hide');
}
}
create() {
const model = this._shape.model;
const style = this._shape.style;
this._elMap.line = new graphic.Line({
zlevel: model.zlevel,
z: model.z,
z2: 9,
shape: {
x1: model.point.x+style[panelType.ProgramControl].button.width/2,
y1: model.point.y+style[panelType.ProgramControl].button.height/2,
x2: model.point.x-style[panelType.ProgramControl].button.width/2,
y2: model.point.y-style[panelType.ProgramControl].button.height/2
},
style: {
stroke: style[panelType.ProgramControl].line.stroke,
lineWidth: style[panelType.ProgramControl].line.lineWidth,
lineCap: 'round'
}
});
this._elMap.button = new graphic.Rect({
zlevel: model.zlevel,
z: model.z,
shape: {
x: model.point.x-style[panelType.ProgramControl].button.width/2,
y: model.point.y-style[panelType.ProgramControl].button.height/2,
width: style[panelType.ProgramControl].button.width,
height: style[panelType.ProgramControl].button.height,
r: [1]
},
style: {
fill: style[panelType.ProgramControl].button.fill,
stroke: style[panelType.ProgramControl].button.stroke,
lineWidth: style[panelType.ProgramControl].button.lineWidth
}
});
this._elMap.blockStart = new graphic.Rect({
zlevel: model.zlevel,
z: model.z,
z2: 3,
shape: {
x: model.point.x-style[panelType.ProgramControl].button.width/2,
y: model.point.y-style[panelType.ProgramControl].button.height/2,
width: style[panelType.ProgramControl].button.width/3,
height: style[panelType.ProgramControl].button.height,
r: [1]
},
style: {
fill: style[panelType.ProgramControl].block.fill,
stroke: style[panelType.ProgramControl].block.stroke,
lineWidth: style[panelType.ProgramControl].block.lineWidth
}
});
this._elMap.blockReset = new graphic.Rect({
zlevel: model.zlevel,
z: model.z,
z2: 3,
shape: {
x: model.point.x-style[panelType.ProgramControl].button.width/2+style[panelType.ProgramControl].button.width/3,
y: model.point.y-style[panelType.ProgramControl].button.height/2,
width: style[panelType.ProgramControl].button.width/3,
height: style[panelType.ProgramControl].button.height,
r: [1]
},
style: {
fill: style[panelType.ProgramControl].block.fill,
stroke: style[panelType.ProgramControl].block.stroke,
lineWidth: style[panelType.ProgramControl].block.lineWidth
}
});
this._elMap.blockStop = new graphic.Rect({
zlevel: model.zlevel,
z: model.z,
z2: 3,
shape: {
x: model.point.x-style[panelType.ProgramControl].button.width/2+style[panelType.ProgramControl].button.width/3*2,
y: model.point.y-style[panelType.ProgramControl].button.height/2,
width: style[panelType.ProgramControl].button.width/3,
height: style[panelType.ProgramControl].button.height,
r: [1]
},
style: {
fill: style[panelType.ProgramControl].block.fill,
stroke: style[panelType.ProgramControl].block.stroke,
lineWidth: style[panelType.ProgramControl].block.lineWidth,
r: [1]
}
});
this._elMap.start = new graphic.Svg({
zlevel: model.zlevel,
z: model.z,
z2: 5,
origin: [0, 0],
rotation: 0,
scale: [1, 1],
shape: {
x: model.point.x-style[panelType.ProgramControl].button.width/2 + style[panelType.ProgramControl].button.width/6,
y: model.point.y-style[panelType.ProgramControl].button.height/2,
path: 'M6 12 L-4 6 L-4 18Z'
},
style: {
fill: style[panelType.ProgramControl].indicate.fill
}
});
this._elMap.reset = new graphic.Svg({
zlevel: model.zlevel,
z: model.z,
z2: 5,
origin: [0, 0],
rotation: 0,
scale: [1, 1],
shape: {
x: model.point.x-style[panelType.ProgramControl].button.width/2+style[panelType.ProgramControl].button.width/3 + style[panelType.ProgramControl].button.width/6,
y: model.point.y-style[panelType.ProgramControl].button.height/2,
path: 'M6 6 L6 18 L1 18 L1 6Z M-6 6 L-6 18 L-1 18 L-1 6Z'
},
style: {
fill: style[panelType.ProgramControl].indicate.fill
}
});
this._elMap.stop = new graphic.Svg({
zlevel: model.zlevel,
z: model.z,
z2: 5,
origin: [0, 0],
rotation: 0,
scale: [1, 1],
shape: {
x: model.point.x-style[panelType.ProgramControl].button.width/2+style[panelType.ProgramControl].button.width/3*2 + style[panelType.ProgramControl].button.width/6,
y: model.point.y-style[panelType.ProgramControl].button.height/2,
path: 'M6 6 L6 18 L-6 18 L-6 6Z'
},
style: {
fill: style[panelType.ProgramControl].indicate.fill
}
});
this.setState(model);
Object.values(this._elMap).forEach(elem => { elem && elem instanceof Array? elem.forEach(el => this.add(el)): this.add(elem); });
}
setShape(model) {
const style = this._shape.style;
if (this._elMap.line) {
this._elMap.line.setShape({
x1: model.point.x+style[panelType.ProgramControl].button.width/2,
y1: model.point.y+style[panelType.ProgramControl].button.height/2,
x2: model.point.x-style[panelType.ProgramControl].button.width/2,
y2: model.point.y-style[panelType.ProgramControl].button.height/2
});
}
if (this._elMap.button) {
this._elMap.button.setShape({
x: model.point.x-style[panelType.ProgramControl].button.width/2,
y: model.point.y-style[panelType.ProgramControl].button.height/2
});
}
if (this._elMap.blockStart) {
this._elMap.blockStart.setShape({
x: model.point.x-style[panelType.ProgramControl].button.width/2,
y: model.point.y-style[panelType.ProgramControl].button.height/2,
width: style[panelType.ProgramControl].button.width/3,
height: style[panelType.ProgramControl].button.height
});
}
if (this._elMap.blockReset) {
this._elMap.blockReset.setShape({
x: model.point.x-style[panelType.ProgramControl].button.width/2+style[panelType.ProgramControl].button.width/3,
y: model.point.y-style[panelType.ProgramControl].button.height/2,
width: style[panelType.ProgramControl].button.width/3,
height: style[panelType.ProgramControl].button.height
});
}
if (this._elMap.blockStop) {
this._elMap.blockStop.setShape({
x: model.point.x-style[panelType.ProgramControl].button.width/2+style[panelType.ProgramControl].button.width/3*2,
y: model.point.y-style[panelType.ProgramControl].button.height/2,
width: style[panelType.ProgramControl].button.width/3,
height: style[panelType.ProgramControl].button.height
});
}
if (this._elMap.start) {
this._elMap.start.setShape({
x: model.point.x-style[panelType.ProgramControl].button.width/2 + style[panelType.ProgramControl].button.width/6,
y: model.point.y-style[panelType.ProgramControl].button.height/2
});
}
if (this._elMap.reset) {
this._elMap.reset.setShape({
x: model.point.x-style[panelType.ProgramControl].button.width/2+style[panelType.ProgramControl].button.width/3 + style[panelType.ProgramControl].button.width/6,
y: model.point.y-style[panelType.ProgramControl].button.height/2
});
}
if (this._elMap.stop) {
this._elMap.stop.setShape({
x: model.point.x-style[panelType.ProgramControl].button.width/2+style[panelType.ProgramControl].button.width/3*2 + style[panelType.ProgramControl].button.width/6,
y: model.point.y-style[panelType.ProgramControl].button.height/2
});
}
}
setState(model) {}
dragging(e) {
const model = this._shape.model;
model.point.x += e.dx;
model.point.y += e.dy;
this.setShape(model);
}
doActive(zr) {
const style = this._shape.style;
const level = zr||this.__zr;
if (this._elMap.button && level) {
level.addHover(this._elMap.button, {
opacity: style.maskOpacity,
fill: color.lift(style.graphHover2Color, style.liftLevel),
stroke: color.lift(style.graphHover2Color, style.liftLevel)
});
}
}
doInactive(zr) {
const level = zr||this.__zr;
if ( this._elMap.button && level) {
level.removeHover(this._elMap.button);
}
}
getViewTipsPoint() {
if (this._elMap.button) {
const button = this._elMap.button.getBoundingRect();
return {
x: button.x + button.width/2,
y: button.y
};
}
}
}

View File

@ -0,0 +1,195 @@
import * as color from 'zrender/src/tool/color';
import * as graphic from '../../../graph/graphic';
import panelType from '../../../constant/panelType';
export default class Switching extends graphic.Group {
constructor(painter, shape) {
super();
this._code = shape.model.code;
this._type = shape.model._type;
this._shape = shape;
this._painter = painter;
this._elMap = {
text: null,
button: null
};
this.create();
this.on('mouseover', this.mouseover, this);
this.on('mouseout', this.mouseout, this);
this.on('mousedown', this.mousedown, this);
this.on('mouseup', this.mouseup, this);
}
mousedown(e) {
const model = this._shape.model;
if (model.isReset &&
!this._shape.draw &&
this._elMap.button) {
this._elMap.button.setStyle({
fill: '#FF0000'
});
}
}
mouseup(e) {
const model = this._shape.model;
const style = this._shape.style;
if (model.isReset &&
!this._shape.draw &&
this._elMap.button) {
setTimeout(() => {
this._elMap.button.setStyle({
fill: style[panelType.Switching].button.fill
});
}, 200);
}
}
mouseover(e) {
if (this._shape.draw) {
this._elMap.button.attr({cursor: 'pointer'});
this.doActive(this.__zr);
}
}
mouseout(e) {
const map = this._painter.$map;
if (this._shape.draw && !map.isHover(this._code)) {
this._elMap.button.attr({cursor: 'default'});
this.doInactive(this.__zr);
}
}
create() {
const model = this._shape.model;
const style = this._shape.style;
this._elMap.button = new graphic.Rect({
zlevel: model.zlevel,
z: model.z,
shape: {
x: model.point.x-model.width/2,
y: model.point.y-model.height/2,
width: model.width,
height: model.height,
r: [1]
},
style: {
fill: style[panelType.Switching].button.fill,
stroke: style[panelType.Switching].button.stroke,
lineWidth: style[panelType.Switching].button.lineWidth,
shadowColor: '#dfdfdf',
shadowOffsetX: 1,
shadowOffsetY: 1
}
});
this._elMap.text = new graphic.Text({
zlevel: model.zlevel,
z: model.z,
z2: 2,
style: {
x: model.point.x,
y: model.point.y,
fontWeight: style[panelType.Switching].text.fontWeight,
fontFamily: style.fontFamily,
fontSize: model.fontSize,
text: model.putInText,
textFill: '#000',
textPadding: [4, 4],
textAlign: 'center',
textVerticalAlign: 'middle'
}
});
this.setState(model);
Object.values(this._elMap).forEach(elem => { elem && elem instanceof Array? elem.forEach(el => this.add(el)): this.add(elem); });
}
setShape(model) {
if (this._elMap.button) {
this._elMap.button.setShape({
x: model.point.x-model.width/2,
y: model.point.y-model.height/2
});
}
if (this._elMap.text) {
this._elMap.text.setStyle({
x: model.point.x,
y: model.point.y
});
}
}
setState(model) {
const entity = model.entity||{};
const data = entity.data ||{};
if (!model.isReset &&
!this._shape.draw &&
entity.data) {
if (this._elMap.button) {
this._elMap.button.setStyle({
fill: data.status? '#FF0000' : '#3CB371'
});
}
if (this._elMap.text) {
this._elMap.text.setStyle({
text: data.status? model.putInText: model.cutOffText
});
}
}
}
dragging(e) {
const model = this._shape.model;
model.point.x += e.dx;
model.point.y += e.dy;
this.setShape(model);
}
doActive(zr) {
const style = this._shape.style;
const level = zr||this.__zr;
if (this._elMap.button && level) {
level.addHover(this._elMap.button, {
opacity: style.maskOpacity,
fill: color.lift(style.graphHover2Color, style.liftLevel)
});
}
if (this._elMap.text && level) {
level.addHover(this._elMap.text, {
opacity: style.maskOpacity,
textFill: color.lift(style.textHover2Color, style.liftLevel)
});
}
}
doInactive(zr) {
const level = zr||this.__zr;
if ( this._elMap.button && level) {
level.removeHover(this._elMap.button);
}
if ( this._elMap.text && level) {
level.removeHover(this._elMap.text);
}
}
getViewTipsPoint() {
if (this._elMap.button) {
const button = this._elMap.button.getBoundingRect();
return {
x: button.x + button.width/2,
y: button.y
};
}
}
}

View File

@ -0,0 +1,12 @@
export {default as Table_Template} from './table-template.js';
export {default as Table_Water_Device_Screen} from './table-water-device-screen.js';
export {default as Table_Water_Elements} from './table-water-elements.js';
export {default as Table_Supercritical_Furnace_Sampling} from './table-supercritical-furnace-sampling.js';
export const templateList = [
{value: 'Table-Template', label: '模板示例'},
{value: 'Table-Water-Device-Screen', label: '水汽取样装置-设备表'},
{value: 'Table-Water-Elements', label: '水汽取样装置-元素表'},
{value: 'Table-Supercritical-Furnace-Sampling', label: '超临界直流炉取样点-设备表'}
]
;

View File

@ -0,0 +1,176 @@
const textStyle = {
fontSize: 14,
fontWeight: 'bold',
fontFamily: 'consolas',
textFill: '#0000FF',
textAlign: 'center',
textVerticalAlign: 'middle'
};
const orderStyle = {
fontSize: 14,
fontWeight: 'bold',
fontFamily: 'consolas',
textFill: '#000000',
textAlign: 'center',
textVerticalAlign: 'middle'
};
export default {
z2: 1,
shape: {
dataSource: [
[
{
type: 'text',
text: '序号',
...textStyle
},
{
type: 'order',
text: '1',
...orderStyle
},
{
type: 'order',
text: '2',
...orderStyle
},
{
type: 'order',
text: '3',
...orderStyle
},
{
type: 'order',
text: '4',
...orderStyle
},
{
type: 'order',
text: '5',
...orderStyle
},
{
type: 'order',
text: '6',
...orderStyle
},
{
type: 'order',
text: '7',
...orderStyle
},
{
type: 'order',
text: '8',
...orderStyle
},
{
type: 'order',
text: '9',
...orderStyle
},
{
type: 'order',
text: '10',
...orderStyle
},
{
type: 'order',
text: '11',
...orderStyle
},
{
type: 'order',
text: '12',
...orderStyle
},
{
type: 'order',
text: '13',
...orderStyle
}
],
[
{
type: 'text',
text: '名称',
...textStyle
},
{
type: 'text',
text: '除氧器出口',
...textStyle
},
{
type: 'text',
text: '除氧器入口',
...textStyle
},
{
type: 'text',
text: '省煤器入口',
...textStyle
},
{
type: 'text',
text: '启动分离器排水',
...textStyle
},
{
type: 'text',
text: '顶棚入口',
...textStyle
},
{
type: 'text',
text: '饱和蒸汽',
...textStyle
},
{
type: 'text',
text: '过热蒸汽',
...textStyle
},
{
type: 'text',
text: '再热蒸汽出口',
...textStyle
},
{
type: 'text',
text: '凝结水泵出口',
...textStyle
},
{
type: 'text',
text: '高压加热器疏水',
...textStyle
},
{
type: 'text',
text: '低压加热器疏水',
...textStyle
},
{
type: 'text',
text: '加氨、加氧点后',
...textStyle
},
{
type: 'text',
text: '凝补水箱入口',
...textStyle
}
]
],
wList: [60, ...new Array(13).fill(110)],
hList: new Array(2).fill(32)
},
style: {
lineWidth: 1,
backgroundColor: '#ffffcc',
stroke: '#000000'
}
};

View File

@ -0,0 +1,58 @@
export default {
z2: 1,
shape: {
dataSource: [
[
{
type: 'order',
fontSize: 14,
fontWeight: 'bold',
fontFamily: 'consolas',
text: '1',
textFill: '#000',
textAlign: 'center',
textVerticalAlign: 'middle'
}, {
type: 'button',
fontSize: 16,
fontWeight: 'normal',
fontFamily: 'consolas',
text: 'button',
textFill: '#000',
textAlign: 'center',
textVerticalAlign: 'middle'
}
],
[
{
type: 'element',
fontSize: 16,
fontWeight: 'bold',
fontFamily: 'consolas',
text: 'element',
textFill: '#000',
textAlign: 'center',
textVerticalAlign: 'middle'
},
{
type: 'text',
name: '3',
fontSize: 22,
fontWeight: 'bold',
fontFamily: 'consolas',
text: 'text',
textFill: '#000',
textAlign: 'center',
textVerticalAlign: 'middle'
}
]
],
wList: [180, 180, 180],
hList: [36, 36, 36]
},
style: {
lineWidth: 1,
backgroundColor: '#ffffcc',
stroke: '#000000'
}
};

View File

@ -0,0 +1,176 @@
const textStyle = {
fontSize: 14,
fontWeight: 'bold',
fontFamily: 'consolas',
textFill: '#0000FF',
textAlign: 'center',
textVerticalAlign: 'middle'
};
const orderStyle = {
fontSize: 14,
fontWeight: 'bold',
fontFamily: 'consolas',
textFill: '#000000',
textAlign: 'center',
textVerticalAlign: 'middle'
};
export default {
z2: 1,
shape: {
dataSource: [
[
{
type: 'text',
text: '序号',
...textStyle
},
{
type: 'order',
text: '1',
...orderStyle
},
{
type: 'order',
text: '2',
...orderStyle
},
{
type: 'order',
text: '3',
...orderStyle
},
{
type: 'order',
text: '4',
...orderStyle
},
{
type: 'order',
text: '5',
...orderStyle
},
{
type: 'order',
text: '6',
...orderStyle
},
{
type: 'order',
text: '7',
...orderStyle
},
{
type: 'order',
text: '8',
...orderStyle
},
{
type: 'order',
text: '9',
...orderStyle
},
{
type: 'order',
text: '10',
...orderStyle
},
{
type: 'order',
text: '11',
...orderStyle
},
{
type: 'order',
text: '12',
...orderStyle
},
{
type: 'order',
text: '13',
...orderStyle
}
],
[
{
type: 'text',
text: '名称',
...textStyle
},
{
type: 'text',
text: '凝结水泵出口',
...textStyle
},
{
type: 'text',
text: '除氧器入口',
...textStyle
},
{
type: 'text',
text: '除氧器出口',
...textStyle
},
{
type: 'text',
text: '省煤器进口',
...textStyle
},
{
type: 'text',
text: '主蒸汽',
...textStyle
},
{
type: 'text',
text: '饱和蒸汽',
...textStyle
},
{
type: 'text',
text: '炉水',
...textStyle
},
{
type: 'text',
text: '再热气入口',
...textStyle
},
{
type: 'text',
text: '再热气出口',
...textStyle
},
{
type: 'text',
text: '低加热出口',
...textStyle
},
{
type: 'text',
text: '精处理',
...textStyle
},
{
type: 'text',
text: '补给水箱入口',
...textStyle
},
{
type: 'text',
text: '补给水泵出口',
...textStyle
}
]
],
wList: [60, ...new Array(13).fill(110)],
hList: new Array(2).fill(32)
},
style: {
lineWidth: 1,
backgroundColor: '#ffffcc',
stroke: '#000000'
}
};

View File

@ -0,0 +1,129 @@
const textStyle = {
fontSize: 14,
fontWeight: 'bold',
fontFamily: 'consolas',
textFill: '#0000FF',
textAlign: 'center',
textVerticalAlign: 'middle'
};
const richStyle = {
fontSize: 14,
fontWeight: 'bold',
fontFamily: 'consolas',
textFill: '#0000FF',
textAlign: 'center',
rich: {
sup: {
fontSize: 6,
textVerticalAlign: 'top'
},
sub: {
fontSize: 6,
textVerticalAlign: 'bottom'
}
}
};
export default {
z2: 1,
shape: {
dataSource: [
[
{
type: 'text',
text: 'PH',
...richStyle
},
{
type: 'text',
text: 'PH分析仪',
...textStyle
},
{
type: 'text',
text: 'N{sub|2}H{sub|4}',
...richStyle
},
{
type: 'text',
text: '联氨分析仪',
...textStyle
}
],
[
{
type: 'text',
text: 'CC',
...richStyle
},
{
type: 'text',
text: '阳电导率分析仪',
...textStyle
},
{
type: 'text',
text: 'SO{sub|2}',
...richStyle
},
{
type: 'text',
text: '硅酸根分析仪',
...textStyle
}
],
[
{
type: 'text',
text: 'SC',
...richStyle
},
{
type: 'text',
text: '比电导率分析仪',
...textStyle
},
{
type: 'text',
text: 'PO{sub|4}{sup|3-}',
...richStyle
},
{
type: 'text',
text: '磷酸根分析仪',
...textStyle
}
],
[
{
type: 'text',
text: 'O{sub|2}',
...richStyle
},
{
type: 'text',
text: '溶解氧分析仪',
...textStyle
},
{
type: 'text',
text: 'NA',
...richStyle
},
{
type: 'text',
text: '钠离子分析仪',
...textStyle
}
]
],
wList: [60, 140, 60, 140],
hList: [32, 32, 32, 32]
},
style: {
lineWidth: 1,
backgroundColor: '#ffffcc',
stroke: '#000000'
}
};

View File

@ -0,0 +1,144 @@
import * as graphic from '../../../graph/graphic';
import panelType from '../../../constant/panelType';
export default class Table extends graphic.Group {
constructor(painter, shape) {
super();
this._code = shape.model.code;
this._type = shape.model._type;
this._shape = shape;
this._painter = painter;
this._elMap = {
table: null
};
this.create();
this.on('mouseover', this.mouseover, this);
this.on('mouseout', this.mouseout, this);
}
mouseover(e) {
if (this._shape.draw) {
this.doActive(this.__zr);
}
}
mouseout(e) {
const map = this._painter.$map;
if (this._shape.draw && !map.isHover(this._code)) {
this.doInactive(this.__zr);
}
}
create() {
const draw = this._shape.draw;
const model = this._shape.model;
const style = this._shape.style;
this._elMap.header = new graphic.Rect({
zlevel: model.zlevel,
z: model.z,
z2: -1,
cursor: draw? 'pointer': 'default',
shape: {
x: model.point.x,
y: model.point.y,
width: model.width,
height: style[panelType.Table].header.height
},
style: {
stroke: model.lineColor,
lineWidth: model.lineWidth,
fill: model.headerBg
}
});
this._elMap.body = new graphic.Rect({
zlevel: model.zlevel,
z: model.z,
z2: -1,
silent: true,
shape: {
x: model.point.x,
y: model.point.y+style[panelType.Table].header.height,
width: model.width,
height: model.height
},
style: {
stroke: model.lineColor,
lineWidth: model.lineWidth,
fill: model.bodyBg
}
});
this._elMap.title = new graphic.Text({
zlevel: model.zlevel,
z: model.z,
z2: 0,
cursor: draw? 'pointer': 'default',
style: {
x: model.point.x+model.width/2,
y: model.point.y+style[panelType.Table].header.height/2,
fontWeight: style[panelType.Table].header.fontWeight,
fontSize: style[panelType.Table].header.fontSize,
fontFamily: style.fontFamily,
text: model.title||'标题',
textAlign: 'center',
textVerticalAlign: 'middle'
}
});
Object.values(this._elMap).forEach(elem => { elem && elem instanceof Array? elem.forEach(el => this.add(el)): this.add(elem); });
}
setShape(model) {
const style = this._shape.style;
if (this._elMap.header) {
this._elMap.header.setShape({
x: model.point.x,
y: model.point.y
});
}
if (this._elMap.body) {
this._elMap.body.setShape({
x: model.point.x,
y: model.point.y+style[panelType.Table].header.height
});
}
if (this._elMap.title) {
this._elMap.title.setStyle({
x: model.point.x+model.width/2,
y: model.point.y+style[panelType.Table].header.height/2
});
}
}
setState(model, e) {
}
dragging(e) {
const model = this._shape.model;
model.point.x += e.dx;
model.point.y += e.dy;
this.setShape(model);
}
doActive(zr) {
}
doInactive(zr) {
}
getViewTipsPoint() {}
}

View File

@ -0,0 +1,111 @@
import store from '@/store';
import * as color from 'zrender/src/tool/color';
import * as graphic from '../../../graph/graphic';
import * as View from './constant/export.js';
import { transformed } from '../../../utils/transform';
export default class Table extends graphic.Group {
constructor(painter, shape) {
super();
this._code = shape.model.code;
this._type = shape.model._type;
this._shape = shape;
this._painter = painter;
this._elMap = {
table: null
};
this.create();
this.on('mouseover', this.mouseover, this);
this.on('mouseout', this.mouseout, this);
}
mouseover(e) {
if (this._shape.draw) {
this.doActive(this.__zr);
}
}
mouseout(e) {
const map = this._painter.$map;
if (this._shape.draw && !map.isHover(this._code)) {
this.doInactive(this.__zr);
}
}
create() {
const draw = this._shape.draw;
const mapType = store.state.map.mapType;
const model = this._shape.model;
const template = (model.template || 'Table-Template').replace(/-/g, '_');
const option = View[template];
if (model.sceneTypes && model.sceneTypes.includes(mapType)) {
this._elMap.table = new graphic.Table({
zlevel: model.zlevel || option.zlevel,
z: model.z || option.z,
z2: model.z2 || option.z2,
cursor: draw? 'pointer': 'default',
shape: {
point: model.point,
...option.shape
},
style: option.style
});
transformed(this._elMap.table, {
scale: [model.scale, model.scale],
rotation: model.rotation || 0
});
}
Object.values(this._elMap).forEach(elem => { elem && elem instanceof Array? elem.forEach(el => this.add(el)): this.add(elem); });
}
setShape(model) {
}
setState(model, e) {
}
dragging(e) {
const model = this._shape.model;
const scale = model.scale;
model.point.x += e.dx / scale;
model.point.y += e.dy / scale;
if (this._elMap.table) {
this._elMap.table.dragging({dx: e.dx/scale, dy: e.dy/scale});
}
this.setShape(model);
}
doActive(zr) {
const style = this._shape.style;
const table = this._elMap.table;
const level = zr||this.__zr;
if (table && table._elMap.bg && level) {
level.addHover(table._elMap.bg, {
opacity: style.maskOpacity,
fill: color.lift(style.maskHover2Color, style.liftLevel)
});
}
}
doInactive(zr) {
const table = this._elMap.table;
const level = zr||this.__zr;
if (table && table._elMap.bg && level) {
level.removeHover(table._elMap.bg);
}
}
getShapeTipsPoint(step) {}
}

View File

@ -0,0 +1,136 @@
import * as color from 'zrender/src/tool/color';
import * as graphic from '../../../graph/graphic';
import store from '@/store';
export default class Text2 extends graphic.Group {
constructor(painter, shape) {
super();
this._code = shape.model.code;
this._type = shape.model._type;
this._shape = shape;
this._painter = painter;
this._rotation = null;
this._origin = null;
this._elMap = {
text: null
};
this.create();
this.on('mouseover', this.mouseover, this);
this.on('mouseout', this.mouseout, this);
}
mouseover(e) {
if (this._shape.draw) {
this.doActive(this.__zr);
}
}
mouseout(e) {
const map = this._painter.$map;
if (this._shape.draw && !map.isHover(this._code)) {
this.doInactive(this.__zr);
}
}
create() {
const draw = this._shape.draw;
const mapType = store.state.map.mapType;
const model = this._shape.model;
const backGroundColor = this.getTextBgColor(model);
const textStyle = this.getTextStyle(model);
this._rotation = -Math.PI / 180 * Number(model.rotate||0);
this._origin = [model.point.x, model.point.y];
if (model.sceneTypes && model.sceneTypes.includes(mapType)) {
this._elMap.text = new graphic.Text({
zlevel: model.zlevel,
z: model.z,
origin: this._origin,
rotation: this._rotation,
silent: !draw,
style: {
x: model.point.x,
y: model.point.y,
fontWeight: 'normal',
textBackgroundColor: backGroundColor,
fontSize: model.fontSize,
fontFamily: model.font,
text: textStyle.textValue || textStyle.value || '',
textLineHeight: model.fontSize+4,
textFill: model.fontColor,
textPadding: [4, 4],
textAlign: textStyle.textAlign,
textVerticalAlign: 'middle'
}
});
}
this.setState(model);
Object.values(this._elMap).forEach(elem => { elem && elem instanceof Array? elem.forEach(el => this.add(el)): this.add(elem); });
}
getTextStyle(model) {
const pattern = /\{<(?<textAlign>\w+)>\}\{<(?<textVerticalAlign>\w+)>\}(?<textValue>(.|\n)*)|(?<value>(.|\n)*)/;
const groups = (pattern.exec(model.name)||{}).groups||{};
return groups;
}
getTextBgColor(model) {
const pattern = /\{<(?<active>\w+)>\}(?<string>(.|\n)*)/;
const groups = (pattern.exec(model.backGroundColor)||{}).groups||{};
return groups.active == 'image'
? { image: `${process.env.VUE_APP_BASE_RESOURCE_URL}${groups.string}` }
: groups.active == 'color'
? groups.string
: model.backGroundColor;
}
setShape(model) {
if (this._elMap.text) {
this._origin = [model.point.x, model.point.y];
this._elMap.text.attr('origin', this._origin);
this._elMap.text.setStyle({
x: model.point.x,
y: model.point.y
});
}
}
setState(model) {
}
dragging(e) {
const model = this._shape.model;
model.point.x += e.dx;
model.point.y += e.dy;
this.setShape(model);
}
doActive(zr) {
const style = this._shape.style;
const level = zr||this.__zr;
if (this._elMap.text && level) {
level.addHover(this._elMap.text, {
opacity: style.maskOpacity,
textBackgroundColor: color.lift(style.textHover2Color, style.liftLevel)
});
}
}
doInactive(zr) {
const level = zr||this.__zr;
if (this._elMap.text && level) {
level.removeHover(this._elMap.text);
}
}
getViewTipsPoint() {}
}

View File

@ -0,0 +1,172 @@
import RadialGradient from 'zrender/src/graphic/RadialGradient';
import * as color from 'zrender/src/tool/color';
import * as graphic from '../../../graph/graphic';
import panelType from '../../../constant/panelType';
import ConstConfig from '@/scripts/ConstConfig';
export default class Warning extends graphic.Group {
constructor(painter, shape, state) {
super();
this._code = shape.model.code;
this._type = shape.model._type;
this._shape = shape;
this._state = state;
this._painter = painter;
this._state = state;
this._elMap = {
circle: null
};
this.create();
this.on('mouseover', this.mouseover, this);
this.on('mouseout', this.mouseout, this);
}
mouseover(e) {
const model = this._shape.model;
if (this._shape.draw) {
this.doActive(this.__zr);
} else if (model.description) {
this._painter.$tipsHandle.trigger('show', {
x: e.offsetX,
y: e.offsetY,
text: model.description,
target: e.target
});
}
}
mouseout(e) {
const map = this._painter.$map;
if (this._shape.draw && !map.isHover(this._code)) {
this.doInactive(this.__zr);
} else {
this._painter.$tipsHandle.trigger('hide');
}
}
create() {
const model = this._shape.model;
const style = this._shape.style;
const distance = 8;
this._elMap.circle = new graphic.Circle({
zlevel: model.zlevel,
z: model.z,
shape: {
cx: model.point.x,
cy: model.point.y,
r: model.radius||10
},
style: {
lineWidth: style[panelType.Warning].circle.lineWidth,
stroke: style[panelType.Warning].circle.stroke,
fill: new RadialGradient(0.5, 0.5, 0.5, [
{offset: 0, color: '#eeeeee'},
{offset: 1, color: '#666666'}
])
}
});
const signX = ConstConfig.ConstMap.LocationMode.Left.value == model.showPosition
? -1
: ConstConfig.ConstMap.LocationMode.Right.value == model.showPosition
? 1
: 0;
const signY = ConstConfig.ConstMap.LocationMode.Top.value == model.showPosition
? -1
: ConstConfig.ConstMap.LocationMode.Bottom.value == model.showPosition
? 1
: 0;
this._elMap.text = new graphic.Text({
zlevel: model.zlevel,
z: model.z,
style: {
x: model.point.x + signX*(model.radius+distance),
y: model.point.y + signY*(model.radius+distance*2),
fontFamily: style.fontFamily,
fontWeight: style[panelType.Warning].text.fontWeight,
fontSize: style[panelType.Warning].text.fontSize,
textFill: style[panelType.Warning].text.textFill,
textVerticalAlign: 'middle',
text: model.description,
textAlign: ConstConfig.ConstMap.LocationMode.Left.value == model.showPosition
? 'right'
: ConstConfig.ConstMap.LocationMode.Right.value == model.showPosition
? 'left'
: 'center'
}
});
model.textShow? this._elMap.text.show(): this._elMap.text.hide();
this.setState(model);
Object.values(this._elMap).forEach(elem => { elem && elem instanceof Array? elem.forEach(el => this.add(el)): this.add(elem); });
}
setShape(model) {
if (this._elMap.circle) {
this._elMap.circle.setShape({
cx: model.point.x,
cy: model.point.y
});
}
if (this._elMap.text) {
const distance = 8;
const signX = ConstConfig.ConstMap.LocationMode.Left.value == model.showPosition
? -1
: ConstConfig.ConstMap.LocationMode.Right.value == model.showPosition
? 1
: 0;
const signY = ConstConfig.ConstMap.LocationMode.Top.value == model.showPosition
? -1
: ConstConfig.ConstMap.LocationMode.Bottom.value == model.showPosition
? 1
: 0;
this._elMap.text.setStyle({
x: model.point.x + signX*(model.radius+distance),
y: model.point.y + signY*(model.radius+distance*2)
});
}
}
setState(model) {
}
dragging(e) {
const model = this._shape.model;
model.point.x += e.dx;
model.point.y += e.dy;
this.setShape(model);
}
doActive(zr) {
const style = this._shape.style;
const level = zr||this.__zr;
if (this._elMap.circle && level) {
level.addHover(this._elMap.circle, {
opacity: style.maskOpacity,
fill: color.lift(style.graphHover2Color, style.liftLevel)
});
}
}
doInactive(zr) {
const level = zr||this.__zr;
if (this._elMap.circle &&level) {
level.removeHover(this._elMap.circle);
}
}
getViewTipsPoint() {
const model = this._shape.model;
return {
x: model.point.x,
y: model.point.y
};
}
}

View File

@ -0,0 +1,31 @@
import graphType from '../../constant/graphType';
import Text2 from './Text/index';
import Table from './Table/index';
import Table1 from './Table/tableIndex';
import LinePipe from './LinePipe/index';
import Resource from './Resource/index';
import Measure from './Measure/index';
import Warning from './Warning/index';
import Switching from './Switching/index';
import Popup from './Popup/index';
import ProgramControl from './ProgramControl/index';
import Pid from './Pid/index';
/** 图库*/
const mapShape = {};
mapShape[graphType.Text] = Text2;
mapShape[graphType.Table] = Table;
mapShape[graphType.Table1] = Table1;
mapShape[graphType.LinePipe] = LinePipe;
mapShape[graphType.Resource] = Resource;
mapShape[graphType.Measure] = Measure;
mapShape[graphType.Warning] = Warning;
mapShape[graphType.Switching] = Switching;
mapShape[graphType.Popup] = Popup;
mapShape[graphType.ProgramControl] = ProgramControl;
mapShape[graphType.Pid] = Pid;
export default mapShape;

View File

@ -0,0 +1,17 @@
import graphMapShape from './graph';
import panelMapShape from './panel';
export default {
__Shape: {
...graphMapShape,
...panelMapShape,
...resourceMapShape
},
getBuilder(type) {
const ShapeClazz = this.__Shape[type];
return (...args) => {
return ShapeClazz? new ShapeClazz(...args) : null;
};
}
};

View File

@ -0,0 +1,312 @@
import * as color from 'zrender/src/tool/color';
import * as graphic from '../../../graph/graphic';
import * as utils from '../../../utils/utils';
import panelType from '../../../constant/panelType';
import ConstSelect from '@/scripts/ConstConfig';
export default class LinePipe extends graphic.Group {
constructor(painter, shape, state) {
super();
this._code = shape.model.code;
this._type = shape.model._type;
this._shape = shape;
this._painter = painter;
this._state = state;
this._elMap = {
lines: [],
line: null,
flow: null,
lArrow: null,
rArrow: null
};
this.create();
this.on('mouseover', this.mouseover, this);
this.on('mouseout', this.mouseout, this);
}
mouseover(e) {
if (this._shape.draw) {
this.doActive(this.__zr);
}
}
mouseout(e) {
const map = this._painter.$map;
if (this._shape.draw && !map.isHover(this._code)) {
this.doInactive(this.__zr);
}
}
create() {
const model = this._shape.model;
const style = this._shape.style;
const isVisible = this._state.isDraw ? true : model.visible;
if (isVisible) {
if (model.points.length >= 2) {
this._elMap.line = new graphic.Polyline({
zlevel: model.zlevel,
z: model.z,
z2: (model.layer || 0),
shape: {
points: model.points.map(elem => { return [elem.x, elem.y]; }),
smooth: model.smooth / 10
},
style: {
lineWidth: model.width||style[panelType.LinePipe].line.lineWidth,
stroke: model.color
}
});
// 文字和状态
if (!this._shape.draw) {
this._elMap.flow = new graphic.Polyline({
zlevel: model.zlevel,
z: model.z,
z2: (model.layer || 0)+1,
silent: true,
shape: {
points: model.points.map(elem => { return [elem.x, elem.y]; }),
smooth: model.smooth / 10
},
style: {
lineDash: [8, 8],
lineWidth: model.width
}
});
this._elMap.flow.hide();
}
if ((ConstSelect.ConstMap.LSvgs[model.leftArrow]||{}).path) {
const rotation = -Math.atan2(
model.points[1].y-model.points[0].y,
model.points[1].x-model.points[0].x
);
const path = ConstSelect.ConstMap.LSvgs[model.leftArrow].path;
this._elMap.lArrow = new graphic.Svg({
zlevel: model.zlevel,
z: model.z,
z2: (model.layer || 0),
origin: [0, 0],
rotation,
shape: {
x: model.points[0].x,
y: model.points[0].y,
path
},
style: {
lineWidth: style[panelType.LinePipe].arrow.lineWidth,
stroke: path.includes('stroke')? model.color: 'transparent ',
fill: path.includes('fill')? model.color: 'transparent '
}
});
}
if ((ConstSelect.ConstMap.RSvgs[model.rightArrow]||{}).path) {
const len = model.points.length-1;
const rotation = -Math.atan2(
model.points[len].y-model.points[len-1].y,
model.points[len].x-model.points[len-1].x
);
const path = ConstSelect.ConstMap.RSvgs[model.rightArrow].path;
this._elMap.rArrow = new graphic.Svg({
zlevel: model.zlevel,
z: model.z,
z2: (model.layer || 0),
origin: [0, 0],
rotation,
shape: {
x: model.points[len].x,
y: model.points[len].y,
path
},
style: {
lineWidth: style[panelType.LinePipe].arrow.lineWidth,
stroke: path.includes('stroke')? model.color: 'transparent ',
fill: path.includes('fill')? model.color: 'transparent '
}
});
}
this._elMap.line.setStyle('lineDash', {
'Solid': null, // 实线
'Dotted': [12, 6], // 虚线
'Point': [4, 4], // 点线
'DotPointA': [12, 4, 4, 4], // 一类虚点线
'DotPointB': [12, 4, 4, 4, 4, 4] // 二类虚点线
}[model.type]);
}
}
this.setState(model);
Object.values(this._elMap).forEach(elem => { elem && elem instanceof Array? elem.forEach(el => this.add(el)): this.add(elem); });
}
setShape(model) {
if (this._elMap.lines && this._elMap.lines.length) {
this._elMap.lines.forEach((line, index) => {
utils.lineProxy(line, model.points[index], model.points[index+1]);
});
}
if (this._elMap.line) {
this._elMap.line.setShape({
points: model.points.map(elem => { return [elem.x, elem.y]; })
});
}
if (this._elMap.flow) {
this._elMap.flow.setShape({
points: model.points.map(elem => { return [elem.x, elem.y]; })
});
}
if (this._elMap.lArrow) {
const rotation = -Math.atan2(
model.points[1].y-model.points[0].y,
model.points[1].x-model.points[0].x
);
this._elMap.lArrow.attr('rotation', rotation);
this._elMap.lArrow.setShape({
x: model.points[0].x,
y: model.points[0].y
});
}
if (this._elMap.rArrow) {
const len = model.points.length-1;
const rotation = -Math.atan2(
model.points[len].y-model.points[len-1].y,
model.points[len].x-model.points[len-1].x
);
this._elMap.rArrow.attr('rotation', rotation);
this._elMap.rArrow.setShape({
x: model.points[len].x,
y: model.points[len].y
});
}
}
setState(model) {
const data = model.entity.data;
const stroke = model.color;
if (data && this._elMap.flow) {
if (data.filled) {
this._elMap.flow.show();
switch (data.from) {
case 'A': this.setFlowRun(data, true); break;
case 'B': this.setFlowRun(data, false); break;
default: this.setFlowStop(); break;
}
if (data.filler) {
this._elMap.flow.setStyle({stroke});
this._elMap.line.hide();
}
} else {
this._elMap.flow.hide();
this._elMap.line.show();
}
}
}
dragging(e) {
const model = this._shape.model;
model.points.map(elem => {
elem.x += e.dx;
elem.y += e.dy;
});
this.setShape(model);
}
setFlowRun(data, clockwise) {
const offsetMap = clockwise ? [32, 16, 0] : [0, 16, 32];
const flowSpeed = Math.ceil(data.speed);
if (this._elMap.flow) {
this._elMap.flow.stopAnimation();
if (flowSpeed > 0) {
this._elMap.flow.animate('style', true)
.when(0, { lineDashOffset: offsetMap[0] * flowSpeed })
.when(1000, { lineDashOffset: offsetMap[1] * flowSpeed })
.when(2000, { lineDashOffset: offsetMap[2] * flowSpeed })
.start();
}
}
}
setFlowStop() {
if (this._elMap.flow) {
this._elMap.flow.stopAnimation();
}
}
setFlowClear() {
if (this._elMap.flow) {
this.remove(this._elMap.flow);
}
}
doActive(zr) {
if (zr||this.__zr) {
const style = this._shape.style;
const level = zr||this.__zr;
if (this._elMap.line) {
level.addHover(this._elMap.line, {
stroke: color.lift(style.pipeHover2Color, style.liftLevel),
opacity: 0.8
});
}
this._elMap.lines.forEach(elem => {
if (elem) {
level.addHover(elem, {
stroke: color.lift(style.pipeHover2Color, style.liftLevel),
opacity: 0.8
});
}
});
[this._elMap.lArrow, this._elMap.rArrow].forEach(el =>{
if (el) {
level.addHover(el, {
stroke: el.shape.path.includes('stroke')
? color.lift(style.pipeHover2Color, style.liftLevel)
: 'transparent',
fill: el.shape.path.includes('fill')
? color.lift(style.pipeHover2Color, style.liftLevel)
: 'transparent'
});
}
});
}
}
doInactive(zr) {
if (zr||this.__zr) {
const level = zr||this.__zr;
[this._elMap.line,
...this._elMap.lines,
this._elMap.lText,
this._elMap.rText,
this._elMap.lArrow,
this._elMap.rArrow
].forEach(elem => {
if (elem) {
level.removeHover(elem);
}
});
}
}
getViewTipsPoint() {}
}

View File

@ -0,0 +1,144 @@
import * as color from 'zrender/src/tool/color';
import * as graphic from '../../../graph/graphic';
// import panelType from '../../../constant/panelType';
export default class Measure extends graphic.Group {
constructor(painter, shape, state) {
super();
this._code = shape.model.code;
this._type = shape.model._type;
this._shape = shape;
this._state = state;
this._painter = painter;
this._state = state;
this._elMap = {
text: null
};
this.create();
this.on('mouseover', this.mouseover, this);
this.on('mouseout', this.mouseout, this);
}
mouseover(e) {
const model = this._shape.model;
if (this._shape.draw) {
this.doActive(this.__zr);
} else if (model.description) {
this._painter.$tipsHandle.trigger('show', {
x: e.offsetX,
y: e.offsetY,
text: model.description,
target: e.target
});
}
}
mouseout(e) {
const map = this._painter.$map;
if (this._shape.draw &&!map.isHover(this._code)) {
this.doInactive(this.__zr);
} else {
this._painter.$tipsHandle.trigger('hide');
}
}
create() {
const model = this._shape.model;
this._elMap.text = new graphic.Text({
zlevel: model.zlevel,
z: model.z,
style: {
x: model.point.x,
y: model.point.y,
fontFamily: 'Times New Roman',
fontWeight: 'normal',
fontSize: model.size,
textVerticalAlign: 'middle',
textBackgroundColor: 'transparent',
text: this.format('--', model.unit),
textFill: model.color||'#fff',
textAlign: 'center',
textPadding: [3, 3, 1, 3],
rich: {
txt: {
fontSize: model.size,
textVerticalAlign: 'middle',
textFill: model.color||'#fff'
},
sup: {
fontSize: parseInt(model.size/3),
textVerticalAlign: 'top'
},
sub: {
fontSize: parseInt(model.size/3),
textVerticalAlign: 'bottom'
}
}
}
});
this.setState(model);
Object.values(this._elMap).forEach(elem => { elem && elem instanceof Array? elem.forEach(el => this.add(el)): this.add(elem); });
}
setShape(model) {
if (this._elMap.text) {
this._elMap.text.setStyle({
x: model.point.x,
y: model.point.y
});
}
}
setState(model) {
const data = model.entity.data ||{};
const decimalPlace = model.decimalPlace||0;
if (this._elMap.text && data) {
const value = data.value == undefined? '--' : Number(data.value||0).toFixed(decimalPlace);
this._elMap.text.setStyle({text: this.format(value, model.unit) });
}
}
format(value, unit) {
return `{txt|${value}} ${unit}`;
}
dragging(e) {
const model = this._shape.model;
model.point.x += e.dx;
model.point.y += e.dy;
this.setShape(model);
}
doActive(zr) {
const style = this._shape.style;
const level = zr||this.__zr;
if (this._elMap.text && level) {
level.addHover(this._elMap.text, {
opacity: style.maskOpacity,
textBackgroundColor: color.lift(style.measureHover2Color, style.liftLevel)
});
}
}
doInactive(zr) {
const level = zr||this.__zr;
if (this._elMap.text &&level) {
level.removeHover(this._elMap.text);
}
}
getViewTipsPoint() {
const model = this._shape.model;
return {
x: model.point.x,
y: model.point.y
};
}
}

View File

@ -0,0 +1,159 @@
import * as color from 'zrender/src/tool/color';
import * as graphic from '../../../graph/graphic';
import panelType from '../../../constant/panelType';
export default class Pid extends graphic.Group {
constructor(painter, shape) {
super();
this._code = shape.model.code;
this._type = shape.model._type;
this._shape = shape;
this._painter = painter;
this._elMap = {
text: null,
button: null
};
this.create();
this.on('mouseover', this.mouseover, this);
this.on('mouseout', this.mouseout, this);
}
mouseover(e) {
const model = this._shape.model;
if (this._shape.draw) {
this._elMap.button.attr({cursor: 'pointer'});
this.doActive(this.__zr);
} else if (model.description) {
this._painter.$tipsHandle.trigger('show', {
x: e.offsetX,
y: e.offsetY,
text: model.description,
target: e.target
});
}
}
mouseout(e) {
const map = this._painter.$map;
if (this._shape.draw && !map.isHover(this._code)) {
this._elMap.button.attr({cursor: 'default'});
this.doInactive(this.__zr);
} else {
this._painter.$tipsHandle.trigger('hide');
}
}
create() {
const model = this._shape.model;
const style = this._shape.style;
this._elMap.button = new graphic.Rect({
zlevel: model.zlevel,
z: model.z,
shape: {
x: model.point.x-model.width/2,
y: model.point.y-model.height/2,
width: model.width,
height: model.height,
r: [1]
},
style: {
fill: style[panelType.Pid].button.fill,
stroke: style[panelType.Pid].button.stroke,
lineWidth: style[panelType.Pid].button.lineWidth,
shadowColor: '#dfdfdf',
shadowOffsetX: 1,
shadowOffsetY: 1
}
});
this._elMap.text = new graphic.Text({
zlevel: model.zlevel,
z: model.z,
z2: 2,
style: {
x: model.point.x,
y: model.point.y,
fontWeight: style[panelType.Pid].text.fontWeight,
fontFamily: style.fontFamily,
fontSize: model.fontSize,
text: model.text,
textFill: '#000',
textPadding: [4, 4],
textAlign: 'center',
textVerticalAlign: 'middle'
}
});
this.setState(model);
Object.values(this._elMap).forEach(elem => { elem && elem instanceof Array? elem.forEach(el => this.add(el)): this.add(elem); });
}
setShape(model) {
if (this._elMap.button) {
this._elMap.button.setShape({
x: model.point.x-model.width/2,
y: model.point.y-model.height/2
});
}
if (this._elMap.text) {
this._elMap.text.setStyle({
x: model.point.x,
y: model.point.y
});
}
}
setState(model) {}
dragging(e) {
const model = this._shape.model;
model.point.x += e.dx;
model.point.y += e.dy;
this.setShape(model);
}
doActive(zr) {
const style = this._shape.style;
const level = zr||this.__zr;
if (this._elMap.button && level) {
level.addHover(this._elMap.button, {
opacity: style.maskOpacity,
fill: color.lift(style.graphHover2Color, style.liftLevel)
});
}
if (this._elMap.text && level) {
level.addHover(this._elMap.text, {
opacity: style.maskOpacity,
textFill: color.lift(style.textHover2Color, style.liftLevel)
});
}
}
doInactive(zr) {
const level = zr||this.__zr;
if ( this._elMap.button && level) {
level.removeHover(this._elMap.button);
}
if ( this._elMap.text && level) {
level.removeHover(this._elMap.text);
}
}
getViewTipsPoint() {
if (this._elMap.button) {
const button = this._elMap.button.getBoundingRect();
return {
x: button.x + button.width/2,
y: button.y
};
}
}
}

View File

@ -0,0 +1,149 @@
import * as color from 'zrender/src/tool/color';
import * as graphic from '../../../graph/graphic';
import panelType from '../../../constant/panelType';
export default class Popup extends graphic.Group {
constructor(painter, shape) {
super();
this._code = shape.model.code;
this._type = shape.model._type;
this._shape = shape;
this._painter = painter;
this._elMap = {
text: null,
button: null
};
this.create();
this.on('mouseover', this.mouseover, this);
this.on('mouseout', this.mouseout, this);
}
mouseover(e) {
if (this._shape.draw) {
this._elMap.button.attr({cursor: 'pointer'});
this.doActive(this.__zr);
}
}
mouseout(e) {
const map = this._painter.$map;
if (this._shape.draw && !map.isHover(this._code)) {
this._elMap.button.attr({cursor: 'default'});
this.doInactive(this.__zr);
}
}
create() {
const model = this._shape.model;
const style = this._shape.style;
this._elMap.button = new graphic.Rect({
zlevel: model.zlevel,
z: model.z,
shape: {
x: model.point.x-model.width/2,
y: model.point.y-model.height/2,
width: model.width,
height: model.height,
r: [1]
},
style: {
fill: style[panelType.Popup].button.fill,
stroke: style[panelType.Popup].button.stroke,
lineWidth: style[panelType.Popup].button.lineWidth,
shadowColor: '#dfdfdf',
shadowOffsetX: 1,
shadowOffsetY: 1
}
});
this._elMap.text = new graphic.Text({
zlevel: model.zlevel,
z: model.z,
z2: 2,
style: {
x: model.point.x,
y: model.point.y,
fontWeight: style[panelType.Popup].text.fontWeight,
fontFamily: style.fontFamily,
fontSize: model.fontSize,
text: model.text,
textFill: '#000',
textPadding: [4, 4],
textAlign: 'center',
textVerticalAlign: 'middle'
}
});
this.setState(model);
Object.values(this._elMap).forEach(elem => { elem && elem instanceof Array? elem.forEach(el => this.add(el)): this.add(elem); });
}
setShape(model) {
if (this._elMap.button) {
this._elMap.button.setShape({
x: model.point.x-model.width/2,
y: model.point.y-model.height/2
});
}
if (this._elMap.text) {
this._elMap.text.setStyle({
x: model.point.x,
y: model.point.y
});
}
}
setState(model) {}
dragging(e) {
const model = this._shape.model;
model.point.x += e.dx;
model.point.y += e.dy;
this.setShape(model);
}
doActive(zr) {
const style = this._shape.style;
const level = zr||this.__zr;
if (this._elMap.button && level) {
level.addHover(this._elMap.button, {
opacity: style.maskOpacity,
fill: color.lift(style.graphHover2Color, style.liftLevel)
});
}
if (this._elMap.text && level) {
level.addHover(this._elMap.text, {
opacity: style.maskOpacity,
textFill: color.lift(style.textHover2Color, style.liftLevel)
});
}
}
doInactive(zr) {
const level = zr||this.__zr;
if ( this._elMap.button && level) {
level.removeHover(this._elMap.button);
}
if ( this._elMap.text && level) {
level.removeHover(this._elMap.text);
}
}
getViewTipsPoint() {
if (this._elMap.button) {
const button = this._elMap.button.getBoundingRect();
return {
x: button.x + button.width/2,
y: button.y
};
}
}
}

View File

@ -0,0 +1,308 @@
import * as color from 'zrender/src/tool/color';
import * as graphic from '../../../graph/graphic';
import panelType from '../../../constant/panelType';
export default class ProgramControl extends graphic.Group {
constructor(painter, shape) {
super();
this._code = shape.model.code;
this._type = shape.model._type;
this._shape = shape;
this._painter = painter;
this._elMap = {
line: null,
button: null,
blockStart: null,
blockReset: null,
blockStop: null,
start: null,
reset: null,
stop: null
};
this.create();
this.on('mouseover', this.mouseover, this);
this.on('mouseout', this.mouseout, this);
}
mouseover(e) {
const model = this._shape.model;
if (this._shape.draw) {
this._elMap.button.attr({cursor: 'pointer'});
this.doActive(this.__zr);
} else if (model.description) {
this._painter.$tipsHandle.trigger('show', {
x: e.offsetX,
y: e.offsetY,
text: model.description,
target: e.target
});
}
}
mouseout(e) {
const map = this._painter.$map;
if (this._shape.draw && !map.isHover(this._code)) {
this._elMap.button.attr({cursor: 'default'});
this.doInactive(this.__zr);
} else {
this._painter.$tipsHandle.trigger('hide');
}
}
create() {
const model = this._shape.model;
const style = this._shape.style;
this._elMap.line = new graphic.Line({
zlevel: model.zlevel,
z: model.z,
z2: 9,
shape: {
x1: model.point.x+style[panelType.ProgramControl].button.width/2,
y1: model.point.y+style[panelType.ProgramControl].button.height/2,
x2: model.point.x-style[panelType.ProgramControl].button.width/2,
y2: model.point.y-style[panelType.ProgramControl].button.height/2
},
style: {
stroke: style[panelType.ProgramControl].line.stroke,
lineWidth: style[panelType.ProgramControl].line.lineWidth,
lineCap: 'round'
}
});
this._elMap.button = new graphic.Rect({
zlevel: model.zlevel,
z: model.z,
shape: {
x: model.point.x-style[panelType.ProgramControl].button.width/2,
y: model.point.y-style[panelType.ProgramControl].button.height/2,
width: style[panelType.ProgramControl].button.width,
height: style[panelType.ProgramControl].button.height,
r: [1]
},
style: {
fill: style[panelType.ProgramControl].button.fill,
stroke: style[panelType.ProgramControl].button.stroke,
lineWidth: style[panelType.ProgramControl].button.lineWidth
}
});
this._elMap.blockStart = new graphic.Rect({
zlevel: model.zlevel,
z: model.z,
z2: 3,
shape: {
x: model.point.x-style[panelType.ProgramControl].button.width/2,
y: model.point.y-style[panelType.ProgramControl].button.height/2,
width: style[panelType.ProgramControl].button.width/3,
height: style[panelType.ProgramControl].button.height,
r: [1]
},
style: {
fill: style[panelType.ProgramControl].block.fill,
stroke: style[panelType.ProgramControl].block.stroke,
lineWidth: style[panelType.ProgramControl].block.lineWidth
}
});
this._elMap.blockReset = new graphic.Rect({
zlevel: model.zlevel,
z: model.z,
z2: 3,
shape: {
x: model.point.x-style[panelType.ProgramControl].button.width/2+style[panelType.ProgramControl].button.width/3,
y: model.point.y-style[panelType.ProgramControl].button.height/2,
width: style[panelType.ProgramControl].button.width/3,
height: style[panelType.ProgramControl].button.height,
r: [1]
},
style: {
fill: style[panelType.ProgramControl].block.fill,
stroke: style[panelType.ProgramControl].block.stroke,
lineWidth: style[panelType.ProgramControl].block.lineWidth
}
});
this._elMap.blockStop = new graphic.Rect({
zlevel: model.zlevel,
z: model.z,
z2: 3,
shape: {
x: model.point.x-style[panelType.ProgramControl].button.width/2+style[panelType.ProgramControl].button.width/3*2,
y: model.point.y-style[panelType.ProgramControl].button.height/2,
width: style[panelType.ProgramControl].button.width/3,
height: style[panelType.ProgramControl].button.height,
r: [1]
},
style: {
fill: style[panelType.ProgramControl].block.fill,
stroke: style[panelType.ProgramControl].block.stroke,
lineWidth: style[panelType.ProgramControl].block.lineWidth,
r: [1]
}
});
this._elMap.start = new graphic.Svg({
zlevel: model.zlevel,
z: model.z,
z2: 5,
origin: [0, 0],
rotation: 0,
scale: [1, 1],
shape: {
x: model.point.x-style[panelType.ProgramControl].button.width/2 + style[panelType.ProgramControl].button.width/6,
y: model.point.y-style[panelType.ProgramControl].button.height/2,
path: 'M6 12 L-4 6 L-4 18Z'
},
style: {
fill: style[panelType.ProgramControl].indicate.fill
}
});
this._elMap.reset = new graphic.Svg({
zlevel: model.zlevel,
z: model.z,
z2: 5,
origin: [0, 0],
rotation: 0,
scale: [1, 1],
shape: {
x: model.point.x-style[panelType.ProgramControl].button.width/2+style[panelType.ProgramControl].button.width/3 + style[panelType.ProgramControl].button.width/6,
y: model.point.y-style[panelType.ProgramControl].button.height/2,
path: 'M6 6 L6 18 L1 18 L1 6Z M-6 6 L-6 18 L-1 18 L-1 6Z'
},
style: {
fill: style[panelType.ProgramControl].indicate.fill
}
});
this._elMap.stop = new graphic.Svg({
zlevel: model.zlevel,
z: model.z,
z2: 5,
origin: [0, 0],
rotation: 0,
scale: [1, 1],
shape: {
x: model.point.x-style[panelType.ProgramControl].button.width/2+style[panelType.ProgramControl].button.width/3*2 + style[panelType.ProgramControl].button.width/6,
y: model.point.y-style[panelType.ProgramControl].button.height/2,
path: 'M6 6 L6 18 L-6 18 L-6 6Z'
},
style: {
fill: style[panelType.ProgramControl].indicate.fill
}
});
this.setState(model);
Object.values(this._elMap).forEach(elem => { elem && elem instanceof Array? elem.forEach(el => this.add(el)): this.add(elem); });
}
setShape(model) {
const style = this._shape.style;
if (this._elMap.line) {
this._elMap.line.setShape({
x1: model.point.x+style[panelType.ProgramControl].button.width/2,
y1: model.point.y+style[panelType.ProgramControl].button.height/2,
x2: model.point.x-style[panelType.ProgramControl].button.width/2,
y2: model.point.y-style[panelType.ProgramControl].button.height/2
});
}
if (this._elMap.button) {
this._elMap.button.setShape({
x: model.point.x-style[panelType.ProgramControl].button.width/2,
y: model.point.y-style[panelType.ProgramControl].button.height/2
});
}
if (this._elMap.blockStart) {
this._elMap.blockStart.setShape({
x: model.point.x-style[panelType.ProgramControl].button.width/2,
y: model.point.y-style[panelType.ProgramControl].button.height/2,
width: style[panelType.ProgramControl].button.width/3,
height: style[panelType.ProgramControl].button.height
});
}
if (this._elMap.blockReset) {
this._elMap.blockReset.setShape({
x: model.point.x-style[panelType.ProgramControl].button.width/2+style[panelType.ProgramControl].button.width/3,
y: model.point.y-style[panelType.ProgramControl].button.height/2,
width: style[panelType.ProgramControl].button.width/3,
height: style[panelType.ProgramControl].button.height
});
}
if (this._elMap.blockStop) {
this._elMap.blockStop.setShape({
x: model.point.x-style[panelType.ProgramControl].button.width/2+style[panelType.ProgramControl].button.width/3*2,
y: model.point.y-style[panelType.ProgramControl].button.height/2,
width: style[panelType.ProgramControl].button.width/3,
height: style[panelType.ProgramControl].button.height
});
}
if (this._elMap.start) {
this._elMap.start.setShape({
x: model.point.x-style[panelType.ProgramControl].button.width/2 + style[panelType.ProgramControl].button.width/6,
y: model.point.y-style[panelType.ProgramControl].button.height/2
});
}
if (this._elMap.reset) {
this._elMap.reset.setShape({
x: model.point.x-style[panelType.ProgramControl].button.width/2+style[panelType.ProgramControl].button.width/3 + style[panelType.ProgramControl].button.width/6,
y: model.point.y-style[panelType.ProgramControl].button.height/2
});
}
if (this._elMap.stop) {
this._elMap.stop.setShape({
x: model.point.x-style[panelType.ProgramControl].button.width/2+style[panelType.ProgramControl].button.width/3*2 + style[panelType.ProgramControl].button.width/6,
y: model.point.y-style[panelType.ProgramControl].button.height/2
});
}
}
setState(model) {}
dragging(e) {
const model = this._shape.model;
model.point.x += e.dx;
model.point.y += e.dy;
this.setShape(model);
}
doActive(zr) {
const style = this._shape.style;
const level = zr||this.__zr;
if (this._elMap.button && level) {
level.addHover(this._elMap.button, {
opacity: style.maskOpacity,
fill: color.lift(style.graphHover2Color, style.liftLevel),
stroke: color.lift(style.graphHover2Color, style.liftLevel)
});
}
}
doInactive(zr) {
const level = zr||this.__zr;
if ( this._elMap.button && level) {
level.removeHover(this._elMap.button);
}
}
getViewTipsPoint() {
if (this._elMap.button) {
const button = this._elMap.button.getBoundingRect();
return {
x: button.x + button.width/2,
y: button.y
};
}
}
}

View File

@ -0,0 +1,62 @@
import * as utils from '../../../utils/utils';
class Caches {
constructor () {
this.registerMap = {};
}
register(model, statuses) {
const type = model.entity.type;
const resourceId = model.resourceId;
const cacheMap = this.getCacheMap(this.registerMap, type);
if (!cacheMap[resourceId]) {
cacheMap[resourceId] = this.buildMapper(statuses);
}
return new Proxy(cacheMap[resourceId], {
get: function(source, key) { return source[key]||source.none; }
});
}
buildMapper(statuses) {
const map = {};
if (statuses instanceof Array) {
statuses.forEach(el => {
const urls = el.urls;
if (urls.length == 1) {
map[el.status] = utils.getResourceUrl(el.urls[0]);
} else {
map[el.status] = [];
urls.forEach(url => {
map[el.status].push(utils.getResourceUrl(url));
});
}
});
} else {
Object.keys(statuses).forEach(status => {
const urls = statuses[status].urls;
if (urls.length == 1) {
map[status] = utils.getResourceUrl(urls[0]);
} else {
map[status] = [];
urls.forEach(url => {
map[status].push(utils.getResourceUrl(url));
});
}
});
}
return map;
}
getCacheMap(target, type) {
if (!target[type]) { target[type]= {}; }
return target[type];
}
clear() {
this.registerMap = {};
}
}
export default new Caches();

View File

@ -0,0 +1,251 @@
import * as utils from '../../../utils/utils';
import * as graphic from '../../../graph/graphic';
import panelType from '../../../constant/panelType';
import StateHandle from './stateHandle.js';
import Caches from './caches';
class Adaptor {
constructor({model, state}) {
this.__model = model;
this.__state = state;
}
get() {
const model = this.__model;
const resource = (this.__state.mapResource||{})[model.resourceId] || {};
const size = (resource.size||'').split(',') || [0, 0];
const width = model.width? model.width: size[0];
const height = model.height? model.height: size[1];
return Object.assign(model, resource, {
width: parseFloat(width),
height: parseFloat(height),
resource
});
}
}
export default class Resource extends graphic.Group {
constructor(painter, shape, state) {
super();
this._code = shape.model.code;
this._type = shape.model._type;
this._shape = shape;
this._painter = painter;
this._state = state;
this._count = 0;
this._timer = null;
this._adaptor = new Adaptor({model: shape.model, state});
this._elMap = {
image: null,
warning: null
};
this.create();
this.on('mouseover', this.mouseover, this);
this.on('mouseout', this.mouseout, this);
}
mouseover(e) {
const model = this._shape.model;
const control = model.control||{};
if (this._shape.draw) {
this._elMap.image.attr({cursor: 'pointer'});
this.doFocus();
} else if (this._elMap.image) {
this._elMap.image.attr({cursor: control.disabled? 'default': 'pointer'});
if (model.description) {
this._painter.$tipsHandle.trigger('show', {
x: e.offsetX,
y: e.offsetY,
text: model.description,
target: e.target
});
}
}
}
mouseout(e) {
const map = this._painter.$map;
if (this._shape.draw && !map.isHover(this._code)) {
this.doBlur();
} else {
this._elMap.image.attr({cursor: 'default'});
this._painter.$tipsHandle.trigger('hide');
}
}
create() {
const model = this._adaptor.get();
const style = this._shape.style;
const rotation = -Math.PI / 180 * Number(model.rotate||0);
const origin = [model.point.x+model.width/2, model.point.y+model.height/2];
const scale = new Array(2).fill(model.scale || 1);
const cache = this.register(model);
const isVisible = this._state.isDraw
? true
: !['PipeFitting'].includes(model.entity.type)&&model.visible;
if (cache&&isVisible) {
if (utils.urlIsSvg(cache.none)) {
this._elMap.image = new graphic.Svg({
zlevel: model.zlevel,
z: model.z,
z2: model.layer+5,
origin: [0, 0],
rotation,
scale,
shape: {
x: model.point.x,
y: model.point.y,
path: cache.none
},
style: {
lineWidth: style[panelType.LinePipe].arrow.lineWidth,
stroke: '#fff',
fill: '#fff'
}
});
} else {
this._elMap.image = new graphic.Image({
zlevel: model.zlevel,
z: model.z,
z2: model.layer+5,
origin,
rotation,
scale,
style: {
image: cache.none,
x: model.point.x,
y: model.point.y,
width: model.width*scale[0],
height: model.height*scale[1]
}
});
}
}
Object.values(this._elMap).forEach(elem => { elem && elem instanceof Array? elem.forEach(el => this.add(el)): this.add(elem); });
this.setState(model);
}
traversed(map, cb) {
Object.values(map).forEach(el => {
if (el) {
if (el instanceof Array) {
this.traversed(el, cb);
} else {
cb(el);
}
}
});
}
setShape(model, e) {
if (this._elMap.image) {
if (utils.shapeIsSvg(this._elMap.image)) {
this._elMap.image.setShape({
x: model.point.x,
y: model.point.y
});
} else {
const origin = [model.point.x+model.width/2, model.point.y+model.height/2];
const scale = new Array(2).fill(model.scale || 1);
this._elMap.image.attr('origin', origin);
this._elMap.image.setStyle({
x: model.point.x,
y: model.point.y,
width: model.width*scale[0],
height: model.height*scale[1]
});
}
}
}
setState(model) {
StateHandle.reload(this);
StateHandle.update();
StateHandle.unload();
}
dragging(e) {
const model = this._adaptor.get();
model.point.x += e.dx;
model.point.y += e.dy;
this.setShape(model, e);
}
doActive(zr) {
const style = this._shape.style;
const level = zr||this.__zr;
if (level && this._elMap.STL_Background) {
this._elMap.STL_Background.doActive(level);
} else if (level && this._elMap.image) {
level.addHover(this._elMap.image, {
opacity: style.maskOpacity,
image: style.maskHover2Image,
fill: style.measureHover2Color,
stroke: style.measureHover2Color
});
}
}
doInactive(zr) {
const level = zr||this.__zr;
if (this._elMap.STL_Background) {
this._elMap.STL_Background.doInactive(level);
} else if (level && this._elMap.image) {
level.removeHover(this._elMap.image);
}
this.doBlur();
}
doFocus() {
Object.values(this._elMap).forEach(elem => {
if (elem) {
elem.setStyle({opacity: 0.5});
}
});
}
doBlur() {
Object.values(this._elMap).forEach(elem => {
if (elem) {
elem.setStyle({opacity: 1});
}
});
}
register(model) {
if (model.resource) {
const resource = model.resource;
const statuses = resource.statusList||[];
statuses.push({status: 'none', urls: [resource.url]});
return Caches.register(model, statuses);
} else {
console.info(`设备绘图不支${model.entity.type}绘图(${model.code})`);
}
}
getViewTipsPoint() {
const model = this._adaptor.get();
const image = this._elMap.image;
if (image) {
const rect = image.getBoundingRect();
return {
x: model.point.x + rect.width/10,
y: model.point.y + rect.height/20
};
}
}
}

View File

@ -0,0 +1,52 @@
class StateHandle {
constructor() {
this.unload();
this.animateMap = null;
}
reload(graph) {
this.graph = graph;
this.model = graph._shape.model;
this.style = graph._shape.style;
this.state = graph._state;
}
unload() {
this.graph = null;
this.model = null;
this.style = null;
}
update() {
if (this.graph) {
const data = this.model.entity.data;
const graph = this.graph;
const cache = this.graph.register(this.model);
if (data && cache && graph._elMap.image) {
const status = cache[data.status];
graph._elMap.image.stopAnimation();
if (status instanceof Array) {
graph._elMap.image.animate('style', true)
.when(37, {image: cache.none })
.when(74, {image: null })
.during(() => {
if (+new Date() - graph._delta > 74) {
graph._elMap.image.setStyle({image: status[graph._count%2]});
graph._delta = +new Date();
graph._count = graph._count%2+1;
}
})
.start();
} else {
graph._elMap.image.stopAnimation();
graph._elMap.image.setStyle({ image: status });
graph._delta = 0;
graph._count = 0;
}
}
}
}
}
export default new StateHandle();

View File

@ -0,0 +1,195 @@
import * as color from 'zrender/src/tool/color';
import * as graphic from '../../../graph/graphic';
import panelType from '../../../constant/panelType';
export default class Switching extends graphic.Group {
constructor(painter, shape) {
super();
this._code = shape.model.code;
this._type = shape.model._type;
this._shape = shape;
this._painter = painter;
this._elMap = {
text: null,
button: null
};
this.create();
this.on('mouseover', this.mouseover, this);
this.on('mouseout', this.mouseout, this);
this.on('mousedown', this.mousedown, this);
this.on('mouseup', this.mouseup, this);
}
mousedown(e) {
const model = this._shape.model;
if (model.isReset &&
!this._shape.draw &&
this._elMap.button) {
this._elMap.button.setStyle({
fill: '#FF0000'
});
}
}
mouseup(e) {
const model = this._shape.model;
const style = this._shape.style;
if (model.isReset &&
!this._shape.draw &&
this._elMap.button) {
setTimeout(() => {
this._elMap.button.setStyle({
fill: style[panelType.Switching].button.fill
});
}, 200);
}
}
mouseover(e) {
if (this._shape.draw) {
this._elMap.button.attr({cursor: 'pointer'});
this.doActive(this.__zr);
}
}
mouseout(e) {
const map = this._painter.$map;
if (this._shape.draw && !map.isHover(this._code)) {
this._elMap.button.attr({cursor: 'default'});
this.doInactive(this.__zr);
}
}
create() {
const model = this._shape.model;
const style = this._shape.style;
this._elMap.button = new graphic.Rect({
zlevel: model.zlevel,
z: model.z,
shape: {
x: model.point.x-model.width/2,
y: model.point.y-model.height/2,
width: model.width,
height: model.height,
r: [1]
},
style: {
fill: style[panelType.Switching].button.fill,
stroke: style[panelType.Switching].button.stroke,
lineWidth: style[panelType.Switching].button.lineWidth,
shadowColor: '#dfdfdf',
shadowOffsetX: 1,
shadowOffsetY: 1
}
});
this._elMap.text = new graphic.Text({
zlevel: model.zlevel,
z: model.z,
z2: 2,
style: {
x: model.point.x,
y: model.point.y,
fontWeight: style[panelType.Switching].text.fontWeight,
fontFamily: style.fontFamily,
fontSize: model.fontSize,
text: model.putInText,
textFill: '#000',
textPadding: [4, 4],
textAlign: 'center',
textVerticalAlign: 'middle'
}
});
this.setState(model);
Object.values(this._elMap).forEach(elem => { elem && elem instanceof Array? elem.forEach(el => this.add(el)): this.add(elem); });
}
setShape(model) {
if (this._elMap.button) {
this._elMap.button.setShape({
x: model.point.x-model.width/2,
y: model.point.y-model.height/2
});
}
if (this._elMap.text) {
this._elMap.text.setStyle({
x: model.point.x,
y: model.point.y
});
}
}
setState(model) {
const entity = model.entity||{};
const data = entity.data ||{};
if (!model.isReset &&
!this._shape.draw &&
entity.data) {
if (this._elMap.button) {
this._elMap.button.setStyle({
fill: data.status? '#FF0000' : '#3CB371'
});
}
if (this._elMap.text) {
this._elMap.text.setStyle({
text: data.status? model.putInText: model.cutOffText
});
}
}
}
dragging(e) {
const model = this._shape.model;
model.point.x += e.dx;
model.point.y += e.dy;
this.setShape(model);
}
doActive(zr) {
const style = this._shape.style;
const level = zr||this.__zr;
if (this._elMap.button && level) {
level.addHover(this._elMap.button, {
opacity: style.maskOpacity,
fill: color.lift(style.graphHover2Color, style.liftLevel)
});
}
if (this._elMap.text && level) {
level.addHover(this._elMap.text, {
opacity: style.maskOpacity,
textFill: color.lift(style.textHover2Color, style.liftLevel)
});
}
}
doInactive(zr) {
const level = zr||this.__zr;
if ( this._elMap.button && level) {
level.removeHover(this._elMap.button);
}
if ( this._elMap.text && level) {
level.removeHover(this._elMap.text);
}
}
getViewTipsPoint() {
if (this._elMap.button) {
const button = this._elMap.button.getBoundingRect();
return {
x: button.x + button.width/2,
y: button.y
};
}
}
}

View File

@ -0,0 +1,144 @@
import * as graphic from '../../../graph/graphic';
import panelType from '../../../constant/panelType';
export default class Table extends graphic.Group {
constructor(painter, shape) {
super();
this._code = shape.model.code;
this._type = shape.model._type;
this._shape = shape;
this._painter = painter;
this._elMap = {
table: null
};
this.create();
this.on('mouseover', this.mouseover, this);
this.on('mouseout', this.mouseout, this);
}
mouseover(e) {
if (this._shape.draw) {
this.doActive(this.__zr);
}
}
mouseout(e) {
const map = this._painter.$map;
if (this._shape.draw && !map.isHover(this._code)) {
this.doInactive(this.__zr);
}
}
create() {
const draw = this._shape.draw;
const model = this._shape.model;
const style = this._shape.style;
this._elMap.header = new graphic.Rect({
zlevel: model.zlevel,
z: model.z,
z2: -1,
cursor: draw? 'pointer': 'default',
shape: {
x: model.point.x,
y: model.point.y,
width: model.width,
height: style[panelType.Table].header.height
},
style: {
stroke: model.lineColor,
lineWidth: model.lineWidth,
fill: model.headerBg
}
});
this._elMap.body = new graphic.Rect({
zlevel: model.zlevel,
z: model.z,
z2: -1,
silent: true,
shape: {
x: model.point.x,
y: model.point.y+style[panelType.Table].header.height,
width: model.width,
height: model.height
},
style: {
stroke: model.lineColor,
lineWidth: model.lineWidth,
fill: model.bodyBg
}
});
this._elMap.title = new graphic.Text({
zlevel: model.zlevel,
z: model.z,
z2: 0,
cursor: draw? 'pointer': 'default',
style: {
x: model.point.x+model.width/2,
y: model.point.y+style[panelType.Table].header.height/2,
fontWeight: style[panelType.Table].header.fontWeight,
fontSize: style[panelType.Table].header.fontSize,
fontFamily: style.fontFamily,
text: model.title||'标题',
textAlign: 'center',
textVerticalAlign: 'middle'
}
});
Object.values(this._elMap).forEach(elem => { elem && elem instanceof Array? elem.forEach(el => this.add(el)): this.add(elem); });
}
setShape(model) {
const style = this._shape.style;
if (this._elMap.header) {
this._elMap.header.setShape({
x: model.point.x,
y: model.point.y
});
}
if (this._elMap.body) {
this._elMap.body.setShape({
x: model.point.x,
y: model.point.y+style[panelType.Table].header.height
});
}
if (this._elMap.title) {
this._elMap.title.setStyle({
x: model.point.x+model.width/2,
y: model.point.y+style[panelType.Table].header.height/2
});
}
}
setState(model, e) {
}
dragging(e) {
const model = this._shape.model;
model.point.x += e.dx;
model.point.y += e.dy;
this.setShape(model);
}
doActive(zr) {
}
doInactive(zr) {
}
getViewTipsPoint() {}
}

View File

@ -0,0 +1,132 @@
import * as color from 'zrender/src/tool/color';
import * as graphic from '../../../graph/graphic';
export default class Text2 extends graphic.Group {
constructor(painter, shape) {
super();
this._code = shape.model.code;
this._type = shape.model._type;
this._shape = shape;
this._painter = painter;
this._rotation = null;
this._origin = null;
this._elMap = {
text: null
};
this.create();
this.on('mouseover', this.mouseover, this);
this.on('mouseout', this.mouseout, this);
}
mouseover(e) {
if (this._shape.draw) {
this.doActive(this.__zr);
}
}
mouseout(e) {
const map = this._painter.$map;
if (this._shape.draw && !map.isHover(this._code)) {
this.doInactive(this.__zr);
}
}
create() {
const draw = this._shape.draw;
const model = this._shape.model;
const backGroundColor = this.getTextBgColor(model);
const textStyle = this.getTextStyle(model);
this._rotation = -Math.PI / 180 * Number(model.rotate||0);
this._origin = [model.point.x, model.point.y];
this._elMap.text = new graphic.Text({
zlevel: model.zlevel,
z: model.z,
origin: this._origin,
rotation: this._rotation,
silent: !draw,
style: {
x: model.point.x,
y: model.point.y,
fontWeight: 'normal',
textBackgroundColor: backGroundColor,
fontSize: model.fontSize,
fontFamily: model.font,
text: textStyle.textValue || textStyle.value || '',
textLineHeight: model.fontSize+4,
textFill: model.fontColor,
textPadding: [4, 4],
textAlign: textStyle.textAlign,
textVerticalAlign: 'middle'
}
});
this.setState(model);
Object.values(this._elMap).forEach(elem => { elem && elem instanceof Array? elem.forEach(el => this.add(el)): this.add(elem); });
}
getTextStyle(model) {
const pattern = /\{<(?<textAlign>\w+)>\}\{<(?<textVerticalAlign>\w+)>\}(?<textValue>(.|\n)*)|(?<value>(.|\n)*)/;
const groups = (pattern.exec(model.name)||{}).groups||{};
return groups;
}
getTextBgColor(model) {
const pattern = /\{<(?<active>\w+)>\}(?<string>(.|\n)*)/;
const groups = (pattern.exec(model.backGroundColor)||{}).groups||{};
return groups.active == 'image'
? { image: `${process.env.VUE_APP_BASE_RESOURCE_URL}${groups.string}` }
: groups.active == 'color'
? groups.string
: model.backGroundColor;
}
setShape(model) {
if (this._elMap.text) {
this._origin = [model.point.x, model.point.y];
this._elMap.text.attr('origin', this._origin);
this._elMap.text.setStyle({
x: model.point.x,
y: model.point.y
});
}
}
setState(model) {
}
dragging(e) {
const model = this._shape.model;
model.point.x += e.dx;
model.point.y += e.dy;
this.setShape(model);
}
doActive(zr) {
const style = this._shape.style;
const level = zr||this.__zr;
if (this._elMap.text && level) {
level.addHover(this._elMap.text, {
opacity: style.maskOpacity,
textBackgroundColor: color.lift(style.textHover2Color, style.liftLevel)
});
}
}
doInactive(zr) {
const level = zr||this.__zr;
if (this._elMap.text && level) {
level.removeHover(this._elMap.text);
}
}
getViewTipsPoint() {}
}

View File

@ -0,0 +1,172 @@
import RadialGradient from 'zrender/src/graphic/RadialGradient';
import * as graphic from '../../../graph/graphic';
import * as color from 'zrender/src/tool/color';
import panelType from '../../../constant/panelType';
import ConstConfig from '@/scripts/ConstConfig';
export default class Warning extends graphic.Group {
constructor(painter, shape, state) {
super();
this._code = shape.model.code;
this._type = shape.model._type;
this._shape = shape;
this._state = state;
this._painter = painter;
this._state = state;
this._elMap = {
circle: null
};
this.create();
this.on('mouseover', this.mouseover, this);
this.on('mouseout', this.mouseout, this);
}
mouseover(e) {
const model = this._shape.model;
if (this._shape.draw) {
this.doActive(this.__zr);
} else if (model.description) {
this._painter.$tipsHandle.trigger('show', {
x: e.offsetX,
y: e.offsetY,
text: model.description,
target: e.target
});
}
}
mouseout(e) {
const map = this._painter.$map;
if (this._shape.draw && !map.isHover(this._code)) {
this.doInactive(this.__zr);
} else {
this._painter.$tipsHandle.trigger('hide');
}
}
create() {
const model = this._shape.model;
const style = this._shape.style;
const distance = 8;
this._elMap.circle = new graphic.Circle({
zlevel: model.zlevel,
z: model.z,
shape: {
cx: model.point.x,
cy: model.point.y,
r: model.radius||10
},
style: {
lineWidth: style[panelType.Warning].circle.lineWidth,
stroke: style[panelType.Warning].circle.stroke,
fill: new RadialGradient(0.5, 0.5, 0.5, [
{offset: 0, color: '#eeeeee'},
{offset: 1, color: '#666666'}
])
}
});
const signX = ConstConfig.ConstMap.LocationMode.Left.value == model.showPosition
? -1
: ConstConfig.ConstMap.LocationMode.Right.value == model.showPosition
? 1
: 0;
const signY = ConstConfig.ConstMap.LocationMode.Top.value == model.showPosition
? -1
: ConstConfig.ConstMap.LocationMode.Bottom.value == model.showPosition
? 1
: 0;
this._elMap.text = new graphic.Text({
zlevel: model.zlevel,
z: model.z,
style: {
x: model.point.x + signX*(model.radius+distance),
y: model.point.y + signY*(model.radius+distance*2),
fontFamily: style.fontFamily,
fontWeight: style[panelType.Warning].text.fontWeight,
fontSize: style[panelType.Warning].text.fontSize,
textFill: style[panelType.Warning].text.textFill,
textVerticalAlign: 'middle',
text: model.description,
textAlign: ConstConfig.ConstMap.LocationMode.Left.value == model.showPosition
? 'right'
: ConstConfig.ConstMap.LocationMode.Right.value == model.showPosition
? 'left'
: 'center'
}
});
model.textShow? this._elMap.text.show(): this._elMap.text.hide();
this.setState(model);
Object.values(this._elMap).forEach(elem => { elem && elem instanceof Array? elem.forEach(el => this.add(el)): this.add(elem); });
}
setShape(model) {
if (this._elMap.circle) {
this._elMap.circle.setShape({
cx: model.point.x,
cy: model.point.y
});
}
if (this._elMap.text) {
const distance = 8;
const signX = ConstConfig.ConstMap.LocationMode.Left.value == model.showPosition
? -1
: ConstConfig.ConstMap.LocationMode.Right.value == model.showPosition
? 1
: 0;
const signY = ConstConfig.ConstMap.LocationMode.Top.value == model.showPosition
? -1
: ConstConfig.ConstMap.LocationMode.Bottom.value == model.showPosition
? 1
: 0;
this._elMap.text.setStyle({
x: model.point.x + signX*(model.radius+distance),
y: model.point.y + signY*(model.radius+distance*2)
});
}
}
setState(model) {
}
dragging(e) {
const model = this._shape.model;
model.point.x += e.dx;
model.point.y += e.dy;
this.setShape(model);
}
doActive(zr) {
const style = this._shape.style;
const level = zr||this.__zr;
if (this._elMap.circle && level) {
level.addHover(this._elMap.circle, {
opacity: style.maskOpacity,
fill: color.lift(style.graphHover2Color, style.liftLevel)
});
}
}
doInactive(zr) {
const level = zr||this.__zr;
if (this._elMap.circle &&level) {
level.removeHover(this._elMap.circle);
}
}
getViewTipsPoint() {
const model = this._shape.model;
return {
x: model.point.x,
y: model.point.y
};
}
}

View File

@ -0,0 +1,29 @@
import panelType from '../../constant/panelType';
import Text2 from './Text/index';
import Table from './Table/index';
import LinePipe from './LinePipe/index';
import Resource from './Resource/index';
import Measure from './Measure/index';
import Warning from './Warning/index';
import Switching from './Switching/index';
import Popup from './Popup/index';
import ProgramControl from './ProgramControl/index';
import Pid from './Pid/index';
/** 图库*/
const mapShape = {};
mapShape[panelType.Text] = Text2;
mapShape[panelType.Table] = Table;
mapShape[panelType.LinePipe] = LinePipe;
mapShape[panelType.Resource] = Resource;
mapShape[panelType.Measure] = Measure;
mapShape[panelType.Warning] = Warning;
mapShape[panelType.Switching] = Switching;
mapShape[panelType.Popup] = Popup;
mapShape[panelType.ProgramControl] = ProgramControl;
mapShape[panelType.Pid] = Pid;
export default mapShape;

229
src/iscs_new/painter.js Normal file
View File

@ -0,0 +1,229 @@
import * as zrUtil from 'zrender/src/core/util';
import * as vector from 'zrender/src/core/vector';
import Graphic from './package';
import Group from 'zrender/src/container/Group';
import graphType from './constant/graphType';
import panelType from './constant/panelType';
import resourceType from './constant/resourceType';
import TransformHandle from './transformHandle';
import StateHandle from './stateHandle';
import TipsHandle from './tipsHandle';
import { ParserType } from './parser/index.js';
function traverseLayers(layers) {
return (inject) => {
inject(layers, type => { return layers.includes(type); });
};
}
class Painter {
constructor(map) {
this.$map = map;
this.$zr = map.getZr();
// 图层数据
this.mapInstanceLevel = {};
// 初始图层
this.initLevels();
// 视图控制器
this.$transformHandle = new TransformHandle(this);
// 状态处理器
this.$stateHandle = new StateHandle(map);
// 提示处理器
this.$tipsHandle = new TipsHandle(map);
}
initLevels() {
// 图层分级策略
// 预留图层级功能 默认全部显示
this.parserBranch = {};
this.parserBranch[ParserType.Graph.value] = traverseLayers(Object.values(graphType));
this.parserBranch[ParserType.Panel.value] = traverseLayers(Object.values(panelType));
this.parserBranch[ParserType.Resource.value] = traverseLayers(Object.values(resourceType));
// 添加父级图层
this.parentLevel = new Group({ name: '__parent__' });
this.$zr.add(this.parentLevel);
// 添加hover子级图层
this.hoverLevel = new Group({ name: `___hover__` });
this.parentLevel.add(this.hoverLevel);
// 添加提示子级图层
this.tipsLevel = new Group({name: `__tips__`});
this.parentLevel.add(this.tipsLevel);
// 添加设备子级图层
// 添加设备模板子级图层
zrUtil.each([
...Object.values(graphType),
...Object.values(panelType),
...Object.values(resourceType)], type => {
const level = new Group({ name: `__${type}__` });
this.mapInstanceLevel[type] = level;
this.parentLevel.add(level);
});
}
newGraph(shape) {
const type = shape.model._type;
const state = this.$map.getState(); // 获取 默认状态
const builder = Graphic.getBuilder(type); // 根据 type 绘制 面板,资源,画面对应的 instance
return builder(this, shape, state);
}
doHover(view, visible=true) {
visible
? this.$map.isHover(view._code)
? view.doActive
? view.doActive(this.$zr)
: null
: view.doInactive
? view.doInactive(this.$zr)
: null
: view.doInactive
? view.doInactive()
: null;
}
add(shape) {
try {
this.delete(shape);
shape.instance = this.newGraph(shape);
if (shape.instance) {
this.$transformHandle.transformView(shape.instance);
this.mapInstanceLevel[shape.model._type].add(shape.instance); // 添加type
this.doHover(shape.instance);
}
} catch (err) {
console.error(err);
}
}
delete(shape) {
if (shape.hover) {
this.hoverLevel.remove(shape.hover);
shape.hover = null;
}
if (shape.instance) {
shape.instance.doInactive(this.$zr);
this.mapInstanceLevel[shape.model._type].remove(shape.instance);
}
}
// 更新设备状态
update(shape) {
try {
if (shape) {
this.$stateHandle.update(shape);
}
} catch (err) {
console.error(err);
}
}
updateTransform(opt) {
this.$transformHandle.updateTransform(opt);
}
updateZrSize(opt) {
this.$transformHandle.updateZrSize(opt);
}
addHoverElem(view) {
this.$transformHandle.transformView(view);
this.hoverLevel.add(view);
}
delHoverElem(view) {
this.hoverLevel.remove(view);
}
setLayerVisible(typeList, parserType = ParserType.Graph.value) {
this.parserBranch[parserType]((layers, check) => {
zrUtil.each(layers, type => {
const instance = this.mapInstanceLevel[type];
if (check(type) && typeList.includes(type)) {
this.parentLevel.add(instance);
} else {
this.parentLevel.remove(instance);
}
}, this);
});
}
setResourceVisible(view, visible) {
const instance = this.mapInstanceLevel[graphType.Resource];
if (instance) {
if (visible) {
this.$transformHandle.transformView(view);
instance.add(view);
} else {
instance.remove(view);
}
}
}
refresh() {
this.$zr.refresh();
}
clear() {
if (this.hoverLevel) {
this.hoverLevel.removeAll();
}
zrUtil.each(Object.values(this.mapInstanceLevel), (level) => {
level && level.removeAll();
}, this);
this.refresh();
}
dispose() {
this.clear();
this.mapInstanceLevel = {};
this.parentLevel = null;
this.$tipsHandle.dispose();
}
getMapShape() {
return this.$map.getMapShape();
}
getShapeByCode(code) {
return this.$map.getShapeByCode(code);
}
getViewTipsPoint(step) {
const shape = this.getShapeByCode(step.code)||{};
const instance = shape.instance;
if (instance) {
const point = instance.getViewTipsPoint();
if (point) {
const transform = this.$transformHandle.getTransform();
const transPoint = vector.applyTransform([], [point.x, point.y], transform);
return {
x: transPoint[0],
y: transPoint[1]
};
}
}
}
getParentLevel() {
return this.parentLevel;
}
getTipsLevel() {
return this.tipsLevel;
}
}
export default Painter;

View File

@ -0,0 +1,21 @@
import * as parserGraph from './parser-graph.js';
import * as parserResource from './parser-resource.js';
import * as parserPanel from './parser-panel.js';
export const ParserType = {
Graph: { name: '绘图', value: 'Graph' },
Data: { name: '数据', value: 'Data' },
Panel: { name: '面板', value: 'Panel'},
Resource: { name: '资源', value: 'Resource'}
};
export function parserFactory(type) {
switch (type) {
case ParserType.Data.value:
case ParserType.Graph.value : return parserGraph;
case ParserType.Resource.value: return parserResource;
case ParserType.Panel.value: return parserPanel;
}
return parserGraph;
}

View File

@ -0,0 +1,199 @@
import * as zrUtil from 'zrender/src/core/util';
import * as utils from '../utils/utils';
import graphType from '../constant/graphType';
import graphRender from '../constant/graphRender';
import graphStyle from '../config/graphStyle';
// 创建一个Shape结构
export function newShape(entity, type, model) {
return { model: Object.assign(model, graphRender[type], {entity}), style: graphStyle, instance: null, hover: null, dragging: false, draw: false };
}
// 解析绘图原始数据
export function parse(state, data, isDraw) {
const mapLink = state.mapLink;
const mapEntity = state.mapEntity;
const mapShape = {};
try {
if (data) {
// 文字
zrUtil.each(data.textList||[], el => {
const entity = { type: 'Text', data: {}};
mapShape[el.code] = newShape(entity, graphType.Text, el);
}, this);
// 按钮
zrUtil.each(data.buttonList||[], el => {
const entity = { type: 'Button', data: {}};
mapShape[el.code] = newShape(entity, graphType.Button, el);
}, this);
// 表
zrUtil.each(data.tableList||[], el => {
const entity = { type: 'Table', data: {}};
mapShape[el.code] = newShape(entity, graphType.Table, el);
}, this);
// 表1
zrUtil.each(data.tableList||[], el => {
const entity = { type: 'Table1', data: {}};
mapShape[el.code] = newShape(entity, graphType.Table1, el);
}, this);
// 资源
zrUtil.each(data.resourceList||[], el => {
const link = utils.getLinkByModel(mapLink, {...el, _type: graphType.Resource})||{};
const entity = isDraw
? mapEntity[link.code]||{}
: mapEntity[link.code] = { code: link.code, type: link.type, data: {}};
mapShape[el.code] = newShape(entity, graphType.Resource, el);
}, this);
// 管线
zrUtil.each(data.linePipeList||[], el => {
const link = utils.getLinkByModel(mapLink, {...el, _type: graphType.LinePipe})||{};
const entity = isDraw
? mapEntity[link.code]||{}
: mapEntity[link.code] = { code: link.code, type: 'Pipe', data: {}};
mapShape[el.code] = newShape(entity, graphType.LinePipe, el);
}, this);
// 计量
zrUtil.each(data.measureList||[], el => {
const entity = { type: graphType.Measure, data: {}};
mapShape[el.code] = newShape(entity, graphType.Measure, el);
}, this);
// 报警
zrUtil.each(data.warningList||[], el => {
const entity = { type: graphType.Warning, data: {}};
mapShape[el.code] = newShape(entity, graphType.Warning, el);
}, this);
// 投切按钮
zrUtil.each(data.switchingList||[], el => {
const entity = { type: graphType.Switching, data: {}};
mapShape[el.code] = newShape(entity, graphType.Switching, el);
}, this);
// 弹窗按钮
zrUtil.each(data.popupList||[], el => {
const entity = { type: graphType.Popup, data: {}};
mapShape[el.code] = newShape(entity, graphType.Popup, el);
}, this);
// 程制按钮
zrUtil.each(data.programControlList||[], el => {
const entity = { type: graphType.ProgramControl, data: {}};
mapShape[el.code] = newShape(entity, graphType.ProgramControl, el);
}, this);
// Pid按钮
zrUtil.each(data.pidList||[], el => {
const entity = { type: graphType.Pid, data: {}};
mapShape[el.code] = newShape(entity, graphType.Pid, el);
}, this);
}
} catch (error) {
console.error('[ERROR] ', error);
}
return mapShape;
}
// 处理依赖关系
export function analysis (state) {
const mapLink = state.mapLink || {}; // 关联关系
const mapEntity = state.mapEntity || {}; // 实体数据
const mapShape = state.mapShape || {}; // 绘图code数据
const mapDependency = {};
function push(set, model) {
set.add(model.code);
}
function complateSelf(model, entity) {
if (entity && entity.code) {
let dependency = mapDependency[entity.code];
if (!dependency) dependency = mapDependency[entity.code] = {};
if (!dependency['Self']) dependency['Self'] = new Set();
push(dependency['Self'], model);
}
}
function complateDependency(model, entity) {
if (entity && entity.code) {
let dependency = mapDependency[entity.code];
if (!dependency) dependency = mapDependency[entity.code] = {};
if (!dependency[model._type]) dependency[model._type] = new Set();
push(dependency[model._type], model);
}
}
try {
Object.values(mapShape).forEach(({model}) => {
const link = utils.getLinkByModel(mapLink, model) || {}; // link关系
const entity = utils.getEntityByModel(mapEntity, mapLink, model) || {}; // 实体数据
if (mapEntity[link.code] && !link.hasOwnProperty('prop')) { // 排查计量 设置为 self
complateSelf(model, entity);
}
if ([graphType.Resource].includes(model._type)) {
const attrList = entity.attrList;
const attrObj = utils.getObjInListBySign(attrList, 'deviceCode');
if (attrObj && attrObj.value) {
const entity = mapEntity[attrObj.value] || {};
complateDependency(model, entity);
}
} else if (link.code && link.hasOwnProperty('prop')) {
const entity = mapEntity[link.code]||{};
complateDependency(model, entity);
}
});
} catch (error) {
console.error(`[ERROR] `, error);
}
return mapDependency;
}
// 更新绘图原始组列表数据
export function update2List(model, map, name) {
const list = map[name];
if (list && list instanceof Array) {
const i = list.findIndex(elem => { return elem.code == model.code; });
if (model._dispose) {
i >= 0 && list.splice(i, 1);
} else if (!list[i]) {
list.push(model);
} else {
Object.assign(list[i], model);
}
} else {
map[name] = [model];
}
}
// 更新绘图的数据
export function updateData(state, model) {
const map = state.map;
if (map && model) {
switch (model._type) {
case graphType.Text: update2List(model, map, 'textList'); break;
case graphType.Button: update2List(model, map, 'buttonList'); break;
case graphType.Table: update2List(model, map, 'tableList'); break;
case graphType.Table1: update2List(model, map, 'table1List'); break;
case graphType.Resource: update2List(model, map, 'resourceList'); break;
case graphType.LinePipe: update2List(model, map, 'linePipeList'); break;
case graphType.Measure: update2List(model, map, 'measureList'); break;
case graphType.Warning: update2List(model, map, 'warningList'); break;
case graphType.Switching: update2List(model, map, 'switchingList'); break;
case graphType.Popup: update2List(model, map, 'popupList'); break;
case graphType.ProgramControl: update2List(model, map, 'programControlList'); break;
case graphType.Pid: update2List(model, map, 'pidList'); break;
}
}
}

View File

@ -0,0 +1,195 @@
import * as zrUtil from 'zrender/src/core/util';
import * as utils from '../utils/utils';
import panelType from '../constant/panelType';
import panelRender from '../constant/panelRender';
import panelStyle from '../config/panelStyle';
// 创建一个Shape结构
export function newShape(entity, type, model) {
return { model: Object.assign(model, panelRender[type], {entity}), style: panelStyle, instance: null, hover: null, dragging: false, draw: false };
}
// 解析绘图原始数据
export function parse(state, data, isDraw) {
const mapLink = state.mapLink;
const mapEntity = state.mapEntity;
const mapShape = {};
try {
if (data) {
// 文字
zrUtil.each(data.textList||[], el => {
const entity = { type: 'Text', data: {}};
mapShape[el.code] = newShape(entity, panelType.Text, el);
}, this);
// 按钮
zrUtil.each(data.buttonList||[], el => {
const entity = { type: 'Button', data: {}};
mapShape[el.code] = newShape(entity, panelType.Button, el);
}, this);
// 表
zrUtil.each(data.tableList||[], el => {
const entity = { type: 'Table', data: {}};
mapShape[el.code] = newShape(entity, panelType.Table, el);
}, this);
// 资源
zrUtil.each(data.resourceList||[], el => {
const link = utils.getLinkByModel(mapLink, {...el, _type: panelType.Resource})||{};
const entity = isDraw
? mapEntity[link.code]||{}
: mapEntity[link.code] = { code: link.code, type: link.type, data: {}};
mapShape[el.code] = newShape(entity, panelType.Resource, el);
}, this);
// 管线
zrUtil.each(data.linePipeList||[], el => {
const link = utils.getLinkByModel(mapLink, {...el, _type: panelType.LinePipe})||{};
const entity = isDraw
? mapEntity[link.code]||{}
: mapEntity[link.code] = { code: link.code, type: 'Pipe', data: {}};
mapShape[el.code] = newShape(entity, panelType.LinePipe, el);
}, this);
// 计量
zrUtil.each(data.measureList||[], el => {
const entity = { type: panelType.Measure, data: {}};
mapShape[el.code] = newShape(entity, panelType.Measure, el);
}, this);
// 报警
zrUtil.each(data.warningList||[], el => {
const entity = { type: panelType.Warning, data: {}};
mapShape[el.code] = newShape(entity, panelType.Warning, el);
}, this);
// 投切按钮
zrUtil.each(data.switchingList||[], el => {
const entity = { type: panelType.Switching, data: {}};
mapShape[el.code] = newShape(entity, panelType.Switching, el);
}, this);
// 弹窗按钮
zrUtil.each(data.popupList||[], el => {
const entity = { type: panelType.Popup, data: {}};
mapShape[el.code] = newShape(entity, panelType.Popup, el);
}, this);
// 程制按钮
zrUtil.each(data.programControlList||[], el => {
const entity = { type: panelType.ProgramControl, data: {}};
mapShape[el.code] = newShape(entity, panelType.ProgramControl, el);
}, this);
// Pid按钮
zrUtil.each(data.pidList||[], el => {
const entity = { type: panelType.Pid, data: {}};
mapShape[el.code] = newShape(entity, panelType.Pid, el);
}, this);
}
} catch (error) {
console.error('[ERROR] ', error);
}
return mapShape;
}
// 分析依赖关系
export function analysis (state) {
const mapLink = state.mapLink||{};
const mapEntity = state.mapEntity||{};
const mapShape = state.mapShape||{};
const mapDependency = {};
function push(set, model) {
set.add(model.code);
}
function complateSelf(model, entity) {
if (entity &&
entity.code) {
let dependency = mapDependency[entity.code];
if (!dependency) dependency = mapDependency[entity.code] = {};
if (!dependency['Self']) dependency['Self'] = new Set();
push(dependency['Self'], model);
}
}
function complateDependency(model, entity) {
if (entity &&
entity.code) {
let dependency = mapDependency[entity.code];
if (!dependency) dependency = mapDependency[entity.code] = {};
if (!dependency[model._type]) dependency[model._type] = new Set();
push(dependency[model._type], model);
}
}
try {
Object.values(mapShape).forEach(({model}) => {
const link = utils.getLinkByModel(mapLink, model)||{};
const entity = utils.getEntityByModel(mapEntity, mapLink, model)||{};
if (mapEntity[link.code] && !link.hasOwnProperty('prop')) {
complateSelf(model, entity);
}
if ([panelType.Resource].includes(model._type)) {
const attrList = entity.attrList;
const attrObj = utils.getObjInListBySign(attrList, 'deviceCode');
if (attrObj && attrObj.value) {
const entity = mapEntity[attrObj.value]||{};
complateDependency(model, entity);
}
} else if (link.code && link.hasOwnProperty('prop') ) {
const entity = mapEntity[link.code]||{};
complateDependency(model, entity);
}
});
} catch (error) {
console.error(`[ERROR] `, error);
}
return mapDependency;
}
// 更新绘图原始组列表数据
export function update2List(model, map, name) {
const list = map[name];
if (list && list instanceof Array) {
const i = list.findIndex(elem => { return elem.code == model.code; });
if (model._dispose) {
i >= 0 && list.splice(i, 1);
} else if (!list[i]) {
list.push(model);
} else {
Object.assign(list[i], model);
}
} else {
map[name] = [model];
}
}
// 更新绘图的数据
export function updateData(state, model) {
const map = state.map;
if (map && model) {
switch (model._type) {
case panelType.Text: update2List(model, map, 'textList'); break;
case panelType.Button: update2List(model, map, 'buttonList'); break;
case panelType.Table: update2List(model, map, 'tableList'); break;
case panelType.Resource: update2List(model, map, 'resourceList'); break;
case panelType.LinePipe: update2List(model, map, 'linePipeList'); break;
case panelType.Measure: update2List(model, map, 'measureList'); break;
case panelType.Warning: update2List(model, map, 'warningList'); break;
case panelType.Switching: update2List(model, map, 'switchingList'); break;
case panelType.Popup: update2List(model, map, 'popupList'); break;
case panelType.ProgramControl: update2List(model, map, 'programControlList'); break;
case panelType.Pid: update2List(model, map, 'pidList'); break;
}
}
}

View File

@ -0,0 +1,123 @@
import * as zrUtil from 'zrender/src/core/util';
import Graphic from '../package';
import * as utils from '../utils/utils';
import panelType from '../constant/panelType';
import resourceStyle from '../config/resourceStyle';
import resourceType from '../constant/resourceType';
import resourceRender from '../constant/resourceRender';
import Vue from 'vue';
// 创建一个Shape结构
export function newShape(entity, type, model) {
return { model: Object.assign(model, resourceRender[type], {entity}), style: resourceStyle, instance: null, hover: null, dragging: false, draw: false };
}
// 创建一个图形
export function newGraph(type, model, base) {
const clonedModel = utils.deepClone(model);
clonedModel.point.x += base.point.x;
clonedModel.point.y += base.point.y;
clonedModel.origin = base.origin;
clonedModel.rotation = base.rotation;
clonedModel.scale = base.scale;
clonedModel.parentTag = base.parentTag;
clonedModel.layer = base.layer+10;
clonedModel.attrList = base.attrList;
clonedModel.dialog = base.dialog;
const builder = Graphic.getBuilder(type); // 根据 type 绘制 面板,资源,画面对应的 instance
return builder(Vue.prototype.$map.getPainter(), newShape({}, type, clonedModel), {is: true});
}
export function parse(state, data, isDraw) {
const mapDevice = {};
try {
if (data) {
if (!data.background) {
data.background = { code: utils.getUID('Resource'), url: '', width: 200, height: 200, point: { x: 0, y: 0 } };
}
mapDevice[data.background.code] = newShape({}, resourceType.Background, Object.assign(data.background, {scale: [1, 1]}) );
zrUtil.each(data.buttonList||[], elem => {
mapDevice[elem.code] = newShape({}, resourceType.Button, Object.assign(elem, {scale: [1, 1]}));
}, this);
zrUtil.each(data.displayList||[], elem => {
mapDevice[elem.code] = newShape({}, resourceType.Display, Object.assign(elem, {scale: [1, 1]}));
}, this);
zrUtil.each(data.pilotLampList||[], elem => {
mapDevice[elem.code] = newShape({}, resourceType.PilotLamp, Object.assign(elem, {scale: [1, 1]}));
}, this);
zrUtil.each(data.textList||[], elem => {
mapDevice[elem.code] = newShape({}, resourceType.Text, Object.assign(elem, {scale: [1, 1]}));
}, this);
}
} catch (error) {
console.log(error);
}
return mapDevice;
}
export function generator(data, base, draw) {
const elMap = {};
try {
if (data) {
if (data.background) {
data.background._silent = true;
elMap[resourceType.Background] = newGraph(resourceType.Background, data.background, base, draw);
}
elMap[resourceType.Button] = [];
zrUtil.each(data.buttonList||[], elem => {
elMap[resourceType.Button].push(newGraph(resourceType.Button, elem, base, draw));
}, this);
elMap[resourceType.Display] = [];
zrUtil.each(data.displayList||[], elem => {
elMap[resourceType.Display].push(newGraph(resourceType.Display, elem, base, draw));
}, this);
elMap[resourceType.PilotLamp] = [];
zrUtil.each(data.pilotLampList||[], elem => {
elMap[resourceType.PilotLamp].push(newGraph(resourceType.PilotLamp, elem, base, draw));
}, this);
}
} catch (error) {
console.log(error);
}
return elMap;
}
export function update2List(model, map, name) {
const list = map[name];
if (list && list instanceof Array) {
const i = list.findIndex(elem => { return elem.code == model.code; });
if (model._dispose) {
i >= 0 && list.splice(i, 1);
} else if (!list[i]) {
list.push(model);
} else {
Object.assign(list[i], model);
}
} else {
map[name] = [model];
}
}
export function updateData(state, model) {
const map = state.map;
if (map && model) {
switch (model._type) {
case resourceType[panelType.Resource].Button: update2List(model, map, 'buttonList'); break;
case resourceType[panelType.Resource].PilotLamp: update2List(model, map, 'pilotLampList'); break;
case resourceType[panelType.Resource].Display: update2List(model, map, 'displayList'); break;
}
}
}

View File

@ -0,0 +1,94 @@
import graphType from './constant/graphType';
import LineDraggable from './draggable/Line';
import ImageDraggable from './draggable/Image';
export default class SelectHandle {
constructor(map, controller) {
this.$map = map;
this.$zr = map.getZr();
this.$controller = controller;
this.$painter = map.getPainter();
this.e = {};
}
onSelected(e) {
if (e.target && e.target.instance) {
this.e = {...e };
if (['Control'].includes(this.$controller.getKeyStr())) {
if (this.$map.isHover(e.target.model.code)) {
this.delSelected(e.target);
} else {
this.addSelected(e.target);
}
} else if (this.$controller.storage.isSelectSelf(e.target.model.code)) {
this.addSelected(e.target);
} else {
this.clear();
this.addSelected(e.target);
}
}
}
addSelected(target) {
this.$controller.storage.set(target.model.code, target);
if (target.instance.doActive) {
target.instance.doActive(this.$zr);
}
if (!target.hover) {
target.hover = this.newHover(target);
this.$painter.addHoverElem(target.hover);
}
}
delSelected(target) {
if (target.instance.doInactive) {
target.instance.doInactive(this.$zr);
}
if (target.hover) {
this.$painter.delHoverElem(target.hover);
target.hover = null;
}
this.$controller.storage.delete(target.model.code);
}
clear() {
this.$controller.storage.values().forEach(target => {
this.delSelected(target);
});
}
setDraggable(draggable) {
const target = this.e.target;
if (target && target.hover) {
target.hover.setDraggable(draggable);
}
}
newHover(target) {
if (this.$map.draggle) {
switch (target.model._type) {
case graphType.LinePipe:
return new LineDraggable(this);
case graphType.Resource:
return new ImageDraggable(this);
}
}
}
render(list) {
this.$map.render(list);
}
normalizedDiff(x, y) {
const options = this.$map.getOptions();
const dx = x / options.scaleRate;
const dy = y / options.scaleRate;
return [dx, dy];
}
}

View File

@ -0,0 +1,82 @@
import * as graphic from './graph/graphic.js';
export default class SelectingHandle {
constructor(map, controller) {
this.$map = map;
this.$zr = map.getZr();
this.$controller = controller;
this.$painter = map.getPainter();
this.begPoint = null;
this.endPoint = null;
this.hover = new graphic.Rect({
_subType: 'selectingEl',
zlevel: 999,
shape: {
x: 0,
y: 0,
width: 0,
height: 0
},
style: {
lineWidth: 0,
stroke: '#000',
fill: 'rgba(200,200,200,0.3)'
}
});
}
isSelecting() {
return this.begPoint;
}
onSelectStart(e) {
// console.log(e, '左键点击');
this.hover.setShape({ x: e.x, y: e.y, width: 0, height: 0 });
this.$painter.addHoverElem(this.hover);
this.begPoint = { x: e.x, y: e.y };
this.endPoint = null;
}
onSelecting(e) {
// console.log(e, '移动');
this.endPoint = { x: e.x, y: e.y };
this.hover.setShape(this.normalizedArea(this.begPoint, this.endPoint));
this.$painter.addHoverElem(this.hover);
}
onSelectEnd(e) {
// console.log(e, '鼠标抬起');
this.endPoint = { x: e.x, y: e.y };
this.hover.setShape(this.normalizedArea(this.begPoint, this.endPoint));
this.$painter.addHoverElem(this.hover);
const hoverRect = this.hover.getBoundingRect();
Object.values(this.$map.getMapShape()).forEach(elem => {
if (!elem.model._silent && elem.instance && hoverRect.intersect(elem.instance.getBoundingRect())) {
this.setSelected(elem);
}
});
this.clear();
this.begPoint = this.endPoint = null;
}
setSelected(target) {
target.instance.doActive(this.$zr);
this.$controller.storage.set(target.model.code, target);
}
clear() {
this.$painter.delHoverElem(this.hover);
}
normalizedArea(begin, end) {
const options = this.$map.getOptions();
const x = (begin.x + options.offsetX) / options.scaleRate;
const y = (begin.y + options.offsetY) / options.scaleRate;
const width = (end.x - begin.x) / options.scaleRate;
const height = (end.y - begin.y) / options.scaleRate;
return {x, y, width, height};
}
}

View File

@ -0,0 +1,52 @@
import graphType from './constant/graphType';
import panelType from './constant/panelType';
// 状态处理器
export default class StateHandle {
constructor(map) {
this.$map = map;
}
update(state) {
const rootState = this.$map.getState(); // 获取 store.state
this.updateState(rootState, state); // 处理实体关联绘图数据
this.updateDepState(rootState, state); // 处理关联数据
}
updateState({mapShape}, state) {
const mapDependency = this.$map.getMapDependency(); // 依赖关系集合
const dependency = mapDependency[state.code]||{};
(dependency.Self||[]).forEach(code => {
this.__update2Self(mapShape[code], state);
});
}
updateDepState({mapShape}, state) {
const mapDependency = this.$map.getMapDependency();
const dependency = mapDependency[state.code]||{};
const mapper = {
[graphType.Measure]: this.__update2Measure,
[panelType.Measure]: this.__update2Measure
};
[...Object.values(graphType), ...Object.values(panelType)].forEach(type => {
const depList = dependency[type]||[];
depList.forEach(code => {
const funcCb = mapper[type];
if (funcCb) {
funcCb.call(this, mapShape[code], state);
}
});
});
}
__update2Self({instance, model}, state) {
Object.assign(model.entity, state);
instance.setState(model);
}
__update2Measure({instance, model}, state) {
const link = this.$map.getLinkByModel(model)||{};
Object.assign(model.entity, {data: {value: state.data[link.prop]}});
instance.setState(model);
}
}

View File

@ -0,0 +1,180 @@
import store from '@/store';
import zrender from 'zrender';
import * as utils from '../utils/utils';
import Eventful from 'zrender/src/mixin/Eventful';
import resourceType from '../constant/resourceType';
import ConstConfig from '@/scripts/ConstConfig';
import { generator } from '../parser/parser-resource';
const renderer = 'canvas';
const devicePixelRatio = 1;
export default class SubMap extends Eventful {
constructor(map) {
super();
this.$map = map;
this.storageMap = {};
this.cacheMap = {};
}
__updateDevice(list) {
list.forEach(el => {
const storage = this.storageMap[el.code];
const cache = (storage || {}).cache;
if (storage && cache) {
cache.update(utils.initModelState(storage.model, {}));
}
});
}
register(opts) {
if (opts.dom) {
const width = opts.dom.clientWidth;
const height = opts.dom.clientHeight;
const canvasId = utils.getUID('canvas_');
const zr = zrender.init(opts.dom, { renderer, devicePixelRatio, width, height, ...utils.deepClone(opts.config || {}) });
const cache = { zr, update: null, layer: null };
opts.dom.setAttribute('canvasId', canvasId);
zr.dom.setAttribute('tabIndex', -1);
this.cacheMap[canvasId] = cache;
return cache;
}
}
appendDevice(cache, model, data) {
const x = 80;
const y = 20;
const layer = new zrender.Group({ name: '__shapes__' });
const elMap = generator(data.graphData||{}, { ...model, point: { x, y }, scale: 1, dialog: true }, false);
cache.zr.clear();
cache.zr.add(layer);
cache.layer = layer;
cache.update = function (state) {
if (model && elMap && state) {
const els = Object.values(elMap);
utils.setModelState(model, state);
(function setState(el) {
if (el instanceof Array) {
el.forEach(it => { setState(it); });
} else {
el.setState(model);
el.dirty();
}
})(els);
}
};
Object.values(elMap).forEach(el => {
if (el instanceof Array) {
el.forEach(it => { layer.add(it); });
} else if (el instanceof Object) {
layer.add(el);
}
});
layer.dirty();
this.on(`update-${model.code}`, cache.update);
this.bindEvent(elMap, model);
this.storageMap[model.code] = { model, elMap, cache };
cache.update(utils.initModelState(model, {}));
}
bindEvent(elMap, model) {
const buttonList = elMap[resourceType.Button] || [];
const displayList = elMap[resourceType.Display] || [];
const attrObj = utils.getObjFormListBySign(model.attrList, 'deviceCode') || {};
if (attrObj.val) {
const related = store.getters['map/getDeviceByCode'](attrObj.val);
displayList.forEach(display => {
buttonList.forEach(button => {
button.on('click', e => {
const control = model.control || {};
if (!control.disabled) {
const operation = {
type: ConstConfig.ConstMap.TipsTrigger.SubMap.value,
code: `${button._val}`,
params: `${model.code}`
};
store.dispatch('training/next', operation).then(({ valid }) => {
if (valid) {
store.dispatch('menuOperation/handleBreakFlag', { break: true });
display.execute(button._device.model.event, { ...e, target: button });
display.dirty();
}
});
}
});
});
display.on('updaterelated', state => {
if (related) {
utils.setModelState(related.model, state);
store.dispatch('training/updateState', [related.model]);
}
});
display.on('updateself', state => {
const device = store.getters['map/getDeviceByCode'](model.code);
if (device.instance) {
utils.setModelState(model, state);
device.instance.setState(model);
}
});
});
}
}
traversed(map, cb) {
Object.values(map).forEach(el => {
if (el) {
if (el instanceof Array) {
this.traversed(el, cb);
} else {
cb(el);
}
}
});
}
dispose(cache) {
if (cache && cache.zr) {
const canvasId = cache.zr.dom.canvasId;
delete this.cacheMap[canvasId];
this.off('update', cache.update);
cache.update = null;
cache.zr.dispose();
cache.zr = null;
}
}
getViewTipsPoint(step) {
const storage = this.storageMap[step.params];
if (storage) {
let point = null;
const dom = storage.cache.zr.dom;
this.traversed(storage.elMap, el => {
if (el._val == step.code) {
point = el.getViewTipsPoint(utils.getDomOffset(dom));
}
});
return point;
}
}
}

View File

@ -0,0 +1,72 @@
import * as graphic from './graph/graphic';
import Eventful from 'zrender/src/mixin/Eventful';
export default class TipsHandle extends Eventful {
constructor(map) {
super();
this.map = map;
this.message = new graphic.Text({
zlevel: 1,
z: 99,
silent: true,
style: {
x: 0,
y: 0,
fontSize: 16,
fontWeight: 'normal',
textBackgroundColor: '#feffc8',
text: 'aaa',
textFill: '#000',
textPadding: [7, 14],
textAlign: 'left',
textVerticalAlign: 'bottom',
textBorderColor: '#666666',
textBorderWidth: 0,
textBorderRadius: 4,
textLineHeight: 22,
textBoxShadowColor: 'rgba(0,0,0,.3)',
textBoxShadowOffsetX: 0,
textBoxShadowOffsetY: 1,
textBoxShadowBlur: 3,
opacity: 0.8
}
});
this.on('show', this.onShow, this);
this.on('hide', this.onHide, this);
}
onShow(e) {
const {x, y, text} = e;
const painter = this.map.getPainter();
const options = this.map.getOptions();
const level = painter.getTipsLevel();
const scaleRate = options.scaleRate || 1;
const offsetX = options.offsetX || 0;
const offsetY = options.offsetY || 0;
const newX = parseInt((x + offsetX) / scaleRate);
const newY = parseInt((y + offsetY) / scaleRate);
this.message.setStyle({x: newX, y: newY, text});
if (level) {
level.add(this.message);
painter.$transformHandle.transformView(this.message);
}
}
onHide(e) {
const painter = this.map.getPainter();
const level = painter.getTipsLevel();
if (level) {
level.remove(this.message);
}
this.message.setStyle('text', '');
}
dispose() {
this.off('show', this.onShow);
this.off('hide', this.onHide);
}
}

View File

@ -0,0 +1,80 @@
import * as utils from './utils/utils';
class TransformHandle {
constructor(painter) {
this.$painter = painter;
this.parentLevel = painter.getParentLevel();
this.rect = { x: 0, y: 0, width: 0, height: 0 };
this.transform = utils.createTransform({ scaleRate: 1, offsetX: 0, offsetY: 0 });
}
getTransform() {
return this.transform;
}
checkVisible(view) {
return utils.createBoundingRect(view).intersect(this.rect);
}
revisibleView(view) {
let visible = false;
if (this.checkVisible(view)) {
view.show();
visible = true;
} else {
view.hide();
visible = false;
}
if (view._code) {
this.$painter.doHover(view, visible);
}
view.dirty();
}
// 视图进行缩放/平移
transformView(view) {
if (view) {
view.transform = this.transform;
view.decomposeTransform();
this.revisibleView(view);
}
}
// 处理所有视图缩放/平移
transformAll() {
this.traverse(this.transformView, this);
}
// 重新计算显示图形
revisibleAll() {
this.traverse(this.revisibleView, this);
}
// 更新偏移量
updateTransform(opts) {
this.transform = utils.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;

View File

@ -0,0 +1,5 @@
export default class Caches extends Map {
constructor(opts) {
super();
}
}

View File

@ -0,0 +1,64 @@
export default class Storage {
constructor() {
this.map = new Map();
this.lst = new Set();
this.clipboard = [];
}
has(code) {
return code ? this.map.has(code) : false;
}
set(code, target) {
if (!this.has(code)) {
this.lst.add(code);
this.map.set(code, target);
}
}
get(code) {
return this.map.get(code);
}
delete(code) {
// debugger;
if (this.has(code)) {
this.map.delete(code);
this.lst.delete(code);
}
}
values() {
return Array.from(this.lst).map(code => { return this.get(code); });
}
clear() {
this.lst.clear();
this.map.clear();
}
isSelectSelf(code) {
return this.has(code);
}
setClipboard(lst) {
this.clipboard = Array.from(lst);
}
clearClipboard() {
this.clipboard = [];
}
getClipboard() {
return this.clipboard;
}
getClipboardSize() {
return this.clipboard.length;
}
forEach() {
return this.map.forEach;
}
}

17
src/iscs_new/utils/dom.js Normal file
View File

@ -0,0 +1,17 @@
export function isDom(dom) {
return typeof dom === 'object' &&
typeof dom.nodeType === 'number' &&
typeof dom.ownerDocument === 'object';
}
export function setAttribute(dom, key, value) {
dom.setAttribute
? dom.setAttribute(key, value)
: (dom[key] = value);
}
export function getAttribute(dom, key) {
return dom.getAttribute
? dom.getAttribute(key)
: dom[key];
}

View File

@ -0,0 +1,29 @@
import * as matrix from 'zrender/src/core/matrix';
// 对图形进行scale/rotation/position变化
export function transformed(shape, {scale, rotation, position}) {
let transform = matrix.create();
if (scale) {
transform = matrix.scale(matrix.create(), transform, scale);
}
if (rotation) {
transform = matrix.rotate(matrix.create(), transform, rotation);
}
if (position) {
transform = matrix.translate(matrix.create(), transform, position);
}
if (shape) {
if (origin) {
shape.attr(origin, origin);
}
shape.transform = transform;
shape.decomposeTransform();
}
return shape;
}

342
src/iscs_new/utils/utils.js Normal file
View File

@ -0,0 +1,342 @@
import * as matrix from 'zrender/src/core/matrix';
import * as color from 'zrender/src/tool/color';
import BoundingRect from 'zrender/src/core/BoundingRect';
var base = 0;
// 获取一个UID
export function getUID(type) {
return [(type || ''), base++, Math.random().toFixed(5)].join('_');
}
// 判断一个图形是否是svg
export function shapeIsSvg(shape) {
return shape.type == 'Svg';
}
// 判断一个url是否svg路径
export function urlIsSvg(url) {
return !/.png$/i.test(url);
}
export function isExistFile(url, draw) {
if (draw) {
try {
let xmlHttp;
if (window.ActiveXObject) {
xmlHttp = new window.ActiveXObject('Microsoft.XMLHTTP');
} else if (window.XMLHttpRequest) {
xmlHttp = new window.XMLHttpRequest();
}
xmlHttp.open('get', url, false);
xmlHttp.send();
if (xmlHttp.readyState == 4) {
if (xmlHttp.status == 200) return true;
else if (xmlHttp.status == 404) return false;
else return false;
}
return false;
} catch (e) {
return false;
}
}
return true;
}
// 根据url重新获取url路径或者Svg内容
export function getResourceUrl(relatedUrl) {
const url = `${process.env.VUE_APP_BASE_RESOURCE_URL}${relatedUrl}`;
const isSvg = /.svg$/i.test(url);
if (isSvg) {
let xmlHttp;
if (window.ActiveXObject) {
xmlHttp = new window.ActiveXObject('Microsoft.XMLHTTP');
} else if (window.XMLHttpRequest) {
xmlHttp = new window.XMLHttpRequest();
}
xmlHttp.open('get', url, false);
xmlHttp.send();
if (xmlHttp.readyState==4) {
if (xmlHttp.status==200) return xmlHttp.response.replace(/.*<path\s*d="(.*)"\s*\/>.*/, '$1');
}
}
return url;
}
export function getObjFormListBySign(list, sign) {
if (list && list.length) {
return list[list.findIndex(el => { return el.sign == sign; })];
}
}
export function initModelState(model, state, blocks=['data', 'contorl']) {
blocks.forEach(block => {
state[block] = {...model[block]||{}};
});
return state;
}
export function exBoundingRect(rt, padding) {
const rect = new BoundingRect(rt.x, rt.y, rt.width, rt.height);
rect.x -= padding;
rect.y -= padding;
rect.width += padding*2;
rect.height += padding*2;
return rect;
}
// 判断Url路径是否存在
export function isExistUrl(relatedUrl, draw) {
if (draw) {
try {
let xmlHttp;
const url = `${process.env.VUE_APP_BASE_RESOURCE_URL}${relatedUrl}`;
if (window.ActiveXObject) {
xmlHttp = new window.ActiveXObject('Microsoft.XMLHTTP');
} else if (window.XMLHttpRequest) {
xmlHttp = new window.XMLHttpRequest();
}
xmlHttp.open('get', url, false);
xmlHttp.send();
if (xmlHttp.readyState==4) {
if (xmlHttp.status==200) return true;
else if (xmlHttp.status==404) return false;
else return false;
}
return false;
} catch (e) {
return false;
}
}
return true;
}
// clone一个对象
export function deepClone(obj) {
var tag = Array.isArray(obj) ? [] : {};
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
if (Array.isArray(obj[key])) {
tag[key] = JSON.parse(JSON.stringify({data: obj[key]})).data;
} else if (typeof obj[key] === 'object' && obj[key] !== null) {
tag[key] = deepClone(obj[key]);
} else {
tag[key] = obj[key];
}
}
}
return tag;
}
// 以clone的方式copy一个对象到另一个对象
export function deepAssign(tag, obj) {
return Object.assign(tag, deepClone(obj));
}
// 拷贝对象指定层次的引用
export function assignByDeep(source, target, deep) {
Object.keys(target).forEach(key => {
if (deep) {
Object.keys(target).forEach(key => {
source[key] = assignByDeep(source[key]||{}, target[key]||{}, deep-1);
});
} else {
source[key] = target[key];
}
});
return source;
}
// 代理一个线条重新计算偏移中心
export function lineProxy(shape, origin, point) {
const dx = point.x - origin.x;
const dy = point.y - origin.y;
const dz = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
shape.attr('origin', [origin.x, origin.y]);
shape.attr('rotation', -Math.atan2(dy, dx),);
shape.setShape({
points: [
[origin.x, origin.y],
[origin.x+dz, origin.y]
]
});
return shape;
}
// 创建一个transform
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().clone();
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, bound) {
var dx = (bound.width - viewRect.width) / 2 - viewRect.x;
var dy = (bound.height - viewRect.height) / 2 - viewRect.y;
return { dx, dy };
}
export function setModelState(model, state) {
Object.keys(state).forEach(block => {
model[block] = {...model[block]||{}, ...state[block]};
});
return model;
}
// 更新point指定x/y的偏移值
export function updatePointDi(point, prop, di) {
let list = point;
if (!(point instanceof Array)) {
list = [point];
}
if (list && list.length) {
list.forEach(el => {
if (el.point) {
el.point[prop] += di;
}
if (el.points) {
el.points.forEach(point => {
point[prop] += di;
});
}
});
}
}
// 通过sceneType获取资源画面
export function getSceneBySceneType(resource, sceneType) {
return (resource.sceneMap||{})[sceneType]||{};
}
// 通过sceneType获取绘图数据块
export function getBlockBySceneType(model, sceneType) {
const index = model.sceneTypes.findIndex(el => { return el == sceneType; });
return index >= 0? model.graphList[index]||null: null;
}
// 在list中通过指定sign获取节点obj
export function getObjInListBySign(list, sign) {
if (list && list.length) {
return list[list.findIndex(el => { return el.sign == sign; })];
}
}
// 通过Model获取link关系
export function getLinkByModel(mapLink, model) {
const type = model._type == 'measure' ? 'measure' : 'device'; // 转换key
return mapLink ? (mapLink[type]||{})[model.code] : {};
}
// 通过Model获取实体
export function getEntityByModel(mapEntity, mapLink, model) {
const link = getLinkByModel(mapLink, model)||{};
return mapEntity[link.code];
}
export function getDomOffset(dom) {
let pol = 0;
let pot = 0;
let offsetLeft = 0;
let offsetTop = 0;
while (dom) {
if (pol != dom.offsetLeft) {
offsetLeft += dom.offsetLeft;
pol = dom.offsetLeft;
}
if (pot != dom.offsetTop) {
offsetTop += dom.offsetTop;
pot = dom.offsetTop;
}
dom = dom.offsetParent;
}
const offset = {
x: offsetLeft,
y: offsetTop
};
return offset;
}
// 矩形碰撞检测
export function checkRectCollision(rect1, rect2) {
const center1 = { x: rect1.point.x + rect1.width / 2, y: rect1.point.y + rect1.height / 2 };
const center2 = { x: rect2.point.x + rect2.width / 2, y: rect2.point.y + rect2.height / 2 };
if (
// 横向判断 和 纵向判断
Math.abs(center1.x - center2.x) < rect1.width / 2 + rect2.width / 2 &&
Math.abs(center1.y - center2.y) < rect1.height / 2 + rect2.height / 2
) {
return true;
}
return false;
}
// 通过两点计算弧度
export function getRadian(point1, point2) {
return Math.atan2(point2.y-point1.y, point2.x-point1.x);
}
// 类型检测
const cehckJsType = (type) => { return (obj) => { return Object.prototype.toString.call(obj) === `[object ${type.name}]`; }; };
export function isFunction() { return cehckJsType(Function); }
export function isArray() { return cehckJsType(Array); }
export function isString() { return cehckJsType(String); }
export function isInstanceOf(obj, targt) {
return obj instanceof targt;
}
export function isMobile() {
var sUserAgent= navigator.userAgent.toLowerCase();
var bIsIpad= sUserAgent.match(/ipad/i) == 'ipad';
var bIsIphoneOs= sUserAgent.match(/iphone os/i) == 'iphone os';
var bIsMidp= sUserAgent.match(/midp/i) == 'midp';
var bIsUc7= sUserAgent.match(/rv:1.2.3.4/i) == 'rv:1.2.3.4';
var bIsUc= sUserAgent.match(/ucweb/i) == 'ucweb';
var bIsAndroid= sUserAgent.match(/android/i) == 'android';
var bIsCE= sUserAgent.match(/windows ce/i) == 'windows ce';
var bIsWM= sUserAgent.match(/windows mobile/i) == 'windows mobile';
// var bIsWebview = sUserAgent.match(/webview/i) == 'webview';
return (bIsIpad || bIsIphoneOs || bIsMidp || bIsUc7 || bIsUc || bIsAndroid || bIsCE || bIsWM);
}
export function handleColor(source, target, distance = 200) {
const rgbSource = [];
const rgbTarget = [];
color.parse(source, rgbSource);
color.parse(target, rgbTarget);
const diffArr = rgbTarget.map((el, i) => { return el- rgbSource[i]; });
const sum = diffArr.slice(0, 3).reduce((s, el) => s + (el*el), 0);
return Math.sqrt(sum)<distance;
}