2019-07-08 09:38:39 +08:00
|
|
|
import * as zrUtil from 'zrender/src/core/util';
|
2019-07-09 19:04:45 +08:00
|
|
|
import zrender from 'zrender';
|
2019-07-03 14:29:09 +08:00
|
|
|
import Painter from './painter';
|
2019-07-10 12:02:02 +08:00
|
|
|
import Options from './options';
|
2019-07-03 14:29:09 +08:00
|
|
|
import ProxyHandle from './proxyHandle';
|
2019-07-09 19:04:45 +08:00
|
|
|
import MouseController from './mouseController';
|
2019-07-03 18:41:00 +08:00
|
|
|
import deviceState from './config/deviceState';
|
2019-07-04 09:20:51 +08:00
|
|
|
import deviceStyle from './config/deviceStyle';
|
2019-07-04 18:39:30 +08:00
|
|
|
import deviceType from './config/deviceType';
|
|
|
|
import { parser, deviceFactory } from './utils/parser';
|
2019-07-03 14:29:09 +08:00
|
|
|
|
2019-07-09 19:04:45 +08:00
|
|
|
const renderer = 'canvas';
|
|
|
|
const devicePixelRatio = 2;
|
|
|
|
|
2019-07-03 14:29:09 +08:00
|
|
|
class Jmap {
|
2019-07-04 10:59:40 +08:00
|
|
|
constructor(opts) {
|
2019-07-09 09:24:54 +08:00
|
|
|
// 回调事件
|
|
|
|
this.methods = opts.methods;
|
|
|
|
|
2019-07-10 12:02:02 +08:00
|
|
|
// 鼠标事件
|
|
|
|
this.Events = { Pan: 'pan', Zoom: 'zoom', Selected: 'selected', Contextmenu: 'contextmenu' };
|
|
|
|
|
2019-07-04 10:59:40 +08:00
|
|
|
// 原始数据
|
|
|
|
this.data = {};
|
2019-07-03 14:29:09 +08:00
|
|
|
|
2019-07-04 10:59:40 +08:00
|
|
|
// 皮肤参数
|
|
|
|
this.skinStyle = '';
|
2019-07-03 14:29:09 +08:00
|
|
|
|
2019-07-04 10:59:40 +08:00
|
|
|
// 皮肤风格
|
|
|
|
this.styleDict = {};
|
2019-07-03 14:29:09 +08:00
|
|
|
|
2019-07-04 10:59:40 +08:00
|
|
|
// 设备数据
|
|
|
|
this.mapDevice = {};
|
2019-07-03 14:29:09 +08:00
|
|
|
|
2019-07-09 19:04:45 +08:00
|
|
|
// 代理数据
|
2019-07-04 10:59:40 +08:00
|
|
|
this.proxyData = {};
|
2019-07-03 14:29:09 +08:00
|
|
|
|
2019-07-10 13:17:12 +08:00
|
|
|
// 默认状态
|
|
|
|
this.defaultStateDict = this.loadDefaultState();
|
|
|
|
|
2019-07-10 12:02:02 +08:00
|
|
|
this.initMapInstance(opts);
|
|
|
|
}
|
|
|
|
|
|
|
|
initMapInstance(opts) {
|
2019-07-10 13:17:12 +08:00
|
|
|
let width = opts.dom.clientWidth;
|
|
|
|
let height = opts.dom.clientHeight;
|
2019-07-10 12:02:02 +08:00
|
|
|
|
2019-07-10 13:17:12 +08:00
|
|
|
this.$zr = zrender.init(opts.dom, Object.assign({ renderer, devicePixelRatio, width, height }, opts.config));
|
2019-07-10 12:02:02 +08:00
|
|
|
|
2019-07-10 13:17:12 +08:00
|
|
|
this.$options = new Options(Object.assign({ scaleRate: 1, offsetX: 0, offsetY: 0, }, opts.options || {}));
|
2019-07-09 19:04:45 +08:00
|
|
|
|
2019-07-10 13:17:12 +08:00
|
|
|
this.$painter = new Painter(this);
|
|
|
|
this.$painter.updateZoomTransform(this.$options);
|
2019-07-10 12:02:02 +08:00
|
|
|
|
2019-07-10 13:17:12 +08:00
|
|
|
this.$mouseController = new MouseController(this);
|
|
|
|
this.$mouseController.enable();
|
2019-07-10 12:02:02 +08:00
|
|
|
|
2019-07-10 13:17:12 +08:00
|
|
|
this.$optionsHandler = this.setOptions.bind(this);
|
|
|
|
this.$mouseController.on(this.Events.Pan, this.$optionsHandler);
|
|
|
|
this.$mouseController.on(this.Events.Zoom, this.$optionsHandler);
|
2019-07-04 10:59:40 +08:00
|
|
|
}
|
2019-07-03 14:29:09 +08:00
|
|
|
|
2019-07-04 10:59:40 +08:00
|
|
|
loadData(skinStyle, data) {
|
2019-07-09 19:04:45 +08:00
|
|
|
// 保存皮肤类型
|
|
|
|
this.skinStyle = skinStyle;
|
|
|
|
|
2019-07-04 10:59:40 +08:00
|
|
|
// 保存原始数据
|
|
|
|
this.data = data;
|
|
|
|
|
2019-07-04 11:00:52 +08:00
|
|
|
// 加载皮肤
|
|
|
|
this.styleDict = this.loadStyle(skinStyle);
|
|
|
|
|
2019-07-04 10:59:40 +08:00
|
|
|
// 解析地图数据
|
|
|
|
this.mapDevice = parser(data, this.defaultStateDict);
|
|
|
|
|
|
|
|
// 生成代理对象
|
2019-07-10 13:17:12 +08:00
|
|
|
this.proxyData = new Proxy(this.mapDevice, new ProxyHandle(this.$painter));
|
2019-07-04 10:59:40 +08:00
|
|
|
|
2019-07-09 19:04:45 +08:00
|
|
|
// 数据加载完成回调
|
|
|
|
(this.methods.dataLoaded instanceof Function) && this.methods.dataLoaded();
|
2019-07-08 09:38:39 +08:00
|
|
|
|
2019-07-04 10:59:40 +08:00
|
|
|
// 初次渲染视图
|
2019-07-10 13:17:12 +08:00
|
|
|
this.$painter.repaint(this.mapDevice, this.styleDict);
|
2019-07-08 09:38:39 +08:00
|
|
|
|
2019-07-09 19:04:45 +08:00
|
|
|
// 视图渲染完成回调
|
|
|
|
(this.methods.viewLoaded instanceof Function) && this.methods.viewLoaded();
|
2019-07-04 11:00:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
loadStyle(skinStyle) {
|
|
|
|
return deviceStyle;
|
2019-07-04 10:59:40 +08:00
|
|
|
}
|
|
|
|
|
2019-07-09 19:04:45 +08:00
|
|
|
loadDefaultState() {
|
2019-07-04 10:59:40 +08:00
|
|
|
const defaultStateDict = {};
|
|
|
|
|
2019-07-08 09:38:39 +08:00
|
|
|
zrUtil.each(Object.keys(deviceState), (type) => {
|
2019-07-04 10:59:40 +08:00
|
|
|
defaultStateDict[type] = {};
|
2019-07-08 09:38:39 +08:00
|
|
|
zrUtil.each(Object.keys(deviceState[type] || {}), (state) => {
|
2019-07-04 10:59:40 +08:00
|
|
|
defaultStateDict[type][state] = deviceState[type][state].Default;
|
2019-07-08 09:38:39 +08:00
|
|
|
})
|
|
|
|
})
|
2019-07-04 10:59:40 +08:00
|
|
|
|
|
|
|
return defaultStateDict;
|
|
|
|
}
|
|
|
|
|
2019-07-09 19:04:45 +08:00
|
|
|
setDefaultState() {
|
|
|
|
let list = [];
|
|
|
|
|
|
|
|
Object.values(this.mapDevice).forEach(elem => {
|
|
|
|
let code = elem._code;
|
|
|
|
let type = elem._type;
|
|
|
|
list.push(Object.assign({ code, type }, this.defaultStateDict[type]));
|
|
|
|
})
|
|
|
|
|
|
|
|
this.update(list);
|
|
|
|
}
|
|
|
|
|
2019-07-04 18:39:30 +08:00
|
|
|
syncData(model) {
|
|
|
|
let code = model.code;
|
|
|
|
let type = model.type;
|
2019-07-05 00:40:53 +08:00
|
|
|
let dispose = model._dispose;
|
2019-07-04 18:39:30 +08:00
|
|
|
|
|
|
|
let prop = null;
|
|
|
|
switch (type) {
|
|
|
|
case deviceType.Link: prop = 'linkList'; break;
|
|
|
|
}
|
|
|
|
|
|
|
|
let list = this.data[prop];
|
|
|
|
if (list) {
|
|
|
|
let idex = list.findIndex(elem => { return elem.code == code });
|
|
|
|
if (idex >= 0) {
|
2019-07-05 00:40:53 +08:00
|
|
|
dispose && list.splice(idex, 1);
|
2019-07-04 18:39:30 +08:00
|
|
|
} else {
|
|
|
|
list.push(model);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
render(list) {
|
|
|
|
(list || []).forEach(elem => {
|
|
|
|
let type = elem.type;
|
|
|
|
let code = elem.code;
|
|
|
|
let device = this.proxyData[code] || deviceFactory(type, this.styleDict[type], elem);
|
|
|
|
let model = Object.assign(device.model || {}, elem);
|
|
|
|
delete this.proxyData[code];
|
|
|
|
if (!elem._dispose) {
|
|
|
|
device = this.proxyData[code] = Object.assign(device, { model });
|
|
|
|
}
|
|
|
|
|
2019-07-09 19:04:45 +08:00
|
|
|
this.syncData(model);
|
2019-07-04 18:39:30 +08:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
update(list) {
|
|
|
|
(list || []).forEach(elem => {
|
|
|
|
let code = elem.code;
|
|
|
|
if (elem._dispose) {
|
|
|
|
delete this.proxyData[code];
|
|
|
|
} else {
|
|
|
|
let device = this.proxyData[code] || {};
|
|
|
|
let state = Object.assign(device.state || {}, elem);
|
|
|
|
this.proxyData[code] = Object.assign(device, { state });
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2019-07-10 12:02:02 +08:00
|
|
|
setOptions(zoom) {
|
2019-07-10 13:17:12 +08:00
|
|
|
this.$options.update(zoom);
|
|
|
|
this.$painter.updateZoomTransform(this.$options);
|
2019-07-10 12:02:02 +08:00
|
|
|
}
|
|
|
|
|
2019-07-09 19:04:45 +08:00
|
|
|
getZr() {
|
2019-07-10 13:17:12 +08:00
|
|
|
return this.$zr;
|
2019-07-09 19:04:45 +08:00
|
|
|
}
|
|
|
|
|
2019-07-04 10:59:40 +08:00
|
|
|
getPainter() {
|
2019-07-10 13:17:12 +08:00
|
|
|
return this.$painter;
|
2019-07-09 19:04:45 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
getEvents() {
|
2019-07-10 12:02:02 +08:00
|
|
|
return this.Events;
|
2019-07-04 10:59:40 +08:00
|
|
|
}
|
|
|
|
|
2019-07-04 18:39:30 +08:00
|
|
|
getSkinStyle() {
|
|
|
|
return this.skinStyle;
|
|
|
|
}
|
|
|
|
|
|
|
|
getStyleDict() {
|
|
|
|
return this.styleDict;
|
|
|
|
}
|
|
|
|
|
|
|
|
getDefaultStateDict() {
|
|
|
|
return this.defaultStateDict;
|
|
|
|
}
|
|
|
|
|
|
|
|
getMapDevice() {
|
|
|
|
return this.mapDevice;
|
|
|
|
}
|
|
|
|
|
2019-07-10 12:02:02 +08:00
|
|
|
on(eventname, cb, context) {
|
|
|
|
let idx = Object.values(this.Events).indexOf(eventname);
|
|
|
|
if (idx >= 0) {
|
|
|
|
switch (eventname) {
|
|
|
|
case this.Events.Selected: {
|
2019-07-10 13:17:12 +08:00
|
|
|
this.$mouseController.on(this.Events.Selected, cb, context);
|
2019-07-10 12:02:02 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case this.Events.Contextmenu: {
|
2019-07-10 13:17:12 +08:00
|
|
|
this.$mouseController.on(this.Events.Contextmenu, cb, context);
|
2019-07-10 12:02:02 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
off(eventname, cb) {
|
|
|
|
let idx = Object.values(this.Events).indexOf(eventname);
|
|
|
|
if (idx >= 0) {
|
|
|
|
switch (eventname) {
|
|
|
|
case this.Events.Selected: {
|
2019-07-10 13:17:12 +08:00
|
|
|
this.$mouseController.off(this.Events.Selected, cb);
|
2019-07-10 12:02:02 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case this.Events.Contextmenu: {
|
2019-07-10 13:17:12 +08:00
|
|
|
this.$mouseController.off(this.Events.Contextmenu, cb);
|
2019-07-10 12:02:02 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-04 18:39:30 +08:00
|
|
|
refresh() {
|
2019-07-10 13:17:12 +08:00
|
|
|
this.$painter.refresh();
|
2019-07-04 18:39:30 +08:00
|
|
|
}
|
|
|
|
|
2019-07-04 10:59:40 +08:00
|
|
|
clear() {
|
2019-07-10 13:17:12 +08:00
|
|
|
this.$painter.clear();
|
2019-07-04 10:59:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
dispose() {
|
2019-07-10 13:17:12 +08:00
|
|
|
this.off(this.Events.Pan, this.$optionsHandler);
|
|
|
|
this.off(this.Events.Zoom, this.$optionsHandler);
|
2019-07-04 10:59:40 +08:00
|
|
|
this.skinStyle = '';
|
|
|
|
this.styleDict = {};
|
|
|
|
this.mapDevice = {};
|
|
|
|
this.proxyData = {};
|
2019-07-10 13:17:12 +08:00
|
|
|
this.$zr && zrender.dispose(this.$zr);
|
|
|
|
this.$painter.dispose();
|
2019-07-04 10:59:40 +08:00
|
|
|
}
|
2019-07-03 14:29:09 +08:00
|
|
|
}
|
|
|
|
|
2019-07-04 10:59:40 +08:00
|
|
|
export default Jmap;
|