main.js 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  1. /**
  2. * echarts 百度地图扩展,必须在echarts初始化前使用
  3. *
  4. * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。
  5. * @author Neil (杨骥, 511415343@qq.com)
  6. */
  7. define(function (require) {
  8. /**
  9. * 构造函数
  10. *
  11. * @param {String|HTMLElement|BMap.Map} obj
  12. * @param {BMap} BMap
  13. * @param {echarts} ec
  14. * @parma {Object=} mapOption 百度地图初始化选项
  15. * @constructor
  16. */
  17. function BMapExt(obj, BMap, ec, mapOption) {
  18. this._init(obj, BMap, ec, mapOption);
  19. };
  20. /**
  21. * echarts 容器元素
  22. *
  23. * @type {HTMLElement}
  24. * @private
  25. */
  26. BMapExt.prototype._echartsContainer = null;
  27. /**
  28. * 百度地图实例
  29. *
  30. * @type {BMap.Map}
  31. * @private
  32. */
  33. BMapExt.prototype._map = null;
  34. /**
  35. * 使用的echarts实例
  36. *
  37. * @type {ECharts}
  38. * @private
  39. */
  40. BMapExt.prototype._ec = null;
  41. /**
  42. * geoCoord
  43. *
  44. * @type {Object}
  45. * @private
  46. */
  47. BMapExt.prototype._geoCoord = [];
  48. /**
  49. * 记录地图的便宜量
  50. *
  51. * @type {Array.<number>}
  52. * @private
  53. */
  54. BMapExt.prototype._mapOffset = [0, 0];
  55. /**
  56. * 初始化方法
  57. *
  58. * @param {String|HTMLElement|BMap.Map} obj
  59. * @param {BMap} BMap
  60. * @param {echarts} ec
  61. * @private
  62. */
  63. BMapExt.prototype._init = function (obj, BMap, ec, mapOption) {
  64. var self = this;
  65. self._map = obj.constructor == BMap.Map ? obj : new BMap.Map(obj, mapOption);
  66. /**
  67. * Overlay类,用来生成覆盖物
  68. *
  69. * @constructor
  70. * @extends BMap.Overlay
  71. */
  72. function Overlay() {}
  73. Overlay.prototype = new BMap.Overlay();
  74. /**
  75. * 初始化
  76. *
  77. * @param {BMap.Map} map
  78. * @override
  79. */
  80. Overlay.prototype.initialize = function (map) {
  81. var size = map.getSize();
  82. var div = self._echartsContainer = document.createElement('div');
  83. div.style.position = 'absolute';
  84. div.style.height = size.height + 'px';
  85. div.style.width = size.width + 'px';
  86. div.style.top = 0;
  87. div.style.left = 0;
  88. map.getPanes().labelPane.appendChild(div);
  89. return div;
  90. };
  91. /**
  92. * @override
  93. */
  94. Overlay.prototype.draw = function () {};
  95. var myOverlay = new Overlay();
  96. /**
  97. * 获取echarts容器
  98. *
  99. * @return {HTMLElement}
  100. * @public
  101. */
  102. self.getEchartsContainer = function () {
  103. return self._echartsContainer;
  104. };
  105. /**
  106. * 获取map实例
  107. *
  108. * @return {BMap.Map}
  109. * @public
  110. */
  111. self.getMap = function () {
  112. return self._map;
  113. }
  114. /**
  115. * 自定义拖拽事件
  116. */
  117. self.onmoving = null;
  118. self.onmoveend = null;
  119. /**
  120. * 自定义缩放事件
  121. */
  122. self.onzoom = null;
  123. /**
  124. * 经纬度转换为屏幕像素
  125. *
  126. * @param {Array.<number>} geoCoord 经纬度
  127. * @return {Array.<number>}
  128. * @public
  129. */
  130. self.geoCoord2Pixel = function (geoCoord) {
  131. var point = new BMap.Point(geoCoord[0], geoCoord[1]);
  132. var pos = self._map.pointToOverlayPixel(point);
  133. return [pos.x, pos.y];
  134. };
  135. /**
  136. * 屏幕像素转换为经纬度
  137. *
  138. * @param {Array.<number>} pixel 像素坐标
  139. * @return {Array.<number>}
  140. * @public
  141. */
  142. self.pixel2GeoCoord = function (pixel) {
  143. var point = self._map.overlayPixelToPoint({
  144. x: pixel[0],
  145. y: pixel[1]
  146. });
  147. return [point.lng, point.lat];
  148. };
  149. /**
  150. * 初始化echarts实例
  151. *
  152. * @return {ECharts}
  153. * @public
  154. */
  155. self.initECharts = function () {
  156. self._ec = ec.init.apply(self, arguments);
  157. self._bindEvent();
  158. self._addMarkWrap();
  159. return self._ec;
  160. };
  161. // addMark wrap for get position from baidu map by geo location
  162. // by kener at 2015.01.08
  163. self._addMarkWrap = function () {
  164. function _addMark (seriesIdx, markData, markType) {
  165. var data;
  166. if (markType == 'markPoint') {
  167. var data = markData.data;
  168. if (data && data.length) {
  169. for (var k in data) {
  170. self._AddPos(data[k]);
  171. }
  172. }
  173. }
  174. else {
  175. data = markData.data;
  176. if (data && data.length) {
  177. for (var k in data) {
  178. self._AddPos(data[k][0]);
  179. self._AddPos(data[k][1]);
  180. }
  181. }
  182. }
  183. self._ec._addMarkOri(seriesIdx, markData, markType);
  184. }
  185. self._ec._addMarkOri = self._ec._addMark;
  186. self._ec._addMark = _addMark;
  187. };
  188. /**
  189. * 获取ECharts实例
  190. *
  191. * @return {ECharts}
  192. * @public
  193. */
  194. self.getECharts = function () {
  195. return self._ec;
  196. };
  197. /**
  198. * 获取地图的偏移量
  199. *
  200. * @return {Array.<number>}
  201. * @public
  202. */
  203. self.getMapOffset = function () {
  204. return self._mapOffset;
  205. };
  206. /**
  207. * 对echarts的setOption加一次处理
  208. * 用来为markPoint、markLine中添加x、y坐标,需要name与geoCoord对应
  209. *
  210. * @param {Object}
  211. * @public
  212. */
  213. self.setOption = function (option, notMerge) {
  214. var series = option.series || {};
  215. // 记录所有的geoCoord
  216. for (var i = 0, item; item = series[i++];) {
  217. var geoCoord = item.geoCoord;
  218. if (geoCoord) {
  219. for (var k in geoCoord) {
  220. self._geoCoord[k] = geoCoord[k];
  221. }
  222. }
  223. }
  224. // 添加x、y
  225. for (var i = 0, item; item = series[i++];) {
  226. var markPoint = item.markPoint || {};
  227. var markLine = item.markLine || {};
  228. var data = markPoint.data;
  229. if (data && data.length) {
  230. for (var k in data) {
  231. self._AddPos(data[k]);
  232. }
  233. }
  234. data = markLine.data;
  235. if (data && data.length) {
  236. for (var k in data) {
  237. self._AddPos(data[k][0]);
  238. self._AddPos(data[k][1]);
  239. }
  240. }
  241. }
  242. self._ec.setOption(option, notMerge);
  243. }
  244. /**
  245. * 增加x、y坐标
  246. *
  247. * @param {Object} obj markPoint、markLine data中的项,必须有name
  248. * @param {Object} geoCoord
  249. */
  250. self._AddPos = function (obj) {
  251. var coord = this._geoCoord[obj.name]
  252. var pos = this.geoCoord2Pixel(coord);
  253. obj.x = pos[0] - self._mapOffset[0];
  254. obj.y = pos[1] - self._mapOffset[1];
  255. };
  256. /**
  257. * 绑定地图事件的处理方法
  258. *
  259. * @private
  260. */
  261. self._bindEvent = function () {
  262. self._map.addEventListener('zoomend', _zoomChangeHandler);
  263. self._map.addEventListener('moving', _moveHandler('moving'));
  264. self._map.addEventListener('moveend', _moveHandler('moveend'));
  265. self._ec.getZrender().on('dragstart', _dragZrenderHandler(true));
  266. self._ec.getZrender().on('dragend', _dragZrenderHandler(false));
  267. }
  268. /**
  269. * 地图缩放触发事件
  270. *
  271. * @private
  272. */
  273. function _zoomChangeHandler() {
  274. _fireEvent('zoom');
  275. }
  276. /**
  277. * 地图移动、如拖拽触发事件
  278. *
  279. * @param {string} type moving | moveend 移动中|移动结束
  280. * @return {Function}
  281. * @private
  282. */
  283. function _moveHandler(type) {
  284. return function () {
  285. // 记录便宜量
  286. var offsetEle =
  287. self._echartsContainer.parentNode.parentNode.parentNode;
  288. self._mapOffset = [
  289. - parseInt(offsetEle.style.left) || 0,
  290. - parseInt(offsetEle.style.top) || 0
  291. ];
  292. self._echartsContainer.style.left = self._mapOffset[0] + 'px';
  293. self._echartsContainer.style.top = self._mapOffset[1] + 'px';
  294. _fireEvent(type);
  295. }
  296. }
  297. /**
  298. * Zrender拖拽触发事件
  299. *
  300. * @param {boolean} isStart
  301. * @return {Function}
  302. * @private
  303. */
  304. function _dragZrenderHandler(isStart) {
  305. return function () {
  306. var func = isStart ? 'disableDragging' : 'enableDragging';
  307. self._map[func]();
  308. }
  309. }
  310. /**
  311. * 触发事件
  312. *
  313. * @param {stirng} type 事件类型
  314. * @private
  315. */
  316. function _fireEvent(type) {
  317. var func = self['on' + type];
  318. if (func) {
  319. func();
  320. } else {
  321. self.refresh();
  322. }
  323. }
  324. /**
  325. * 刷新页面
  326. *
  327. * @public
  328. */
  329. self.refresh = function () {
  330. if (self._ec) {
  331. var option = self._ec.getOption();
  332. self._ec.clear();
  333. self.setOption(option);
  334. }
  335. }
  336. self._map.addOverlay(myOverlay);
  337. };
  338. return BMapExt;
  339. });