一、编写EchartsLayer类实现注入到window对象,实现类如下:
import * as Cesium from 'cesium/Cesium' import * as echarts from 'echarts' !(function () { function EchartsLayer(viewer) { this._viewer = viewer; registerMap(this); createChart(this); resize(this); } Object.defineProperties(EchartsLayer.prototype, { chart: { get: function () { return this._chart; } } }) function registerMap(layer) { if (!Cesium.defined(echarts)) { throw new Cesium.DeveloperError("echarts is undefined."); } echarts.registerCoordinateSystem("GLMap", getCoordinateSystem(layer._viewer)), echarts.registerAction({ type: "GLMapRoam", event: "GLMapRoam", update: "updateLayout" }, function (t, e) { }), echarts.extendComponentModel({ type: "GLMap", defaultOption: {roam: !1} }); echarts.extendComponentView({ type: "GLMap", init: function (t, e) { this.api = e; layer._viewer.scene.postRender.addEventListener(this.moveHandler, this) }, moveHandler: function (t, e) { this.api.dispatchAction({ type: "GLMapRoam" }); }, render: function (t, e, i) { }, dispose: function (t) { layer._viewer.scene.postRender.removeEventListener(this.moveHandler, this) } }); } function createChart(layer) { var scene = layer._viewer.scene; scene.canvas.setAttribute("tabIndex", 0); var ele = document.createElement('div'); ele.style.position = "absolute"; ele.style.top = "0px"; ele.style.left = "0px"; ele.style.width = scene.canvas.width + "px"; ele.style.height = scene.canvas.height + "px"; ele.style.pointerEvents = "none"; ele.setAttribute("id", "echarts"); ele.setAttribute("class", "echartMap"); layer._viewer.container.appendChild(ele); layer._echartsContainer = ele; layer._chart = echarts.init(ele); } function resize(layer) { window.onresize = function () { var scene = layer._viewer.scene; layer._echartsContainer.style.width = scene.canvas.style.width + "px"; layer._echartsContainer.style.height = scene.canvas.style.height + "px"; layer._chart.resize(); } } EchartsLayer.prototype.isDestroyed = function () { return false; }; EchartsLayer.prototype.destroy = function () { if (this._echartsContainer) { this._viewer.container.removeChild(this._echartsContainer); this._echartsContainer = undefined; } if (this._chart) { this._chart.dispose(); this._chart = undefined; } Cesium.destroyObject(this); } function getCoordinateSystem(viewer) { function GLMapCoordSys(api) { this.dimensions = ['lng', 'lat']; this._mapOffset = [0, 0]; this._api = api; this._viewer = viewer; this._occluder = new Cesium.EllipsoidalOccluder(this._viewer.scene.globe.ellipsoid, this._viewer.scene.camera.position); } GLMapCoordSys.prototype.dimensions = ['lng', 'lat'] GLMapCoordSys.prototype.setMapOffset = function (mapOffset) { this._mapOffset = mapOffset; }; GLMapCoordSys.prototype.dataToPoint = function (data) { var e = [0, 0], i = Cesium.Cartesian3.fromDegrees(data[0], data[1]); if (!i) return e; this._occluder.cameraPosition = this._viewer.scene.camera.position; if(!this._occluder.isPointVisible(i)) { return []; }; var n = viewer.scene.cartesianToCanvasCoordinates(i); if (!n) return e; return (Cesium.Cartesian3.angleBetween(viewer.scene.camera.position, i) < Cesium.Math.toRadians(75)) ? [n.x - this._mapOffset[0], n.y - this._mapOffset[1]] : e; } GLMapCoordSys.prototype.pointToData = function (pt) { var mapOffset = this._mapOffset; var cart = viewer.scene.pickPosition( new Cartesian2(pt[0] + mapOffset[0], pt[1] + mapOffset[1]), new Cesium.Cartesian3() ); var carto = Cesium.Cartographic.fromCartesian(cart); return [Cesium.Math.toDegrees(carto.longitude), Cesium.Math.toDegrees(carto.latitude)]; } GLMapCoordSys.prototype.getViewRect = function () { var api = this._api return new echarts.graphic.BoundingRect(0, 0, api.getWidth(), api.getHeight()) } GLMapCoordSys.prototype.getRoamTransform = function () { return echarts.matrix.create(); } GLMapCoordSys.dimensions = GLMapCoordSys.prototype.dimensions GLMapCoordSys.create = function (ecModel, api) { var coordSys; ecModel.eachComponent('GLMap', function (GLMapModel) { coordSys = new GLMapCoordSys(api); coordSys.setMapOffset(GLMapModel.__mapOffset || [0, 0]); GLMapModel.coordinateSystem = coordSys; }) ecModel.eachSeries(function (seriesModel) { if (seriesModel.get('coordinateSystem') === 'GLMap') { seriesModel.coordinateSystem = coordSys; } }) } return GLMapCoordSys; } window.EchartsLayer = EchartsLayer; })();
二、编写调用工具类
/*** * echarts图层通用工具 * date:2022-04-15 * author:zdh * @type {EchartsLayerUtil} */ import './EchartsLayer' import * as Cesium from 'cesium/Cesium' let EchartsLayerUtil = (function () { function EchartsLayerUtil (ZJNCesium) { this.ZJNCesium = ZJNCesium this.transferLayer = null } EchartsLayerUtil.prototype.createTransferLayer = function (data,idField,labelField){ let geoCoordMap = data.geoCoordMap; let convertData = function (data) { let res = []; for (let i = 0; i < data.length; i++) { let dataItem = data[i]; let fromCoord = [parseFloat(geoCoordMap[dataItem[0][idField]][0]),parseFloat(geoCoordMap[dataItem[0][idField]][1])]; let toCoord = [parseFloat(geoCoordMap[dataItem[1][idField]][0]),parseFloat(geoCoordMap[dataItem[1][idField]][1])]; if (fromCoord && toCoord) { res.push({ fromName: dataItem[0][idField], toName: dataItem[1][idField], coords: [fromCoord, toCoord], value: 3, }); } } return res; } let series = []; data.resultData.forEach(function (item, i) { series.push( { coordinateSystem: 'GLMap', type: "effectScatter", symbolSize: 20, hoverAnimation: true, itemStyle: { color: "rgba(60,53,212,1)", borderColor: "rgba(60,53,212,0.4)", borderWidth: 10 }, data: [ { value: [parseFloat(geoCoordMap[item[0][0][idField]][0]),parseFloat(geoCoordMap[item[0][0][idField]][1])], itemStyle: { normal: { color: '#df27ba' } } } ], label: { normal: { show: true, position: 'right', //显示位置 offset: [5, 0], //偏移设置 formatter: function (params) { //圆环显示文字 return item[0][0][labelField]; }, fontWeight: 8, fontSize: 20, }, } }, { name: 'Top10', type: 'lines', coordinateSystem: 'GLMap', zlevel: 2, symbol: ['none','circle'], emphasis: { lineStyle: { color: 'rgb(255,255,108)', width: 6, }, }, tooltip: { formatter: '{b}', }, animation: false, symbolSize: 10, effect: { show: true, period: 4, //箭头指向速度,值越小速度越快 trailLength: 0.02, //特效尾迹长度[0,1]值越大,尾迹越长重 symbol: 'arrow', //箭头图标 symbolSize: 8, //图标大小 }, lineStyle: { normal: { color:'#eee', width: 1, //尾迹线条宽度 opacity: 1, //尾迹线条透明度 curveness: 0.3, //尾迹线条曲直度 }, }, data: convertData(item) } ) }) this.transferLayer = new EchartsLayer(this.ZJNCesium.viewer) let option = { // title: { // text: 'ArcGIS API for Javascript4.10扩展Echarts4之模拟迁徙', // subtext: 'Data from Echart社区,Develop By YANG', // left: 'center', // textStyle: { // color: '#fff' // } // }, animation: false, GLMap: {}, tooltip: { trigger: 'item' }, series: series }; this.transferLayer.chart.setOption(option) let handler = new Cesium.ScreenSpaceEventHandler(this.ZJNCesium.viewer.scene.canvas); handler.setInputAction(function (e) { let pos = this.ZJNCesium.viewer.scene.pickPosition(e.position); console.log(pos); }, Cesium.ScreenSpaceEventType.LEFT_CLICK); } return EchartsLayerUtil }()) export {EchartsLayerUtil}
三、测试数据整理
{ "geoCoordMap": { "cbbb669db45c4fe19ce9074bfb4cd1e8": [ 114.696074, 35.898948 ], "e3fb0b7892f74cff96f008567194d947": [ 110.768251, 33.990967 ], "f9dafa255b774af08003811e33c9de10": [ 115.367576, 33.399821 ], "53f3da71ab124333aff0ad35b915e6ac": [ 116.342632, 37.501695 ], "7e821d134dd64bc587f31ea73156bfc0": [ 116.360495, 34.836477 ], "b8d343de07304c4fb378db198febd45f": [ 117.440802, 34.944583 ], "81a5cd1eb9d04b92b0d955fc269b35fc": [ 115.767717, 35.702342 ], "8425a827de3e48548387ff0f92c62791": [ 115.783878, 34.308761 ] }, "resultData": [ [ [ { "entName": "王氏中医医院有限责任公司", "code": "cbbb669db45c4fe19ce9074bfb4cd1e8" }, { "entName": "汇楚危险废物处置有限公司", "code": "8425a827de3e48548387ff0f92c62791" } ] ], [ [ { "entName": "社区卫生服务中心", "code": "e3fb0b7892f74cff96f008567194d947" }, { "entName": "汇楚危险废物处置有限公司", "code": "8425a827de3e48548387ff0f92c62791" } ] ], [ [ { "entName": "济堂风湿病专科医院", "code": "f9dafa255b774af08003811e33c9de10" }, { "entName": "汇楚危险废物处置有限公司", "code": "8425a827de3e48548387ff0f92c62791" } ] ], [ [ { "entName": "红济中医医院", "code": "53f3da71ab124333aff0ad35b915e6ac" }, { "entName": "汇楚危险废物处置有限公司", "code": "8425a827de3e48548387ff0f92c62791" } ] ], [ [ { "entName": "温泉社区卫生服务中心", "code": "7e821d134dd64bc587f31ea73156bfc0" }, { "entName": "汇楚危险废物处置有限公司", "code": "8425a827de3e48548387ff0f92c62791" } ] ], [ [ { "entName": "温泉社区卫生服务中心", "code": "b8d343de07304c4fb378db198febd45f" }, { "entName": "汇楚危险废物处置有限公司", "code": "8425a827de3e48548387ff0f92c62791" } ] ], [ [ { "entName": "社区卫生服务中心", "code": "81a5cd1eb9d04b92b0d955fc269b35fc" }, { "entName": "汇楚危险废物处置有限公司", "code": "8425a827de3e48548387ff0f92c62791" } ] ] ] }
四、框架内配置加载信息
qxt:{ entities:[], isRLayerPanel: true, dataIdField: 'code', dataLabelField: 'entName', dataPath: '', options:{ id:'qxt', url: '/static/EchartsData/transferData.json', name:'迁徙图', isShow:true }, location: { "destination":{"x":-4739343.203207548,"y":10948294.24246299,"z":8769980.74531059}, "orientation":{"heading":6.230093908112224,"pitch":-1.567082607022392,"roll":0}, duration: 2 }, entityType:'EchartsQXT' }
五、框架内调用解析代码编写
if (layersInfo[layerId].entityType === "EchartsQXT") { if (ZJNCesium.echartsLayerUtil === null) { ZJNCesium.echartsLayerUtil = new EchartsLayerUtil(ZJNCesium) } let _this = ZJNCesium getMapData(layersInfo[layerId].options.url).then((res) => { if (layersInfo[layerId].dataPath != undefined && layersInfo[layerId].dataPath != "") { let dp = layersInfo[layerId].dataPath.split('/') for (let i = 0; i < dp.length; i++) { res = res[dp[i]] } } _this.echartsLayerUtil.createTransferLayer(res, layersInfo[layerId].dataIdField, layersInfo[layerId].dataLabelField) layersInfo[layerId].echartsLayer = _this.echartsLayerUtil.transferLayer if( layersInfo[layerId].options.isShow){ layersInfo[layerId].echartsLayer.chart.getDom().style.display = '' }else { layersInfo[layerId].echartsLayer.chart.getDom().style.display = 'none' } }); }
六、成果展示
感谢支持技术分享,请扫码点赞支持:
技术合作交流qq:2401315930