├── Echarts3Layer.js ├── Echarts3Layer3x.js ├── Echarts3Layer4x.js ├── LICENSE ├── README.md ├── echarts-gl.js ├── echarts.js ├── echarts.min.js ├── index.html └── src └── echartsLayer.js /Echarts3Layer.js: -------------------------------------------------------------------------------- 1 | define(["dojo/_base/declare","dojo/_base/lang","esri/geometry/Point","esri/geometry/ScreenPoint"],function(e,t,n,i){return e("Echarts3Layer",null,{name:"Echarts3Layer",_map:null,_ec:null,_geoCoord:[],_option:null,_mapOffset:[0,0],constructor:function(e,t){this._map=e;var n=this._echartsContainer=document.createElement("div");n.style.position="absolute",n.style.height=e.height+"px",n.style.width=e.width+"px",n.style.top=0,n.style.left=0,e.__container.appendChild(n),this._init(e,t)},_init:function(e,t){console.log('develop by wandergis');var o=this;o._map=e,o._ec=t,o.getEchartsContainer=function(){return o._echartsContainer},o.getMap=function(){return o._map},o.geoCoord2Pixel=function(e){var t=new n(e[0],e[1]),i=o._map.toScreen(t);return[i.x,i.y]},o.pixel2GeoCoord=function(e){var t=o._map.toMap(new i(e[0],e[1]));return[t.lng,t.lat]},o.initECharts=function(){return o._ec=t.init.apply(o,arguments),o._ec.Geo.prototype.dataToPoint=function(e){var t=new n(e[0],e[1]),i=o._map.toScreen(t);return[i.x,i.y]},o._bindEvent(),o._ec},o.getECharts=function(){return o._ec},o.setOption=function(e,t){o._option=e,o._ec.setOption(e,t)},o._bindEvent=function(){o._map.on("zoom-end",function(e){o._ec.resize(),o._echartsContainer.style.visibility="visible"}),o._map.on("zoom-start",function(e){o._echartsContainer.style.visibility="hidden"}),o._map.on("pan",function(e){o._echartsContainer.style.visibility="hidden"}),o._map.on("pan-end",function(e){o._ec.resize(),o._echartsContainer.style.visibility="visible"}),o._map.on("resize",function(){var e=o._echartsContainer.parentNode.parentNode.parentNode;o._mapOffset=[-parseInt(e.style.left)||0,-parseInt(e.style.top)||0],o._echartsContainer.style.left=o._mapOffset[0]+"px",o._echartsContainer.style.top=o._mapOffset[1]+"px",setTimeout(function(){o._map.resize(),o._map.reposition(),o._ec.resize()},200),o._echartsContainer.style.visibility="visible"}),o._ec.getZr().on("dragstart",function(e){}),o._ec.getZr().on("dragend",function(e){}),o._ec.getZr().on("mousewheel",function(e){o._lastMousePos=o._map.toMap(new i(e.event.x,e.event.y));var t=e.wheelDelta,n=o._map,a=n.getZoom();t=t>0?Math.ceil(t):Math.floor(t),t=Math.max(Math.min(t,4),-4),t=Math.max(n.getMinZoom(),Math.min(n.getMaxZoom(),a+t))-a,o._delta=0,o._startTime=null,t&&n.setZoom(a+t)})}}})}); -------------------------------------------------------------------------------- /Echarts3Layer3x.js: -------------------------------------------------------------------------------- 1 | define(["dojo/_base/declare", "dojo/_base/lang", "esri/geometry/Point", "esri/geometry/ScreenPoint"], function (declare, t, Point, ScreenPoint) { 2 | return declare("Echarts3Layer3x", null, { 3 | name: "Echarts3Layer3x", 4 | _map: null, 5 | _ec: null, 6 | _geoCoord: [], 7 | _option: null, 8 | _mapOffset: [0, 0], 9 | constructor: function (map, echartsObj) { 10 | this._map = map; 11 | var element = this._echartsContainer = document.createElement("div"); 12 | element.style.position = "absolute", 13 | element.style.height = map.height + "px", 14 | element.style.width = map.width + "px", 15 | element.style.top = 0, 16 | element.style.left = 0, 17 | map.__container.appendChild(element), 18 | this._init(map, echartsObj) 19 | }, 20 | _init: function (map, echartsObj) { 21 | console.log('develop by wandergis'); 22 | var _self = this; 23 | _self._map = map, 24 | _self._ec = echartsObj, 25 | _self.getEchartsContainer = function () { 26 | return _self._echartsContainer 27 | }, 28 | _self.getMap = function () { 29 | return _self._map 30 | }, 31 | _self.initECharts = function () { 32 | _self._ec = echartsObj.init.apply(_self, arguments); 33 | _self._ec.Geo.prototype.dataToPoint = function (e) { 34 | var pointTemp = new Point(e[0], e[1]), 35 | pointScreenObj = _self._map.toScreen(pointTemp); 36 | return [pointScreenObj.x, pointScreenObj.y] 37 | }; 38 | _self._bindEvent(); 39 | return _self._ec 40 | }, 41 | //_self.initECharts = function () { 42 | // return _self._ec = echartsObj.init.apply(_self, arguments), 43 | // _self._ec.Geo.prototype.dataToPoint = function (e) { 44 | // var pointTemp = new Point(e[0], e[1]), 45 | // pointScreenObj = _self._map.toScreen(pointTemp); 46 | // return [pointScreenObj.x, pointScreenObj.y] 47 | // }, 48 | // _self._bindEvent(), 49 | // _self._ec 50 | //}, 51 | _self.getECharts = function () { 52 | return _self._ec 53 | }, 54 | _self.setOption = function (e, t) { 55 | _self._option = e, 56 | _self._ec.setOption(e, t) 57 | }, 58 | _self._bindEvent = function () { 59 | _self._map.on("zoom-end", function (e) { 60 | _self._ec.resize(), 61 | _self._echartsContainer.style.visibility = "visible" 62 | }), 63 | _self._map.on("zoom-start", function (e) { 64 | _self._echartsContainer.style.visibility = "hidden" 65 | }), 66 | _self._map.on("pan", function (e) { 67 | _self._echartsContainer.style.visibility = "hidden" 68 | }), 69 | _self._map.on("pan-end", function (e) { 70 | _self._ec.resize(), _self._echartsContainer.style.visibility = "visible" 71 | }), 72 | _self._map.on("resize", function () { 73 | var e = _self._echartsContainer.parentNode.parentNode.parentNode; 74 | _self._mapOffset = [-parseInt(e.style.left) || 0, -parseInt(e.style.top) || 0], 75 | _self._echartsContainer.style.left = _self._mapOffset[0] + "px", 76 | _self._echartsContainer.style.top = _self._mapOffset[1] + "px", 77 | setTimeout(function () { 78 | _self._map.resize(), _self._map.reposition(), _self._ec.resize() 79 | }, 200), 80 | _self._echartsContainer.style.visibility = "visible" 81 | }), 82 | _self._ec.getZr().on("dragstart", function (e) { 83 | }), 84 | _self._ec.getZr().on("dragend", function (e) { 85 | }), 86 | _self._ec.getZr().on("mousewheel", function (e) { 87 | _self._lastMousePos = _self._map.toMap(new ScreenPoint(e.event.x, e.event.y)); 88 | var t = e.wheelDelta, 89 | mapTemp = _self._map, 90 | a = mapTemp.getZoom(); 91 | t = t > 0 ? Math.ceil(t) : Math.floor(t), t = Math.max(Math.min(t, 4), -4), t = Math.max(mapTemp.getMinZoom(), Math.min(mapTemp.getMaxZoom(), a + t)) - a, _self._delta = 0, _self._startTime = null, t && mapTemp.setZoom(a + t) 92 | }) 93 | } 94 | } 95 | }) 96 | }); -------------------------------------------------------------------------------- /Echarts3Layer4x.js: -------------------------------------------------------------------------------- 1 | define(["dojo/_base/declare", "dojo/_base/lang", 2 | "esri/geometry/support/webMercatorUtils", 3 | "esri/geometry/SpatialReference", 4 | "esri/geometry/Point", 5 | "esri/geometry/ScreenPoint"], function (declare, t, webMercatorUtils, SpatialReference,Point, ScreenPoint) { 6 | return declare("Echarts3Layer4x", null, { 7 | name: "Echarts3Layer4x", 8 | _view: null, 9 | _map: null, 10 | _ec: null, 11 | _geoCoord: [], 12 | _option: null, 13 | _mapOffset: [0, 0], 14 | constructor: function (view, echartsObj) { 15 | this._map = view.map; 16 | this._view = view; 17 | var element = this._echartsContainer = document.createElement("div"); 18 | element.style.position = "absolute"; 19 | element.style.height = view.height + "px"; 20 | element.style.width = view.width + "px"; 21 | element.style.top = 0; 22 | element.style.left = 0; 23 | element.style.pointerEvents = 'none'; 24 | 25 | view.container.appendChild(element); 26 | this._init(view, echartsObj); 27 | }, 28 | _init: function (view, echartsObj) { 29 | console.log('develop by wandergis'); 30 | var _self = this; 31 | _self._map = view.map, 32 | _self._view = view, 33 | _self._ec = echartsObj, 34 | _self.getEchartsContainer = function () { 35 | return _self._echartsContainer 36 | }, 37 | _self.getMap = function () { 38 | return _self._map 39 | }, 40 | _self.initECharts = function () { 41 | _self._ec = echartsObj.init.apply(_self, arguments); 42 | _self._ec.Geo.prototype.dataToPoint = function (e) { 43 | var pointTemp = new Point(e[0], e[1]); 44 | // var pointMercator = webMercatorUtils.lngLatToXY(pointTemp.longitude, pointTemp.latitude, true);//4.5还可以 45 | var pointMercator = webMercatorUtils.lngLatToXY(pointTemp.longitude, pointTemp.latitude);//4.7版本 46 | var pointFinal = new Point(pointMercator[0],pointMercator[1],new SpatialReference(102100)); 47 | var pointScreenObj = _self._view.toScreen(pointFinal); 48 | return [pointScreenObj.x, pointScreenObj.y] 49 | }; 50 | _self._bindEvent(); 51 | return _self._ec 52 | }, 53 | //_self.initECharts = function () { 54 | // return _self._ec = echartsObj.init.apply(_self, arguments), 55 | // _self._ec.Geo.prototype.dataToPoint = function (e) { 56 | // var pointTemp = new Point(e[0], e[1]), 57 | // pointScreenObj = _self._map.toScreen(pointTemp); 58 | // return [pointScreenObj.x, pointScreenObj.y] 59 | // }, 60 | // _self._bindEvent(), 61 | // _self._ec 62 | //}, 63 | _self.getECharts = function () { 64 | return _self._ec 65 | }, 66 | _self.setOption = function (e, t) { 67 | _self._option = e, 68 | _self._ec.setOption(e, t) 69 | }, 70 | _self._bindEvent = function () { 71 | //浏览器窗口大小变化 72 | _self._view.on("resize", function () { 73 | var e = _self._echartsContainer.parentNode.parentNode.parentNode; 74 | _self._mapOffset = [-parseInt(e.style.left) || 0, -parseInt(e.style.top) || 0], 75 | _self._echartsContainer.style.left = _self._mapOffset[0] + "px", 76 | _self._echartsContainer.style.top = _self._mapOffset[1] + "px", 77 | setTimeout(function () { 78 | _self._ec.resize() 79 | }, 200), 80 | _self._echartsContainer.style.visibility = "visible" 81 | }), 82 | //鼠标抬起 83 | _self._view.on("pointer-up", function (e) { 84 | _self._ec.resize() 85 | }); 86 | //监听zoom事件 87 | _self._view.watch("zoom", function (value) { 88 | if (isInteger(value)) { 89 | _self._ec.resize() 90 | } 91 | //console.log("zoom级别:" + value); 92 | }); 93 | } 94 | } 95 | }) 96 | }); 97 | /** 98 | * @func 字符串是否是整数 99 | * @param str 要判断的字符串 100 | * @return true或者false 101 | * */ 102 | function isInteger( str ){ 103 | var regu = /^[-]{0,1}[0-9]{1,}$/; 104 | return regu.test(str); 105 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 xcsf 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## ArcGIS-API-for-JS-with-Echarts 2 | 3 | #### ArcGIS API for Javascript 4.X扩展Echarts4.2.0 4 | 5 | 放着一个ArcGIS API for Javascript结合使用Echarts的demo。 6 | 7 | 主要是一个自定义的Echarts图层对象,echartsLayer.js文件 8 | 9 | [参考博客](https://blog.csdn.net/yy284872497/article/details/85228643) 10 | 11 | 大概思路是通过注册坐标系实现。 12 | 13 | 这个仓库的demo也使用是通过这个方法实现的Echarts图层。 14 | 15 | 16 | 17 | 思路是通过屏幕坐标转换实现。 18 | 19 | 存放代码备用 20 | 21 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 模拟人口迁徙 6 | 7 | 25 | 26 | 27 | 28 | 37 | 38 | 422 | 423 | 424 |
425 | 426 | 427 | 428 | -------------------------------------------------------------------------------- /src/echartsLayer.js: -------------------------------------------------------------------------------- 1 | define([ 2 | "dojo/_base/declare", 3 | "dojo/_base/lang", 4 | "esri/geometry/Point", 5 | "esri/geometry/SpatialReference" 6 | ], function (declare, lang, n, SpatialReference) { 7 | return declare("EchartsglLayer", null, { 8 | name: "EchartsglLayer", 9 | view: null, 10 | box: null, 11 | chart: null, 12 | chartOption: null, 13 | visible: true, 14 | constructor: function (view, option) { 15 | //如果在服务器上使用该代码 可以将echart对象传入到option中 16 | echarts.registerCoordinateSystem('arcgis', this.getE3CoordinateSystem(view)); 17 | this.init(view, option); 18 | }, 19 | init: function (view, option) { 20 | this.setBaseMap(view); 21 | this.createLayer(); 22 | //this.setChartOption(option); 23 | }, 24 | setBaseMap: function (view) { 25 | this.view = view; 26 | }, 27 | setChartOption: function (option) { 28 | this.chartOption = option; 29 | this.setCharts(); 30 | }, 31 | setVisible: function (bool) { 32 | if (!this.box || this.visible === bool) return; 33 | this.box.hidden = !bool; 34 | this.visible = bool; 35 | bool === true && setCharts(); 36 | }, 37 | refreshBegin: function () { 38 | this.box.hidden = true; 39 | }, 40 | refreshing: function () { 41 | setCharts(); 42 | }, 43 | refreshEnd: function () { 44 | this.box.hidden = false; 45 | }, 46 | on: function (eventName, handler, context) { 47 | this.chart.on(eventName, handler, context); 48 | }, 49 | off: function (eventName, handler, context) { 50 | this.chart.off(eventName, handler, context); 51 | }, 52 | map_DragStart_Listener: null, 53 | map_DragEnd_Listener: null, 54 | map_ZoomStart_Listener: null, 55 | map_ZoomEnd_Listener: null, 56 | map_ExtentChange_Listener: null, 57 | map_click_Listener: null, 58 | setCharts: function () { 59 | if (!this.visible) return; 60 | if (this.chartOption == null || this.chartOption == 'undefined') return; 61 | let baseExtent = this.view.extent; 62 | //判断是否使用了mark类型标签,每次重绘要重新转换地理坐标到屏幕坐标 63 | //根据地图extent,重绘echarts 64 | this.chartOption.xAxis = { show: false, min: baseExtent.xmin, max: baseExtent.xmax }; 65 | this.chartOption.yAxis = { show: false, min: baseExtent.ymin, max: baseExtent.ymax }; 66 | this.chart.setOption(this.chartOption); 67 | this.chartOption.animation = false; 68 | }, 69 | /*创建layer的容器,添加到map的layers下面*/ 70 | createLayer: function () { 71 | let box = this.box = document.createElement("div"); 72 | box.setAttribute("id", "echartsData") 73 | box.setAttribute("name", "echartsData") 74 | box.style.width = this.view.width + 'px'; 75 | box.style.height = this.view.height + 'px'; 76 | box.style.position = "absolute"; 77 | box.style.top = 0; 78 | box.style.left = 0; 79 | let parent = document.getElementsByClassName("esri-view-surface")[0]; 80 | parent.appendChild(box); 81 | this.chart = echarts.init(box); 82 | //this.setCharts(); 83 | this.startMapEventListeners(); 84 | }, 85 | /*销毁实例*/ 86 | removeLayer: function () { 87 | this.box.outerHTML = ""; 88 | this.view = null; 89 | this.box = null; 90 | this.originLyr = null; 91 | this.features = null; 92 | this.screenData = []; 93 | this.chart = null; 94 | this.chartOption = null; 95 | this.map_DragStart_Listener.remove(); 96 | this.map_DragEnd_Listener.remove(); 97 | this.map_ZoomStart_Listener.remove(); 98 | this.map_ZoomEnd_Listener.remove(); 99 | this.map_ExtentChange_Listener.remove(); 100 | }, 101 | /*监听地图事件,根据图层是否显示,判断是否重绘echarts*/ 102 | startMapEventListeners: function () { 103 | let view = this.view; 104 | view.watch("extent", lang.hitch(this, function () { 105 | 106 | 107 | if (!this.visible) return; 108 | this.setCharts(); 109 | this.chart.resize(); 110 | this.box.hidden = false; 111 | })); 112 | view.watch("rotation", lang.hitch(this, function () { 113 | if (!this.visible) return; 114 | this.setCharts(); 115 | this.chart.resize(); 116 | this.box.hidden = false; 117 | })); 118 | 119 | }, 120 | getE3CoordinateSystem: function (map) { 121 | var CoordSystem = function CoordSystem(map) { 122 | this.map = map; 123 | this._mapOffset = [0, 0]; 124 | }; 125 | CoordSystem.create = function (ecModel) { 126 | ecModel.eachSeries(function (seriesModel) { 127 | if (seriesModel.get('coordinateSystem') === 'arcgis') { 128 | seriesModel.coordinateSystem = new CoordSystem(map); 129 | } 130 | }); 131 | }; 132 | CoordSystem.getDimensionsInfo = function () { 133 | return ['x', 'y']; 134 | }; 135 | CoordSystem.dimensions = ['x', 'y']; 136 | CoordSystem.prototype.dimensions = ['x', 'y']; 137 | CoordSystem.prototype.setMapOffset = function setMapOffset(mapOffset) { 138 | this._mapOffset = mapOffset; 139 | } 140 | CoordSystem.prototype.dataToPoint = function dataToPoint(data) { 141 | var point = { 142 | type: "point", 143 | x: data[0], 144 | y: data[1], 145 | spatialReference: new SpatialReference(4326) 146 | }; 147 | var px = map.toScreen(point); 148 | var mapOffset = this._mapOffset; 149 | return [px.x - mapOffset[0], px.y - mapOffset[1]]; 150 | } 151 | CoordSystem.prototype.pointToData = function pointToData(pt) { 152 | var mapOffset = this._mapOffset; 153 | var screentPoint = { 154 | x: pt[0] + mapOffset[0], 155 | y: pt[1] + mapOffset[1] 156 | }; 157 | var data = map.toMap(screentPoint); 158 | return [data.x, data.y]; 159 | }; 160 | CoordSystem.prototype.getViewRect = function getViewRect() { 161 | return new graphic.BoundingRect(0, 0, this.map.width, this.map.height); 162 | }; 163 | CoordSystem.prototype.getRoamTransform = function getRoamTransform() { 164 | return matrix.create(); 165 | }; 166 | return CoordSystem 167 | } 168 | 169 | }); 170 | }) --------------------------------------------------------------------------------