328 lines
10 KiB
JavaScript
328 lines
10 KiB
JavaScript
|
import zrender from 'zrender';
|
||
|
// import * as zrUtil from 'zrender/src/core/util';
|
||
|
import localStore from 'storejs';
|
||
|
import Options from './options';
|
||
|
import MouseController from './mouseController';
|
||
|
import Painter from './painter';
|
||
|
import deviceType from './constant/deviceType';
|
||
|
import {calculateDCenter, createBoundingRect, deviceFactory} from './utils/parser';
|
||
|
import { updateIbpData } from './utils/parser';
|
||
|
|
||
|
const renderer = 'canvas';
|
||
|
const devicePixelRatio = 1;
|
||
|
|
||
|
class IbpPan {
|
||
|
constructor(opts) {
|
||
|
this.methods = opts.methods;
|
||
|
|
||
|
// 鼠标事件
|
||
|
this.events = { __Pan: 'pan', Selected: 'selected', Contextmenu: 'contextmenu'};
|
||
|
|
||
|
// 设备数据
|
||
|
this.ibpDevice = {};
|
||
|
|
||
|
// 展示的画布大小
|
||
|
this.canvasSize = {};
|
||
|
|
||
|
this.initIbpPage(opts);
|
||
|
}
|
||
|
initIbpPage(opts) {
|
||
|
const width = opts.config.width;
|
||
|
const height = opts.config.height;
|
||
|
this.isAllowDragging = false;
|
||
|
this.$ibpZr = zrender.init(opts.dom, Object.assign({ renderer, devicePixelRatio, width, height }, opts.config));
|
||
|
this.$options = new Options(Object.assign({ scaleRate: 1, offsetX: 0, offsetY: 0 }, opts.options || {})); // 缩放
|
||
|
this.$mouseController = new MouseController(this);
|
||
|
|
||
|
this.$mouseController.enable();
|
||
|
|
||
|
this.$painter = new Painter(this);
|
||
|
this.$painter.updateZrSize({width: this.$ibpZr.getWidth(), height: this.$ibpZr.getHeight()});
|
||
|
this.$painter.updateTransform(this.$options, this.canvasSize);
|
||
|
|
||
|
this.optionsHandler = this.setOptions.bind(this);
|
||
|
|
||
|
this.$mouseController.on(this.events.__Pan, this.optionsHandler);
|
||
|
}
|
||
|
|
||
|
setIbp(config, ibpDevice) {
|
||
|
// 保存平移缩放数据
|
||
|
if (config.config) {
|
||
|
this.$options.scaleRate = config.scaling;
|
||
|
this.$options.offsetX = config.origin.x;
|
||
|
this.$options.offsetY = config.origin.y;
|
||
|
}
|
||
|
|
||
|
// 保存原始数据
|
||
|
this.data = config;
|
||
|
|
||
|
// 保存需展现的画布大小
|
||
|
this.canvasSize = {
|
||
|
x: 0,
|
||
|
y: 0,
|
||
|
width: config.background.width,
|
||
|
height: config.background.height
|
||
|
};
|
||
|
|
||
|
// 地图数据
|
||
|
this.ibpDevice = ibpDevice;
|
||
|
|
||
|
// 数据加载完成 回调
|
||
|
if (this.methods.dataLoaded instanceof Function) { this.methods.dataLoaded(this.ibpDevice); }
|
||
|
|
||
|
// 初次渲染视图
|
||
|
this.$painter.repaint(this.ibpDevice);
|
||
|
|
||
|
// 视图加载完成 回调
|
||
|
if (this.methods.viewLoaded instanceof Function) { this.methods.viewLoaded(this.ibpDevice); }
|
||
|
|
||
|
this.$painter.updateTransform(this.$options, this.canvasSize);
|
||
|
}
|
||
|
|
||
|
setDefaultState() {
|
||
|
const list = [];
|
||
|
Object.values(this.mapDevice).forEach(elem => {
|
||
|
const type = elem.model._type;
|
||
|
list.push(deviceFactory(type, Object.assign(elem.model, this.defaultStateDict[type]) ));
|
||
|
});
|
||
|
|
||
|
this.update(list);
|
||
|
if (this.methods.stateLoaded instanceof Function) { this.methods.stateLoaded(list); }
|
||
|
}
|
||
|
|
||
|
setOptions(opts) {
|
||
|
const options = this.pullBack(opts);
|
||
|
this.$options.update(options);
|
||
|
this.$painter.updateTransform(this.$options, this.canvasSize);
|
||
|
|
||
|
if (this.$options.disabled == true) {
|
||
|
this.$mouseController.disable();
|
||
|
} else {
|
||
|
this.$mouseController.enable(opts);
|
||
|
}
|
||
|
|
||
|
if (this.methods.optionsUpdate instanceof Function) { this.methods.optionsUpdate(this.$options); }
|
||
|
}
|
||
|
|
||
|
setCenter(deviceCode) {
|
||
|
const device = this.ibpDevice[deviceCode];
|
||
|
if (device && device.instance) {
|
||
|
var rect = createBoundingRect(device.instance);
|
||
|
var dcenter = calculateDCenter(rect, { width: this.$ibpZr.getWidth(), height: this.$ibpZr.getHeight() });
|
||
|
this.setOptions(dcenter);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
setLevelVisible(list) {
|
||
|
this.$painter.setLevelVisible(list);
|
||
|
}
|
||
|
|
||
|
render(list) {
|
||
|
(list || []).forEach(elem => {
|
||
|
const code = elem.code;
|
||
|
const type = elem._type;
|
||
|
if (type === deviceType.Background) {
|
||
|
this.canvasSize = {
|
||
|
x: 0,
|
||
|
y: 0,
|
||
|
width: elem.width,
|
||
|
height: elem.height
|
||
|
};
|
||
|
}
|
||
|
updateIbpData(elem);
|
||
|
const oDevice = this.ibpDevice[code] || deviceFactory(type, elem);
|
||
|
const nDevice = deviceFactory(type, Object.assign(oDevice.model || {}, elem));
|
||
|
delete this.ibpDevice[code];
|
||
|
this.$painter.delete(oDevice);
|
||
|
if (!elem._dispose) {
|
||
|
this.ibpDevice[code] = nDevice;
|
||
|
this.$painter.add(nDevice);
|
||
|
}
|
||
|
});
|
||
|
if (this.methods.viewUpdate instanceof Function) { this.methods.viewUpdate(list); }
|
||
|
}
|
||
|
|
||
|
// 中间处理
|
||
|
hookHandle(model, elem) {
|
||
|
const code = elem.code;
|
||
|
const type = elem._type;
|
||
|
// 如果是延时计时,需要保存计数值到全局
|
||
|
if (type === deviceType.StationCounter) {
|
||
|
let val = '' + elem.val;
|
||
|
if (val === '0' || !elem.val) {
|
||
|
val = elem.val = localStore.get(code) || '0';
|
||
|
}
|
||
|
|
||
|
localStore(code, val);
|
||
|
}
|
||
|
for (var prop in elem) {
|
||
|
if (elem[prop] != model[prop]) {
|
||
|
Object.assign(model, elem);
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
update(list) {
|
||
|
(list || []).forEach(elem => {
|
||
|
const code = elem.code;
|
||
|
const oDevice = this.ibpDevice[code];
|
||
|
if (elem.dispose) {
|
||
|
this.$painter.delete(oDevice);
|
||
|
} else {
|
||
|
if (this.hookHandle(oDevice.model, elem)) {
|
||
|
this.$painter.update(oDevice);
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
|
||
|
if (this.methods.stateUpdate instanceof Function) { this.methods.stateUpdate(list); }
|
||
|
}
|
||
|
setStatus(code, model) {
|
||
|
const oDevcie = this.ibpDevice[code].instance;
|
||
|
oDevcie.setStatus(model);
|
||
|
}
|
||
|
setDeviceStatus(list) {
|
||
|
const deviceList = Object.values(this.ibpDevice);
|
||
|
deviceList.forEach(elem =>{
|
||
|
(list || []).forEach(it =>{
|
||
|
if (elem.model.linkDevice === it.code) {
|
||
|
elem.instance.setStatus(it);
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
|
||
|
}
|
||
|
drawIbpInit() {
|
||
|
this.$mouseController.setAllowDragging(true);
|
||
|
}
|
||
|
|
||
|
pullBack(payload) {
|
||
|
if (payload.type === 'zoom') {
|
||
|
const zrWidth = this.$ibpZr.getWidth();
|
||
|
const zrHeight = this.$ibpZr.getHeight();
|
||
|
const originX = payload.originX || zrWidth / 2;
|
||
|
const originY = payload.originY || zrHeight / 2;
|
||
|
const x = (this.$options.offsetX + originX) / this.$options.scaleRate;
|
||
|
const y = (this.$options.offsetY + originY) / this.$options.scaleRate;
|
||
|
const newScaleRate = this.$options.getScaleRate(payload.scale);
|
||
|
const dx = originX - (x * newScaleRate - this.$options.offsetX);
|
||
|
const dy = originY - (y * newScaleRate - this.$options.offsetY);
|
||
|
payload.dx = dx;
|
||
|
payload.dy = dy;
|
||
|
}
|
||
|
|
||
|
return payload || {};
|
||
|
}
|
||
|
|
||
|
getZr() {
|
||
|
return this.$ibpZr;
|
||
|
}
|
||
|
|
||
|
getEvents() {
|
||
|
return this.events;
|
||
|
}
|
||
|
|
||
|
getDeviceByCode(code) {
|
||
|
return this.ibpDevice[code];
|
||
|
}
|
||
|
|
||
|
resize(opt) {
|
||
|
this.$ibpZr.resize(opt);
|
||
|
this.$painter.updateZrSize(opt);
|
||
|
}
|
||
|
|
||
|
refresh() {
|
||
|
this.$painter.refresh();
|
||
|
}
|
||
|
clear() {
|
||
|
this.skinCode = '';
|
||
|
this.style = {};
|
||
|
this.ibpDevice = {};
|
||
|
this.$painter.clear();
|
||
|
}
|
||
|
initClockTime(initTime) {
|
||
|
Object.values(this.ibpDevice)
|
||
|
.forEach(elem => {
|
||
|
if (elem.model._type === deviceType.Clock) {
|
||
|
this.$painter.initClockTime(elem, initTime);
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
setClockStart(started) {
|
||
|
Object.values(this.ibpDevice)
|
||
|
.forEach(elem => {
|
||
|
if (elem.model._type === deviceType.Clock) {
|
||
|
this.$painter.setClockStart(elem, started);
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
dispose() {
|
||
|
this.off(this.events.Pan, this.optionsHandler);
|
||
|
this.off(this.events.Zoom, this.optionsHandler);
|
||
|
|
||
|
this.clear();
|
||
|
|
||
|
this.$mouseController.dispose();
|
||
|
this.$ibpZr && zrender.dispose(this.$ibpZr);
|
||
|
this.$painter.dispose();
|
||
|
}
|
||
|
|
||
|
on(eventname, cb, context) {
|
||
|
const idx = Object.values(this.events).indexOf(eventname);
|
||
|
if (idx >= 0) {
|
||
|
switch (eventname) {
|
||
|
case this.events.Selected:
|
||
|
this.$mouseController.on(this.events.Selected, cb, context);
|
||
|
break;
|
||
|
case this.events.Contextmenu:
|
||
|
this.$mouseController.on(this.events.Contextmenu, cb, context);
|
||
|
break;
|
||
|
case this.events.DataZoom:
|
||
|
this.$mouseController.on(this.events.DataZoom, cb, context);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
off(eventname, cb) {
|
||
|
const idx = Object.values(this.events).indexOf(eventname);
|
||
|
if (idx >= 0) {
|
||
|
switch (eventname) {
|
||
|
case this.events.Selected:
|
||
|
this.$mouseController.off(this.events.Selected, cb);
|
||
|
break;
|
||
|
case this.events.Contextmenu:
|
||
|
this.$mouseController.off(this.events.Contextmenu, cb);
|
||
|
break;
|
||
|
case this.events.DataZoom:
|
||
|
this.$mouseController.off(this.events.DataZoom, cb);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
renderCheckBox(model) {
|
||
|
const type = model._type;
|
||
|
const code = model.code;
|
||
|
const oDevice = this.ibpDevice[code] || deviceFactory(type, model);
|
||
|
const nDevice = deviceFactory(type, Object.assign(oDevice.model || {}, model));
|
||
|
delete this.ibpDevice[code];
|
||
|
this.$painter.delete(oDevice);
|
||
|
if (!model._dispose) {
|
||
|
this.ibpDevice[code] = nDevice;
|
||
|
this.$painter.add(nDevice);
|
||
|
}
|
||
|
}
|
||
|
deleteCheckBox(code) {
|
||
|
const oDevice = this.ibpDevice[code];
|
||
|
if (oDevice) {
|
||
|
delete this.ibpDevice[code];
|
||
|
this.$painter.delete(oDevice);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
export default IbpPan;
|