import * as zrUtil from 'zrender/src/core/util'; import zrender from 'zrender'; import Painter from './painter'; import Options from './options'; import ProxyHandle from './proxyHandle'; import MouseController from './mouseController'; import deviceState from './config/deviceState'; import deviceStyle from './config/deviceStyle'; import deviceType from './config/deviceType'; import { parser, deviceFactory } from './utils/parser'; const renderer = 'canvas'; const devicePixelRatio = 2; class Jmap { constructor(opts) { // 回调事件 this.methods = opts.methods; // 鼠标事件 this.Events = { Pan: 'pan', Zoom: 'zoom', Selected: 'selected', Contextmenu: 'contextmenu' }; // 原始数据 this.data = {}; // 皮肤参数 this.skinStyle = ''; // 皮肤风格 this.styleDict = {}; // 设备数据 this.mapDevice = {}; // 代理数据 this.proxyData = {}; // 默认状态 this.defaultStateDict = this.loadDefaultState(); this.initMapInstance(opts); } initMapInstance(opts) { let width = opts.dom.clientWidth; let height = opts.dom.clientHeight; this.$zr = 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.$painter = new Painter(this); this.$painter.updateZoomTransform(this.$options); this.$mouseController = new MouseController(this); this.$mouseController.enable(); this.$optionsHandler = this.setOptions.bind(this); this.$mouseController.on(this.Events.Pan, this.$optionsHandler); this.$mouseController.on(this.Events.Zoom, this.$optionsHandler); } loadData(data) { // 保存皮肤类型 this.skinStyle = data.skinStyle; // 保存原始数据 this.data = data; // 加载皮肤 this.styleDict = this.loadStyle(this.skinStyle); // 解析地图数据 this.mapDevice = parser(data, this.defaultStateDict); // 生成代理对象 this.proxyData = new Proxy(this.mapDevice, new ProxyHandle(this.$painter)); // 数据加载完成回调 (this.methods.dataLoaded instanceof Function) && this.methods.dataLoaded(); // 初次渲染视图 this.$painter.repaint(this.mapDevice, this.styleDict); // 视图渲染完成回调 (this.methods.viewLoaded instanceof Function) && this.methods.viewLoaded(); } loadStyle(skinStyle) { return deviceStyle; } loadDefaultState() { const defaultStateDict = {}; zrUtil.each(Object.keys(deviceState), (type) => { defaultStateDict[type] = {}; zrUtil.each(Object.keys(deviceState[type] || {}), (state) => { defaultStateDict[type][state] = deviceState[type][state].Default; }) }) return defaultStateDict; } 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); } setOptions(zoom) { this.$options.update(zoom); this.$painter.updateZoomTransform(this.$options); } syncData(model) { let code = model.code; let type = model.type; let dispose = model._dispose; 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) { dispose && list.splice(idex, 1); } 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 }); } this.syncData(model); }) } 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 }); } }) } getZr() { return this.$zr; } getPainter() { return this.$painter; } getEvents() { return this.Events; } getSkinStyle() { return this.skinStyle; } getStyleDict() { return this.styleDict; } getDefaultStateDict() { return this.defaultStateDict; } getMapDevice() { return this.mapDevice; } on(eventname, cb, context) { let 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; } } } } off(eventname, cb) { let 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; } } } } refresh() { this.$painter.refresh(); } clear() { this.$painter.clear(); } dispose() { this.off(this.Events.Pan, this.$optionsHandler); this.off(this.Events.Zoom, this.$optionsHandler); this.skinStyle = ''; this.styleDict = {}; this.mapDevice = {}; this.proxyData = {}; this.$zr && zrender.dispose(this.$zr); this.$painter.dispose(); } } export default Jmap;