You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

bmap.js 9.9 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. (function (global, factory) {
  2. typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('echarts')) :
  3. typeof define === 'function' && define.amd ? define(['exports', 'echarts'], factory) :
  4. (factory((global.bmap = {}),global.echarts));
  5. }(this, (function (exports,echarts) { 'use strict';
  6. /* global BMap */
  7. function BMapCoordSys(bmap, api) {
  8. this._bmap = bmap;
  9. this.dimensions = ['lng', 'lat'];
  10. this._mapOffset = [0, 0];
  11. this._api = api;
  12. this._projection = new BMap.MercatorProjection();
  13. }
  14. BMapCoordSys.prototype.dimensions = ['lng', 'lat'];
  15. BMapCoordSys.prototype.setZoom = function (zoom) {
  16. this._zoom = zoom;
  17. };
  18. BMapCoordSys.prototype.setCenter = function (center) {
  19. this._center = this._projection.lngLatToPoint(new BMap.Point(center[0], center[1]));
  20. };
  21. BMapCoordSys.prototype.setMapOffset = function (mapOffset) {
  22. this._mapOffset = mapOffset;
  23. };
  24. BMapCoordSys.prototype.getBMap = function () {
  25. return this._bmap;
  26. };
  27. BMapCoordSys.prototype.dataToPoint = function (data) {
  28. var point = new BMap.Point(data[0], data[1]);
  29. // TODO mercator projection is toooooooo slow
  30. // var mercatorPoint = this._projection.lngLatToPoint(point);
  31. // var width = this._api.getZr().getWidth();
  32. // var height = this._api.getZr().getHeight();
  33. // var divider = Math.pow(2, 18 - 10);
  34. // return [
  35. // Math.round((mercatorPoint.x - this._center.x) / divider + width / 2),
  36. // Math.round((this._center.y - mercatorPoint.y) / divider + height / 2)
  37. // ];
  38. var px = this._bmap.pointToOverlayPixel(point);
  39. var mapOffset = this._mapOffset;
  40. return [px.x - mapOffset[0], px.y - mapOffset[1]];
  41. };
  42. BMapCoordSys.prototype.pointToData = function (pt) {
  43. var mapOffset = this._mapOffset;
  44. var pt = this._bmap.overlayPixelToPoint({
  45. x: pt[0] + mapOffset[0],
  46. y: pt[1] + mapOffset[1]
  47. });
  48. return [pt.lng, pt.lat];
  49. };
  50. BMapCoordSys.prototype.getViewRect = function () {
  51. var api = this._api;
  52. return new echarts.graphic.BoundingRect(0, 0, api.getWidth(), api.getHeight());
  53. };
  54. BMapCoordSys.prototype.getRoamTransform = function () {
  55. return echarts.matrix.create();
  56. };
  57. BMapCoordSys.prototype.prepareCustoms = function (data) {
  58. var rect = this.getViewRect();
  59. return {
  60. coordSys: {
  61. // The name exposed to user is always 'cartesian2d' but not 'grid'.
  62. type: 'bmap',
  63. x: rect.x,
  64. y: rect.y,
  65. width: rect.width,
  66. height: rect.height
  67. },
  68. api: {
  69. coord: echarts.util.bind(this.dataToPoint, this),
  70. size: echarts.util.bind(dataToCoordSize, this)
  71. }
  72. };
  73. };
  74. function dataToCoordSize(dataSize, dataItem) {
  75. dataItem = dataItem || [0, 0];
  76. return echarts.util.map([0, 1], function (dimIdx) {
  77. var val = dataItem[dimIdx];
  78. var halfSize = dataSize[dimIdx] / 2;
  79. var p1 = [];
  80. var p2 = [];
  81. p1[dimIdx] = val - halfSize;
  82. p2[dimIdx] = val + halfSize;
  83. p1[1 - dimIdx] = p2[1 - dimIdx] = dataItem[1 - dimIdx];
  84. return Math.abs(this.dataToPoint(p1)[dimIdx] - this.dataToPoint(p2)[dimIdx]);
  85. }, this);
  86. }
  87. var Overlay;
  88. // For deciding which dimensions to use when creating list data
  89. BMapCoordSys.dimensions = BMapCoordSys.prototype.dimensions;
  90. function createOverlayCtor() {
  91. function Overlay(root) {
  92. this._root = root;
  93. }
  94. Overlay.prototype = new BMap.Overlay();
  95. /**
  96. * 初始化
  97. *
  98. * @param {BMap.Map} map
  99. * @override
  100. */
  101. Overlay.prototype.initialize = function (map) {
  102. map.getPanes().labelPane.appendChild(this._root);
  103. return this._root;
  104. };
  105. /**
  106. * @override
  107. */
  108. Overlay.prototype.draw = function () {};
  109. return Overlay;
  110. }
  111. BMapCoordSys.create = function (ecModel, api) {
  112. var bmapCoordSys;
  113. var root = api.getDom();
  114. // TODO Dispose
  115. ecModel.eachComponent('bmap', function (bmapModel) {
  116. var painter = api.getZr().painter;
  117. var viewportRoot = painter.getViewportRoot();
  118. if (typeof BMap === 'undefined') {
  119. throw new Error('BMap api is not loaded');
  120. }
  121. Overlay = Overlay || createOverlayCtor();
  122. if (bmapCoordSys) {
  123. throw new Error('Only one bmap component can exist');
  124. }
  125. if (!bmapModel.__bmap) {
  126. // Not support IE8
  127. var bmapRoot = root.querySelector('.ec-extension-bmap');
  128. if (bmapRoot) {
  129. // Reset viewport left and top, which will be changed
  130. // in moving handler in BMapView
  131. viewportRoot.style.left = '0px';
  132. viewportRoot.style.top = '0px';
  133. root.removeChild(bmapRoot);
  134. }
  135. bmapRoot = document.createElement('div');
  136. bmapRoot.style.cssText = 'width:100%;height:100%';
  137. // Not support IE8
  138. bmapRoot.classList.add('ec-extension-bmap');
  139. root.appendChild(bmapRoot);
  140. var bmap = bmapModel.__bmap = new BMap.Map(bmapRoot);
  141. var overlay = new Overlay(viewportRoot);
  142. bmap.addOverlay(overlay);
  143. // Override
  144. painter.getViewportRootOffset = function () {
  145. return {offsetLeft: 0, offsetTop: 0};
  146. };
  147. }
  148. var bmap = bmapModel.__bmap;
  149. // Set bmap options
  150. // centerAndZoom before layout and render
  151. var center = bmapModel.get('center');
  152. var zoom = bmapModel.get('zoom');
  153. if (center && zoom) {
  154. var pt = new BMap.Point(center[0], center[1]);
  155. bmap.centerAndZoom(pt, zoom);
  156. }
  157. bmapCoordSys = new BMapCoordSys(bmap, api);
  158. bmapCoordSys.setMapOffset(bmapModel.__mapOffset || [0, 0]);
  159. bmapCoordSys.setZoom(zoom);
  160. bmapCoordSys.setCenter(center);
  161. bmapModel.coordinateSystem = bmapCoordSys;
  162. });
  163. ecModel.eachSeries(function (seriesModel) {
  164. if (seriesModel.get('coordinateSystem') === 'bmap') {
  165. seriesModel.coordinateSystem = bmapCoordSys;
  166. }
  167. });
  168. };
  169. function v2Equal(a, b) {
  170. return a && b && a[0] === b[0] && a[1] === b[1];
  171. }
  172. echarts.extendComponentModel({
  173. type: 'bmap',
  174. getBMap: function () {
  175. // __bmap is injected when creating BMapCoordSys
  176. return this.__bmap;
  177. },
  178. setCenterAndZoom: function (center, zoom) {
  179. this.option.center = center;
  180. this.option.zoom = zoom;
  181. },
  182. centerOrZoomChanged: function (center, zoom) {
  183. var option = this.option;
  184. return !(v2Equal(center, option.center) && zoom === option.zoom);
  185. },
  186. defaultOption: {
  187. center: [104.114129, 37.550339],
  188. zoom: 5,
  189. mapStyle: {},
  190. roam: false
  191. }
  192. });
  193. echarts.extendComponentView({
  194. type: 'bmap',
  195. render: function (bMapModel, ecModel, api) {
  196. var rendering = true;
  197. var bmap = bMapModel.getBMap();
  198. var viewportRoot = api.getZr().painter.getViewportRoot();
  199. var coordSys = bMapModel.coordinateSystem;
  200. var moveHandler = function (type, target) {
  201. if (rendering) {
  202. return;
  203. }
  204. var offsetEl = viewportRoot.parentNode.parentNode.parentNode;
  205. var mapOffset = [
  206. -parseInt(offsetEl.style.left, 10) || 0,
  207. -parseInt(offsetEl.style.top, 10) || 0
  208. ];
  209. viewportRoot.style.left = mapOffset[0] + 'px';
  210. viewportRoot.style.top = mapOffset[1] + 'px';
  211. coordSys.setMapOffset(mapOffset);
  212. bMapModel.__mapOffset = mapOffset;
  213. api.dispatchAction({
  214. type: 'bmapRoam'
  215. });
  216. };
  217. function zoomEndHandler() {
  218. if (rendering) {
  219. return;
  220. }
  221. api.dispatchAction({
  222. type: 'bmapRoam'
  223. });
  224. }
  225. bmap.removeEventListener('moving', this._oldMoveHandler);
  226. // FIXME
  227. // Moveend may be triggered by centerAndZoom method when creating coordSys next time
  228. // bmap.removeEventListener('moveend', this._oldMoveHandler);
  229. bmap.removeEventListener('zoomend', this._oldZoomEndHandler);
  230. bmap.addEventListener('moving', moveHandler);
  231. // bmap.addEventListener('moveend', moveHandler);
  232. bmap.addEventListener('zoomend', zoomEndHandler);
  233. this._oldMoveHandler = moveHandler;
  234. this._oldZoomEndHandler = zoomEndHandler;
  235. var roam = bMapModel.get('roam');
  236. if (roam && roam !== 'scale') {
  237. bmap.enableDragging();
  238. }
  239. else {
  240. bmap.disableDragging();
  241. }
  242. if (roam && roam !== 'move') {
  243. bmap.enableScrollWheelZoom();
  244. bmap.enableDoubleClickZoom();
  245. bmap.enablePinchToZoom();
  246. }
  247. else {
  248. bmap.disableScrollWheelZoom();
  249. bmap.disableDoubleClickZoom();
  250. bmap.disablePinchToZoom();
  251. }
  252. var originalStyle = bMapModel.__mapStyle;
  253. var newMapStyle = bMapModel.get('mapStyle') || {};
  254. // FIXME, Not use JSON methods
  255. var mapStyleStr = JSON.stringify(newMapStyle);
  256. if (JSON.stringify(originalStyle) !== mapStyleStr) {
  257. // FIXME May have blank tile when dragging if setMapStyle
  258. if (Object.keys(newMapStyle).length) {
  259. bmap.setMapStyle(newMapStyle);
  260. }
  261. bMapModel.__mapStyle = JSON.parse(mapStyleStr);
  262. }
  263. rendering = false;
  264. }
  265. });
  266. /**
  267. * BMap component extension
  268. */
  269. echarts.registerCoordinateSystem('bmap', BMapCoordSys);
  270. // Action
  271. echarts.registerAction({
  272. type: 'bmapRoam',
  273. event: 'bmapRoam',
  274. update: 'updateLayout'
  275. }, function (payload, ecModel) {
  276. ecModel.eachComponent('bmap', function (bMapModel) {
  277. var bmap = bMapModel.getBMap();
  278. var center = bmap.getCenter();
  279. bMapModel.setCenterAndZoom([center.lng, center.lat], bmap.getZoom());
  280. });
  281. });
  282. var version = '1.0.0';
  283. exports.version = version;
  284. })));
  285. //# sourceMappingURL=bmap.js.map