a324b568a9351bd481ca1b89027090f00678fbec.svn-base 66 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720
  1. /**
  2. * echarts图表类:地图
  3. *
  4. * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。
  5. * @author Kener (@Kener-林峰, kener.linfeng@gmail.com)
  6. *
  7. */
  8. define(function (require) {
  9. var ChartBase = require('./base');
  10. // 图形依赖
  11. var TextShape = require('zrender/shape/Text');
  12. var PathShape = require('zrender/shape/Path');
  13. var CircleShape = require('zrender/shape/Circle');
  14. var RectangleShape = require('zrender/shape/Rectangle');
  15. var LineShape = require('zrender/shape/Line');
  16. var PolygonShape = require('zrender/shape/Polygon');
  17. var EllipseShape = require('zrender/shape/Ellipse');
  18. var ZrImage = require('zrender/shape/Image');
  19. // 组件依赖
  20. require('../component/dataRange');
  21. require('../component/roamController');
  22. var HeatmapLayer = require('../layer/heatmap');
  23. var ecConfig = require('../config');
  24. // 地图默认参数
  25. ecConfig.map = {
  26. zlevel: 0, // 一级层叠
  27. z: 2, // 二级层叠
  28. mapType: 'china', // 各省的mapType暂时都用中文
  29. //mapLocation: {
  30. // x: 'center' | 'left' | 'right' | 'x%' | {number},
  31. // y: 'center' | 'top' | 'bottom' | 'x%' | {number}
  32. // width // 自适应
  33. // height // 自适应
  34. //},
  35. // mapValueCalculation: 'sum', // 数值合并方式,默认加和,可选为:
  36. // 'sum' | 'average' | 'max' | 'min'
  37. // mapValuePrecision: 0, // 地图数值计算结果小数精度
  38. showLegendSymbol: true, // 显示图例颜色标识(系列标识的小圆点),存在legend时生效
  39. // selectedMode: false, // 选择模式,默认关闭,可选single,multiple
  40. dataRangeHoverLink: true,
  41. hoverable: true,
  42. clickable: true,
  43. // roam: false, // 是否开启缩放及漫游模式
  44. // scaleLimit: null,
  45. itemStyle: {
  46. normal: {
  47. // color: 各异,
  48. borderColor: 'rgba(0,0,0,0)',
  49. borderWidth: 1,
  50. areaStyle: {
  51. color: '#ccc'
  52. },
  53. label: {
  54. show: false,
  55. textStyle: {
  56. color: 'rgb(139,69,19)'
  57. }
  58. }
  59. },
  60. emphasis: { // 也是选中样式
  61. // color: 各异,
  62. borderColor: 'rgba(0,0,0,0)',
  63. borderWidth: 1,
  64. areaStyle: {
  65. color: 'rgba(255,215,0,0.8)'
  66. },
  67. label: {
  68. show: false,
  69. textStyle: {
  70. color: 'rgb(100,0,0)'
  71. }
  72. }
  73. }
  74. }
  75. };
  76. var ecData = require('../util/ecData');
  77. var zrUtil = require('zrender/tool/util');
  78. var zrConfig = require('zrender/config');
  79. var zrEvent = require('zrender/tool/event');
  80. var _mapParams = require('../util/mapData/params').params;
  81. var _textFixed = require('../util/mapData/textFixed');
  82. var _geoCoord = require('../util/mapData/geoCoord');
  83. /**
  84. * 构造函数
  85. * @param {Object} messageCenter echart消息中心
  86. * @param {ZRender} zr zrender实例
  87. * @param {Object} series 数据
  88. * @param {Object} component 组件
  89. */
  90. function Map(ecTheme, messageCenter, zr, option, myChart){
  91. // 图表基类
  92. ChartBase.call(this, ecTheme, messageCenter, zr, option, myChart);
  93. var self = this;
  94. self._onmousewheel = function(params) {
  95. return self.__onmousewheel(params);
  96. };
  97. self._onmousedown = function(params) {
  98. return self.__onmousedown(params);
  99. };
  100. self._onmousemove = function(params) {
  101. return self.__onmousemove(params);
  102. };
  103. self._onmouseup = function(params) {
  104. return self.__onmouseup(params);
  105. };
  106. self._onroamcontroller = function(params) {
  107. return self.__onroamcontroller(params);
  108. };
  109. self._ondrhoverlink = function(params) {
  110. return self.__ondrhoverlink(params);
  111. };
  112. this._isAlive = true; // 活着标记
  113. this._selectedMode = {}; // 选择模式
  114. this._activeMapType = {}; // 当前活跃的地图类型
  115. this._clickable = {}; // 悬浮高亮模式,索引到图表
  116. this._hoverable = {}; // 悬浮高亮模式,索引到图表
  117. this._showLegendSymbol = {}; // 显示图例颜色标识
  118. this._selected = {}; // 地图选择状态
  119. this._mapTypeMap = {}; // 图例类型索引
  120. this._mapDataMap = {}; // 根据地图类型索引bbox,transform,path
  121. this._nameMap = {}; // 个性化地名
  122. this._specialArea = {}; // 特殊
  123. this._refreshDelayTicket; // 滚轮缩放时让refresh飞一会
  124. this._mapDataRequireCounter; // 异步回调计数器
  125. this._markAnimation = false;
  126. this._hoverLinkMap = {};
  127. // 漫游相关信息
  128. this._roamMap = {};
  129. this._scaleLimitMap = {};
  130. this._mx;
  131. this._my;
  132. this._mousedown;
  133. this._justMove; // 避免移动响应点击
  134. this._curMapType; // 当前移动的地图类型
  135. this.refresh(option);
  136. this.zr.on(zrConfig.EVENT.MOUSEWHEEL, this._onmousewheel);
  137. this.zr.on(zrConfig.EVENT.MOUSEDOWN, this._onmousedown);
  138. messageCenter.bind(ecConfig.EVENT.ROAMCONTROLLER, this._onroamcontroller);
  139. messageCenter.bind(ecConfig.EVENT.DATA_RANGE_HOVERLINK, this._ondrhoverlink);
  140. }
  141. Map.prototype = {
  142. type : ecConfig.CHART_TYPE_MAP,
  143. /**
  144. * 绘制图形
  145. */
  146. _buildShape : function () {
  147. var series = this.series;
  148. this.selectedMap = {}; // 系列
  149. this._activeMapType = {}; // 当前活跃的地图类型
  150. var legend = this.component.legend;
  151. var seriesName;
  152. var valueData = {};
  153. var mapType;
  154. var data;
  155. var name;
  156. var mapSeries = {};
  157. var mapValuePrecision = {};
  158. var valueCalculation = {};
  159. for (var i = 0, l = series.length; i < l; i++) {
  160. if (series[i].type == ecConfig.CHART_TYPE_MAP) { // map
  161. series[i] = this.reformOption(series[i]);
  162. mapType = series[i].mapType;
  163. mapSeries[mapType] = mapSeries[mapType] || {};
  164. mapSeries[mapType][i] = true;
  165. mapValuePrecision[mapType] = mapValuePrecision[mapType]
  166. || series[i].mapValuePrecision;
  167. this._scaleLimitMap[mapType] = this._scaleLimitMap[mapType] || {};
  168. series[i].scaleLimit
  169. && zrUtil.merge(this._scaleLimitMap[mapType], series[i].scaleLimit, true);
  170. this._roamMap[mapType] = series[i].roam || this._roamMap[mapType];
  171. if (this._hoverLinkMap[mapType] == null || this._hoverLinkMap[mapType]) {
  172. // false 1票否决
  173. this._hoverLinkMap[mapType] = series[i].dataRangeHoverLink;
  174. }
  175. this._nameMap[mapType] = this._nameMap[mapType] || {};
  176. series[i].nameMap
  177. && zrUtil.merge(this._nameMap[mapType], series[i].nameMap, true);
  178. this._activeMapType[mapType] = true;
  179. if (series[i].textFixed) {
  180. zrUtil.merge(
  181. _textFixed, series[i].textFixed, true
  182. );
  183. }
  184. if (series[i].geoCoord) {
  185. zrUtil.merge(
  186. _geoCoord, series[i].geoCoord, true
  187. );
  188. }
  189. this._selectedMode[mapType] = this._selectedMode[mapType]
  190. || series[i].selectedMode;
  191. if (this._hoverable[mapType] == null || this._hoverable[mapType]) {
  192. // false 1票否决
  193. this._hoverable[mapType] = series[i].hoverable;
  194. }
  195. if (this._clickable[mapType] == null || this._clickable[mapType]) {
  196. // false 1票否决
  197. this._clickable[mapType] = series[i].clickable;
  198. }
  199. if (this._showLegendSymbol[mapType] == null
  200. || this._showLegendSymbol[mapType]
  201. ) {
  202. // false 1票否决
  203. this._showLegendSymbol[mapType] = series[i].showLegendSymbol;
  204. }
  205. valueCalculation[mapType] = valueCalculation[mapType]
  206. || series[i].mapValueCalculation;
  207. seriesName = series[i].name;
  208. this.selectedMap[seriesName] = legend
  209. ? legend.isSelected(seriesName)
  210. : true;
  211. if (this.selectedMap[seriesName]) {
  212. valueData[mapType] = valueData[mapType] || {};
  213. data = series[i].data;
  214. for (var j = 0, k = data.length; j < k; j++) {
  215. name = this._nameChange(mapType, data[j].name);
  216. valueData[mapType][name] = valueData[mapType][name]
  217. || {
  218. seriesIndex : [],
  219. valueMap: {},
  220. precision: 0
  221. };
  222. for (var key in data[j]) {
  223. if (key != 'value') {
  224. valueData[mapType][name][key] =
  225. data[j][key];
  226. }
  227. else if (!isNaN(data[j].value)) {
  228. // value
  229. valueData[mapType][name].value == null
  230. && (valueData[mapType][name].value = 0);
  231. valueData[mapType][name].precision =
  232. Math.max(
  233. this.getPrecision(+data[j].value),
  234. valueData[mapType][name].precision
  235. );
  236. valueData[mapType][name].value += (+data[j].value);
  237. valueData[mapType][name].valueMap[i] = +data[j].value;
  238. }
  239. }
  240. //索引有该区域的系列样式
  241. valueData[mapType][name].seriesIndex.push(i);
  242. }
  243. }
  244. }
  245. }
  246. this._mapDataRequireCounter = 0;
  247. for (var mt in valueData) {
  248. this._mapDataRequireCounter++;
  249. }
  250. //清空
  251. this._clearSelected();
  252. if (this._mapDataRequireCounter === 0) {
  253. this.clear();
  254. this.zr && this.zr.delShape(this.lastShapeList);
  255. this.lastShapeList = [];
  256. }
  257. for (var mt in valueData) {
  258. for (var k in valueData[mt]) {
  259. if (valueCalculation[mt] == 'average') {
  260. valueData[mt][k].value /= valueData[mt][k].seriesIndex.length;
  261. }
  262. var value = valueData[mt][k].value;
  263. if (value != null) {
  264. valueData[mt][k].value = value.toFixed(
  265. mapValuePrecision[mt] == null
  266. ? valueData[mt][k].precision : mapValuePrecision[mt]
  267. ) - 0;
  268. }
  269. }
  270. this._mapDataMap[mt] = this._mapDataMap[mt] || {};
  271. if (this._mapDataMap[mt].mapData) {
  272. // 已经缓存了则直接用
  273. this._mapDataCallback(mt, valueData[mt], mapSeries[mt])(
  274. this._mapDataMap[mt].mapData
  275. );
  276. }
  277. else if (_mapParams[mt.replace(/\|.*/, '')].getGeoJson) {
  278. // 特殊区域
  279. this._specialArea[mt] =
  280. _mapParams[mt.replace(/\|.*/, '')].specialArea
  281. || this._specialArea[mt];
  282. _mapParams[mt.replace(/\|.*/, '')].getGeoJson(
  283. this._mapDataCallback(mt, valueData[mt], mapSeries[mt])
  284. );
  285. }
  286. }
  287. },
  288. /**
  289. * @param {string} mt mapType
  290. * @parma {Object} vd valueData
  291. * @param {Object} ms mapSeries
  292. */
  293. _mapDataCallback : function (mt, vd, ms) {
  294. var self = this;
  295. return function (md) {
  296. if (!self._isAlive || self._activeMapType[mt] == null) {
  297. // 异步地图数据回调时有可能实例已经被释放
  298. return;
  299. }
  300. // 缓存这份数据
  301. if (mt.indexOf('|') != -1) {
  302. // 子地图,加工一份新的mapData
  303. md = self._getSubMapData(mt, md);
  304. }
  305. self._mapDataMap[mt].mapData = md;
  306. if (md.firstChild) {
  307. self._mapDataMap[mt].rate = 1;
  308. self._mapDataMap[mt].projection = require('../util/projection/svg');
  309. }
  310. else {
  311. self._mapDataMap[mt].rate = 0.75;
  312. self._mapDataMap[mt].projection = require('../util/projection/normal');
  313. }
  314. self._buildMap(
  315. mt, // 类型
  316. self._getProjectionData(mt, md, ms), // 地图数据
  317. vd, // 用户数据
  318. ms // 系列
  319. );
  320. self._buildMark(mt, ms);
  321. if (--self._mapDataRequireCounter <= 0) {
  322. self.addShapeList();
  323. self.zr.refreshNextFrame();
  324. }
  325. self._buildHeatmap(mt);
  326. };
  327. },
  328. _clearSelected : function() {
  329. for (var k in this._selected) {
  330. if (!this._activeMapType[this._mapTypeMap[k]]) {
  331. delete this._selected[k];
  332. delete this._mapTypeMap[k];
  333. }
  334. }
  335. },
  336. _getSubMapData : function (mapType, mapData) {
  337. var subType = mapType.replace(/^.*\|/, '');
  338. var features = mapData.features;
  339. for (var i = 0, l = features.length; i < l; i++) {
  340. if (features[i].properties
  341. && features[i].properties.name == subType
  342. ) {
  343. features = features[i];
  344. if (subType == 'United States of America'
  345. && features.geometry.coordinates.length > 1 // 未被简化
  346. ) {
  347. features = {
  348. geometry: {
  349. coordinates: features.geometry
  350. .coordinates.slice(5,6),
  351. type: features.geometry.type
  352. },
  353. id: features.id,
  354. properties: features.properties,
  355. type: features.type
  356. };
  357. }
  358. break;
  359. }
  360. }
  361. return {
  362. 'type' : 'FeatureCollection',
  363. 'features':[
  364. features
  365. ]
  366. };
  367. },
  368. /**
  369. * 按需加载相关地图
  370. */
  371. _getProjectionData : function (mapType, mapData, mapSeries) {
  372. var normalProjection = this._mapDataMap[mapType].projection;
  373. var province = [];
  374. // bbox永远不变
  375. var bbox = this._mapDataMap[mapType].bbox
  376. || normalProjection.getBbox(
  377. mapData, this._specialArea[mapType]
  378. );
  379. //console.log(bbox)
  380. var transform;
  381. //console.log(1111,transform)
  382. if (!this._mapDataMap[mapType].hasRoam) {
  383. // 第一次或者发生了resize,需要判断
  384. transform = this._getTransform(
  385. bbox,
  386. mapSeries,
  387. this._mapDataMap[mapType].rate
  388. );
  389. }
  390. else {
  391. //经过用户漫游不再响应resize
  392. transform = this._mapDataMap[mapType].transform;
  393. }
  394. //console.log(bbox,transform)
  395. var lastTransform = this._mapDataMap[mapType].lastTransform
  396. || {scale:{}};
  397. var pathArray;
  398. if (transform.left != lastTransform.left
  399. || transform.top != lastTransform.top
  400. || transform.scale.x != lastTransform.scale.x
  401. || transform.scale.y != lastTransform.scale.y
  402. ) {
  403. // 发生过变化,需要重新生成pathArray
  404. // 一般投射
  405. //console.log(transform)
  406. pathArray = normalProjection.geoJson2Path(
  407. mapData, transform, this._specialArea[mapType]
  408. );
  409. lastTransform = zrUtil.clone(transform);
  410. }
  411. else {
  412. transform = this._mapDataMap[mapType].transform;
  413. pathArray = this._mapDataMap[mapType].pathArray;
  414. }
  415. this._mapDataMap[mapType].bbox = bbox;
  416. this._mapDataMap[mapType].transform = transform;
  417. this._mapDataMap[mapType].lastTransform = lastTransform;
  418. this._mapDataMap[mapType].pathArray = pathArray;
  419. //console.log(pathArray)
  420. var position = [transform.left, transform.top];
  421. for (var i = 0, l = pathArray.length; i < l; i++) {
  422. /* for test
  423. console.log(
  424. mapData.features[i].properties.cp, // 经纬度度
  425. pathArray[i].cp // 平面坐标
  426. );
  427. console.log(
  428. this.pos2geo(mapType, pathArray[i].cp), // 平面坐标转经纬度
  429. this.geo2pos(mapType, mapData.features[i].properties.cp)
  430. )
  431. */
  432. province.push(this._getSingleProvince(
  433. mapType, pathArray[i], position
  434. ));
  435. }
  436. if (this._specialArea[mapType]) {
  437. for (var area in this._specialArea[mapType]) {
  438. province.push(this._getSpecialProjectionData(
  439. mapType, mapData,
  440. area, this._specialArea[mapType][area],
  441. position
  442. ));
  443. }
  444. }
  445. // 中国地图加入南海诸岛
  446. if (mapType == 'china') {
  447. var leftTop = this.geo2pos(
  448. mapType,
  449. _geoCoord['南海诸岛'] || _mapParams['南海诸岛'].textCoord
  450. );
  451. // scale.x : width = 10.51 : 64
  452. var scale = transform.scale.x / 10.5;
  453. var textPosition = [
  454. 32 * scale + leftTop[0],
  455. 83 * scale + leftTop[1]
  456. ];
  457. if (_textFixed['南海诸岛']) {
  458. textPosition[0] += _textFixed['南海诸岛'][0];
  459. textPosition[1] += _textFixed['南海诸岛'][1];
  460. }
  461. province.push({
  462. name : this._nameChange(mapType, '南海诸岛'),
  463. path : _mapParams['南海诸岛'].getPath(leftTop, scale),
  464. position : position,
  465. textX : textPosition[0],
  466. textY : textPosition[1]
  467. });
  468. }
  469. //console.log(JSON.stringify(province));
  470. //console.log(JSON.stringify(this._mapDataMap[mapType].transform));
  471. return province;
  472. },
  473. /**
  474. * 特殊地区投射数据
  475. */
  476. _getSpecialProjectionData : function (mapType, mapData, areaName, mapSize, position) {
  477. //console.log('_getSpecialProjectionData--------------')
  478. // 构造单独的geoJson地图数据
  479. mapData = this._getSubMapData('x|' + areaName, mapData);
  480. // bbox
  481. var normalProjection = require('../util/projection/normal');
  482. var bbox = normalProjection.getBbox(mapData);
  483. //console.log('bbox', bbox)
  484. // transform
  485. var leftTop = this.geo2pos(
  486. mapType,
  487. [mapSize.left, mapSize.top]
  488. );
  489. var rightBottom = this.geo2pos(
  490. mapType,
  491. [mapSize.left + mapSize.width, mapSize.top + mapSize.height]
  492. );
  493. //console.log('leftright' , leftTop, rightBottom);
  494. var width = Math.abs(rightBottom[0] - leftTop[0]);
  495. var height = Math.abs(rightBottom[1] - leftTop[1]);
  496. var mapWidth = bbox.width;
  497. var mapHeight = bbox.height;
  498. //var minScale;
  499. var xScale = (width / 0.75) / mapWidth;
  500. var yScale = height / mapHeight;
  501. if (xScale > yScale) {
  502. xScale = yScale * 0.75;
  503. width = mapWidth * xScale;
  504. }
  505. else {
  506. yScale = xScale;
  507. xScale = yScale * 0.75;
  508. height = mapHeight * yScale;
  509. }
  510. var transform = {
  511. OffsetLeft : leftTop[0],
  512. OffsetTop : leftTop[1],
  513. //width: width,
  514. //height: height,
  515. scale : {
  516. x : xScale,
  517. y : yScale
  518. }
  519. };
  520. //console.log('**',areaName, transform)
  521. var pathArray = normalProjection.geoJson2Path(
  522. mapData, transform
  523. );
  524. //console.log(pathArray)
  525. return this._getSingleProvince(
  526. mapType, pathArray[0], position
  527. );
  528. },
  529. _getSingleProvince : function (mapType, path, position) {
  530. var textPosition;
  531. var name = path.properties.name;
  532. var textFixed = _textFixed[name] || [0, 0];
  533. if (_geoCoord[name]) {
  534. // 经纬度直接定位不加textFixed
  535. textPosition = this.geo2pos(
  536. mapType,
  537. _geoCoord[name]
  538. );
  539. }
  540. else if (path.cp) {
  541. textPosition = [
  542. path.cp[0] + textFixed[0],
  543. path.cp[1] + textFixed[1]
  544. ];
  545. }
  546. else {
  547. var bbox = this._mapDataMap[mapType].bbox;
  548. textPosition = this.geo2pos(
  549. mapType,
  550. [bbox.left + bbox.width / 2, bbox.top + bbox.height / 2]
  551. );
  552. textPosition[0] += textFixed[0];
  553. textPosition[1] += textFixed[1];
  554. }
  555. //console.log(textPosition)
  556. path.name = this._nameChange(mapType, name);
  557. path.position = position;
  558. path.textX = textPosition[0];
  559. path.textY = textPosition[1];
  560. return path;
  561. },
  562. /**
  563. * 获取缩放
  564. */
  565. _getTransform : function (bbox, mapSeries, rate) {
  566. var series = this.series;
  567. var mapLocation;
  568. var x;
  569. var cusX;
  570. var y;
  571. var cusY;
  572. var width;
  573. var height;
  574. var zrWidth = this.zr.getWidth();
  575. var zrHeight = this.zr.getHeight();
  576. //上下左右留空
  577. var padding = Math.round(Math.min(zrWidth, zrHeight) * 0.02);
  578. for (var key in mapSeries) {
  579. mapLocation = series[key].mapLocation || {};
  580. cusX = mapLocation.x || cusX;
  581. cusY = mapLocation.y || cusY;
  582. width = mapLocation.width || width;
  583. height = mapLocation.height || height;
  584. }
  585. //x = isNaN(cusX) ? padding : cusX;
  586. x = this.parsePercent(cusX, zrWidth);
  587. x = isNaN(x) ? padding : x;
  588. //y = isNaN(cusY) ? padding : cusY;
  589. y = this.parsePercent(cusY, zrHeight);
  590. y = isNaN(y) ? padding : y;
  591. width = width == null
  592. ? (zrWidth - x - 2 * padding)
  593. : (this.parsePercent(width, zrWidth));
  594. height = height == null
  595. ? (zrHeight - y - 2 * padding)
  596. : (this.parsePercent(height, zrHeight));
  597. var mapWidth = bbox.width;
  598. var mapHeight = bbox.height;
  599. //var minScale;
  600. var xScale = (width / rate) / mapWidth;
  601. var yScale = height / mapHeight;
  602. if (xScale > yScale) {
  603. //minScale = yScale;
  604. xScale = yScale * rate;
  605. width = mapWidth * xScale;
  606. }
  607. else {
  608. //minScale = xScale;
  609. yScale = xScale;
  610. xScale = yScale * rate;
  611. height = mapHeight * yScale;
  612. }
  613. //console.log(minScale)
  614. //width = mapWidth * minScale;
  615. //height = mapHeight * minScale;
  616. if (isNaN(cusX)) {
  617. cusX = cusX || 'center';
  618. switch (cusX + '') {
  619. case 'center' :
  620. x = Math.floor((zrWidth - width) / 2);
  621. break;
  622. case 'right' :
  623. x = zrWidth - width;
  624. break;
  625. //case 'left' :
  626. //x = padding;
  627. }
  628. }
  629. //console.log(cusX,x,zrWidth,width,'kener')
  630. if (isNaN(cusY)) {
  631. cusY = cusY || 'center';
  632. switch (cusY + '') {
  633. case 'center' :
  634. y = Math.floor((zrHeight - height) / 2);
  635. break;
  636. case 'bottom' :
  637. y = zrHeight - height;
  638. break;
  639. //case 'top' :
  640. //y = padding;
  641. }
  642. }
  643. //console.log(x,y,width,height)
  644. return {
  645. left : x,
  646. top : y,
  647. width: width,
  648. height: height,
  649. //scale : minScale * 50, // wtf 50
  650. baseScale : 1,
  651. scale : {
  652. x : xScale,
  653. y : yScale
  654. }
  655. //translate : [x + width / 2, y + height / 2]
  656. };
  657. },
  658. /**
  659. * 构建地图
  660. * @param {Object} mapData 图形数据
  661. * @param {Object} valueData 用户数据
  662. */
  663. _buildMap : function (mapType, mapData, valueData, mapSeries) {
  664. var series = this.series;
  665. var legend = this.component.legend;
  666. var dataRange = this.component.dataRange;
  667. var seriesName;
  668. var name;
  669. var data;
  670. var value;
  671. var queryTarget;
  672. var color;
  673. var font;
  674. var style;
  675. var highlightStyle;
  676. var shape;
  677. var textShape;
  678. for (var i = 0, l = mapData.length; i < l; i++) {
  679. style = zrUtil.clone(mapData[i]);
  680. highlightStyle = {
  681. name : style.name,
  682. path : style.path,
  683. position : zrUtil.clone(style.position)
  684. };
  685. name = style.name;
  686. data = valueData[name]; // 多系列合并后的数据
  687. if (data) {
  688. queryTarget = [data]; // level 3
  689. seriesName = '';
  690. for (var j = 0, k = data.seriesIndex.length; j < k; j++) {
  691. var serie = series[data.seriesIndex[j]];
  692. // level 2
  693. queryTarget.push(serie);
  694. seriesName += serie.name + ' ';
  695. if (legend
  696. && this._showLegendSymbol[mapType]
  697. && legend.hasColor(serie.name)
  698. ) {
  699. this.shapeList.push(new CircleShape({
  700. zlevel : serie.zlevel,
  701. z : serie.z + 1,
  702. position : zrUtil.clone(style.position),
  703. _mapType : mapType,
  704. /*
  705. _geo : this.pos2geo(
  706. mapType, [style.textX + 3 + j * 7, style.textY - 10]
  707. ),
  708. */
  709. style : {
  710. x : style.textX + 3 + j * 7,
  711. y : style.textY - 10,
  712. r : 3,
  713. color : legend.getColor(
  714. serie.name
  715. )
  716. },
  717. hoverable : false
  718. }));
  719. }
  720. }
  721. value = data.value;
  722. }
  723. else {
  724. data = {
  725. name: name,
  726. value: '-'
  727. };
  728. seriesName = '';
  729. queryTarget = [];
  730. for (var key in mapSeries) {
  731. queryTarget.push(series[key]);
  732. }
  733. value = '-';
  734. }
  735. this.ecTheme.map && queryTarget.push(this.ecTheme.map); // level 1
  736. queryTarget.push(ecConfig.map); // level 1
  737. // 值域控件控制
  738. color = (dataRange && !isNaN(value))
  739. ? dataRange.getColor(value)
  740. : null;
  741. // 常规设置
  742. style.color = style.color
  743. || color
  744. || this.getItemStyleColor(
  745. this.deepQuery(queryTarget, 'itemStyle.normal.color'),
  746. data.seriesIndex, -1, data
  747. )
  748. || this.deepQuery(
  749. queryTarget, 'itemStyle.normal.areaStyle.color'
  750. );
  751. style.strokeColor = style.strokeColor
  752. || this.deepQuery(queryTarget, 'itemStyle.normal.borderColor');
  753. style.lineWidth = style.lineWidth
  754. || this.deepQuery(queryTarget, 'itemStyle.normal.borderWidth');
  755. // 高亮
  756. highlightStyle.color = this.getItemStyleColor(
  757. this.deepQuery(queryTarget, 'itemStyle.emphasis.color'),
  758. data.seriesIndex, -1, data
  759. )
  760. || this.deepQuery(
  761. queryTarget, 'itemStyle.emphasis.areaStyle.color'
  762. )
  763. || style.color;
  764. highlightStyle.strokeColor = this.deepQuery(
  765. queryTarget, 'itemStyle.emphasis.borderColor'
  766. )
  767. || style.strokeColor;
  768. highlightStyle.lineWidth = this.deepQuery(
  769. queryTarget, 'itemStyle.emphasis.borderWidth'
  770. )
  771. || style.lineWidth;
  772. style.brushType = highlightStyle.brushType = style.brushType || 'both';
  773. style.lineJoin = highlightStyle.lineJoin = 'round';
  774. style._name = highlightStyle._name = name;
  775. font = this.deepQuery(queryTarget, 'itemStyle.normal.label.textStyle');
  776. // 文字标签避免覆盖单独一个shape
  777. textShape = {
  778. zlevel : this.getZlevelBase(),
  779. z : this.getZBase() + 1,
  780. //hoverable: this._hoverable[mapType],
  781. //clickable: this._clickable[mapType],
  782. position : zrUtil.clone(style.position),
  783. _mapType : mapType,
  784. _geo : this.pos2geo(
  785. mapType, [style.textX, style.textY]
  786. ),
  787. style : {
  788. brushType : 'fill',
  789. x : style.textX,
  790. y : style.textY,
  791. text : this.getLabelText(name, value, queryTarget, 'normal'),
  792. _name : name,
  793. textAlign : 'center',
  794. color : this.deepQuery(queryTarget, 'itemStyle.normal.label.show')
  795. ? this.deepQuery(
  796. queryTarget,
  797. 'itemStyle.normal.label.textStyle.color'
  798. )
  799. : 'rgba(0,0,0,0)',
  800. textFont : this.getFont(font)
  801. }
  802. };
  803. textShape._style = zrUtil.clone(textShape.style);
  804. textShape.highlightStyle = zrUtil.clone(textShape.style);
  805. if (this.deepQuery(queryTarget, 'itemStyle.emphasis.label.show')) {
  806. textShape.highlightStyle.text = this.getLabelText(
  807. name, value, queryTarget, 'emphasis'
  808. );
  809. textShape.highlightStyle.color = this.deepQuery(
  810. queryTarget,
  811. 'itemStyle.emphasis.label.textStyle.color'
  812. ) || textShape.style.color;
  813. font = this.deepQuery(
  814. queryTarget,
  815. 'itemStyle.emphasis.label.textStyle'
  816. ) || font;
  817. textShape.highlightStyle.textFont = this.getFont(font);
  818. }
  819. else {
  820. textShape.highlightStyle.color = 'rgba(0,0,0,0)';
  821. }
  822. shape = {
  823. zlevel : this.getZlevelBase(),
  824. z : this.getZBase(),
  825. //hoverable: this._hoverable[mapType],
  826. //clickable: this._clickable[mapType],
  827. position : zrUtil.clone(style.position),
  828. style : style,
  829. highlightStyle : highlightStyle,
  830. _style: zrUtil.clone(style),
  831. _mapType: mapType
  832. };
  833. if (style.scale != null) {
  834. shape.scale = zrUtil.clone(style.scale);
  835. }
  836. textShape = new TextShape(textShape);
  837. switch (shape.style.shapeType) {
  838. case 'rectangle' :
  839. shape = new RectangleShape(shape);
  840. break;
  841. case 'line' :
  842. shape = new LineShape(shape);
  843. break;
  844. case 'circle' :
  845. shape = new CircleShape(shape);
  846. break;
  847. case 'polygon' :
  848. shape = new PolygonShape(shape);
  849. break;
  850. case 'ellipse':
  851. shape = new EllipseShape(shape);
  852. break;
  853. default :
  854. shape = new PathShape(shape);
  855. if (shape.buildPathArray) {
  856. shape.style.pathArray = shape.buildPathArray(shape.style.path);
  857. }
  858. break;
  859. }
  860. if (this._selectedMode[mapType] &&
  861. (this._selected[name] && data.selected !== false)
  862. || data.selected === true
  863. ) {
  864. textShape.style = textShape.highlightStyle;
  865. shape.style = shape.highlightStyle;
  866. }
  867. textShape.clickable = shape.clickable =
  868. this._clickable[mapType]
  869. && (data.clickable == null || data.clickable);
  870. if (this._selectedMode[mapType]) {
  871. this._selected[name] = this._selected[name] != null
  872. ? this._selected[name]
  873. : data.selected;
  874. this._mapTypeMap[name] = mapType;
  875. if (data.selectable == null || data.selectable) {
  876. shape.clickable = textShape.clickable = true;
  877. shape.onclick = textShape.onclick = this.shapeHandler.onclick;
  878. }
  879. }
  880. if (this._hoverable[mapType]
  881. && (data.hoverable == null || data.hoverable)
  882. ) {
  883. textShape.hoverable = shape.hoverable = true;
  884. shape.hoverConnect = textShape.id;
  885. textShape.hoverConnect = shape.id;
  886. }
  887. else {
  888. textShape.hoverable = shape.hoverable = false;
  889. }
  890. // console.log(name,shape);
  891. ecData.pack(
  892. textShape,
  893. {
  894. name: seriesName,
  895. tooltip: this.deepQuery(queryTarget, 'tooltip')
  896. },
  897. 0,
  898. data, 0,
  899. name
  900. );
  901. this.shapeList.push(textShape);
  902. ecData.pack(
  903. shape,
  904. {
  905. name: seriesName,
  906. tooltip: this.deepQuery(queryTarget, 'tooltip')
  907. },
  908. 0,
  909. data, 0,
  910. name
  911. );
  912. this.shapeList.push(shape);
  913. }
  914. //console.log(this._selected);
  915. },
  916. // 添加标注
  917. _buildMark : function (mapType, mapSeries) {
  918. this._seriesIndexToMapType = this._seriesIndexToMapType || {};
  919. this.markAttachStyle = this.markAttachStyle || {};
  920. var position = [
  921. this._mapDataMap[mapType].transform.left,
  922. this._mapDataMap[mapType].transform.top
  923. ];
  924. if (mapType == 'none') {
  925. position = [0, 0];
  926. }
  927. for (var sIdx in mapSeries) {
  928. this._seriesIndexToMapType[sIdx] = mapType;
  929. this.markAttachStyle[sIdx] = {
  930. position : position,
  931. _mapType : mapType
  932. };
  933. this.buildMark(sIdx);
  934. }
  935. },
  936. _buildHeatmap: function(mapType) {
  937. var series = this.series;
  938. for (var i = 0, l = series.length; i < l; i++) {
  939. // render heatmap
  940. if (series[i].heatmap) {
  941. // convert geo position to screen position
  942. var data = series[i].heatmap.data;
  943. if (series[i].heatmap.needsTransform === false) {
  944. // baidu map position, does not need transform
  945. var geo = [];
  946. for (var j = 0, len = data.length; j < len; ++j) {
  947. geo.push([data[j][3], data[j][4], data[j][2]]);
  948. }
  949. var pos = [0, 0]
  950. } else {
  951. // other map
  952. var geoData = series[i].heatmap._geoData;
  953. // copy initial geo position
  954. if (geoData === undefined) {
  955. series[i].heatmap._geoData = [];
  956. for (var j = 0, len = data.length; j < len; ++j) {
  957. series[i].heatmap._geoData[j] = data[j];
  958. }
  959. geoData = series[i].heatmap._geoData;
  960. }
  961. var len = data.length;
  962. for (var id = 0; id < len; ++id) {
  963. data[id] = this.geo2pos(mapType,
  964. [geoData[id][0], geoData[id][1]]);
  965. }
  966. var pos = [
  967. this._mapDataMap[mapType].transform.left,
  968. this._mapDataMap[mapType].transform.top
  969. ]
  970. }
  971. var layer = new HeatmapLayer(series[i].heatmap);
  972. var canvas = layer.getCanvas(data[0][3] ? geo : data,
  973. this.zr.getWidth(), this.zr.getHeight())
  974. var image = new ZrImage({
  975. zlevel: this.getZlevelBase(),
  976. z: this.getZBase() + 1,
  977. position: pos,
  978. scale: [1, 1],
  979. hoverable: false,
  980. style: {
  981. x: 0,
  982. y: 0,
  983. image: canvas,
  984. width: canvas.width,
  985. height: canvas.height
  986. }
  987. });
  988. image.type = 'heatmap';
  989. image._mapType = mapType;
  990. this.shapeList.push(image);
  991. this.zr.addShape(image);
  992. }
  993. }
  994. },
  995. // 位置转换
  996. getMarkCoord : function (seriesIndex, mpData) {
  997. return (mpData.geoCoord || _geoCoord[mpData.name])
  998. ? this.geo2pos(
  999. this._seriesIndexToMapType[seriesIndex],
  1000. mpData.geoCoord || _geoCoord[mpData.name]
  1001. )
  1002. : [0, 0];
  1003. },
  1004. getMarkGeo : function(mpData) {
  1005. return mpData.geoCoord || _geoCoord[mpData.name];
  1006. },
  1007. _nameChange : function (mapType, name) {
  1008. return this._nameMap[mapType][name] || name;
  1009. },
  1010. /**
  1011. * 根据lable.format计算label text
  1012. */
  1013. getLabelText : function (name, value, queryTarget, status) {
  1014. var formatter = this.deepQuery(
  1015. queryTarget,
  1016. 'itemStyle.' + status + '.label.formatter'
  1017. );
  1018. if (formatter) {
  1019. if (typeof formatter == 'function') {
  1020. return formatter.call(
  1021. this.myChart,
  1022. name,
  1023. value
  1024. );
  1025. }
  1026. else if (typeof formatter == 'string') {
  1027. formatter = formatter.replace('{a}','{a0}')
  1028. .replace('{b}','{b0}');
  1029. formatter = formatter.replace('{a0}', name)
  1030. .replace('{b0}', value);
  1031. return formatter;
  1032. }
  1033. }
  1034. else {
  1035. return name;
  1036. }
  1037. },
  1038. _findMapTypeByPos : function (mx, my) {
  1039. var transform;
  1040. var left;
  1041. var top;
  1042. var width;
  1043. var height;
  1044. for (var mapType in this._mapDataMap) {
  1045. transform = this._mapDataMap[mapType].transform;
  1046. if (!transform || !this._roamMap[mapType] || !this._activeMapType[mapType]) {
  1047. continue;
  1048. }
  1049. left = transform.left;
  1050. top = transform.top;
  1051. width = transform.width;
  1052. height = transform.height;
  1053. if (mx >= left
  1054. && mx <= (left + width)
  1055. && my >= top
  1056. && my <= (top + height)
  1057. ) {
  1058. return mapType;
  1059. }
  1060. }
  1061. return;
  1062. },
  1063. /**
  1064. * 滚轮缩放
  1065. */
  1066. __onmousewheel : function (params) {
  1067. if (this.shapeList.length <= 0) {
  1068. return;
  1069. }
  1070. for (var i = 0, l = this.shapeList.length; i < l; i++) {
  1071. var shape = this.shapeList[i];
  1072. // If any shape is still animating
  1073. if (shape.__animating) {
  1074. return;
  1075. }
  1076. }
  1077. var event = params.event;
  1078. var mx = zrEvent.getX(event);
  1079. var my = zrEvent.getY(event);
  1080. var delta;
  1081. var eventDelta = zrEvent.getDelta(event);
  1082. //eventDelta = eventDelta > 0 ? (-1) : 1;
  1083. var mapType;
  1084. var mapTypeControl = params.mapTypeControl;
  1085. if (!mapTypeControl) {
  1086. mapTypeControl = {};
  1087. mapType = this._findMapTypeByPos(mx, my);
  1088. if (mapType && this._roamMap[mapType] && this._roamMap[mapType] != 'move') {
  1089. mapTypeControl[mapType] = true;
  1090. }
  1091. }
  1092. function scalePolyline(shapeStyle, delta) {
  1093. for (var i = 0; i < shapeStyle.pointList.length; i++) {
  1094. var point = shapeStyle.pointList[i];
  1095. point[0] *= delta;
  1096. point[1] *= delta;
  1097. }
  1098. //If smoothness > 0
  1099. var controlPointList = shapeStyle.controlPointList;
  1100. if (controlPointList) {
  1101. for (var i = 0; i < controlPointList.length; i++) {
  1102. var point = controlPointList[i];
  1103. point[0] *= delta;
  1104. point[1] *= delta;
  1105. }
  1106. }
  1107. }
  1108. function scaleMarkline(shapeStyle, delta) {
  1109. shapeStyle.xStart *= delta;
  1110. shapeStyle.yStart *= delta;
  1111. shapeStyle.xEnd *= delta;
  1112. shapeStyle.yEnd *= delta;
  1113. if (shapeStyle.cpX1 != null) {
  1114. shapeStyle.cpX1 *= delta;
  1115. shapeStyle.cpY1 *= delta;
  1116. }
  1117. }
  1118. var haveScale = false;
  1119. for (mapType in mapTypeControl) {
  1120. if (mapTypeControl[mapType]) {
  1121. haveScale = true;
  1122. var transform = this._mapDataMap[mapType].transform;
  1123. var left = transform.left;
  1124. var top = transform.top;
  1125. var width = transform.width;
  1126. var height = transform.height;
  1127. // 位置转经纬度
  1128. var geoAndPos = this.pos2geo(mapType, [mx - left, my - top]);
  1129. if (eventDelta > 0) {
  1130. delta = 1.2; // 放大
  1131. if (this._scaleLimitMap[mapType].max != null
  1132. && transform.baseScale >= this._scaleLimitMap[mapType].max
  1133. ) {
  1134. continue; // 缩放限制
  1135. }
  1136. }
  1137. else {
  1138. delta = 1 / 1.2; // 缩小
  1139. if (this._scaleLimitMap[mapType].min != null
  1140. && transform.baseScale <= this._scaleLimitMap[mapType].min
  1141. ) {
  1142. continue; // 缩放限制
  1143. }
  1144. }
  1145. transform.baseScale *= delta;
  1146. transform.scale.x *= delta;
  1147. transform.scale.y *= delta;
  1148. transform.width = width * delta;
  1149. transform.height = height * delta;
  1150. this._mapDataMap[mapType].hasRoam = true;
  1151. this._mapDataMap[mapType].transform = transform;
  1152. // 经纬度转位置
  1153. geoAndPos = this.geo2pos(mapType, geoAndPos);
  1154. // 保持视觉中心
  1155. transform.left -= geoAndPos[0] - (mx - left);
  1156. transform.top -= geoAndPos[1] - (my - top);
  1157. this._mapDataMap[mapType].transform = transform;
  1158. this.clearEffectShape(true);
  1159. for (var i = 0, l = this.shapeList.length; i < l; i++) {
  1160. var shape = this.shapeList[i];
  1161. if(shape._mapType == mapType) {
  1162. var shapeType = shape.type;
  1163. var shapeStyle = shape.style;
  1164. shape.position[0] = transform.left;
  1165. shape.position[1] = transform.top;
  1166. switch (shapeType) {
  1167. case 'path':
  1168. case 'symbol':
  1169. case 'circle':
  1170. case 'rectangle':
  1171. case 'polygon':
  1172. case 'line':
  1173. case 'ellipse':
  1174. case 'heatmap':
  1175. shape.scale[0] *= delta;
  1176. shape.scale[1] *= delta;
  1177. break;
  1178. case 'mark-line':
  1179. scaleMarkline(shapeStyle, delta);
  1180. break;
  1181. case 'polyline':
  1182. scalePolyline(shapeStyle, delta);
  1183. break;
  1184. case 'shape-bundle':
  1185. for (var j = 0; j < shapeStyle.shapeList.length; j++) {
  1186. var subShape = shapeStyle.shapeList[j];
  1187. if (subShape.type == 'mark-line') {
  1188. scaleMarkline(subShape.style, delta);
  1189. }
  1190. else if (subShape.type == 'polyline') {
  1191. scalePolyline(subShape.style, delta);
  1192. }
  1193. }
  1194. break;
  1195. case 'icon':
  1196. case 'image':
  1197. geoAndPos = this.geo2pos(mapType, shape._geo);
  1198. shapeStyle.x = shapeStyle._x =
  1199. geoAndPos[0] - shapeStyle.width / 2;
  1200. shapeStyle.y = shapeStyle._y =
  1201. geoAndPos[1] - shapeStyle.height / 2;
  1202. break;
  1203. default:
  1204. geoAndPos = this.geo2pos(mapType, shape._geo);
  1205. shapeStyle.x = geoAndPos[0];
  1206. shapeStyle.y = geoAndPos[1];
  1207. if (shapeType == 'text') {
  1208. shape._style.x = shape.highlightStyle.x
  1209. = geoAndPos[0];
  1210. shape._style.y = shape.highlightStyle.y
  1211. = geoAndPos[1];
  1212. }
  1213. }
  1214. this.zr.modShape(shape.id);
  1215. }
  1216. }
  1217. }
  1218. }
  1219. if (haveScale) {
  1220. zrEvent.stop(event);
  1221. this.zr.refreshNextFrame();
  1222. var self = this;
  1223. clearTimeout(this._refreshDelayTicket);
  1224. this._refreshDelayTicket = setTimeout(
  1225. function(){
  1226. self && self.shapeList && self.animationEffect();
  1227. },
  1228. 100
  1229. );
  1230. this.messageCenter.dispatch(
  1231. ecConfig.EVENT.MAP_ROAM,
  1232. params.event,
  1233. {type : 'scale'},
  1234. this.myChart
  1235. );
  1236. }
  1237. },
  1238. __onmousedown : function (params) {
  1239. if (this.shapeList.length <= 0) {
  1240. return;
  1241. }
  1242. var target = params.target;
  1243. if (target && target.draggable) {
  1244. return;
  1245. }
  1246. var event = params.event;
  1247. var mx = zrEvent.getX(event);
  1248. var my = zrEvent.getY(event);
  1249. var mapType = this._findMapTypeByPos(mx, my);
  1250. if (mapType && this._roamMap[mapType] && this._roamMap[mapType] != 'scale') {
  1251. this._mousedown = true;
  1252. this._mx = mx;
  1253. this._my = my;
  1254. this._curMapType = mapType;
  1255. this.zr.on(zrConfig.EVENT.MOUSEUP, this._onmouseup);
  1256. var self = this;
  1257. setTimeout(function (){
  1258. self.zr.on(zrConfig.EVENT.MOUSEMOVE, self._onmousemove);
  1259. },100);
  1260. }
  1261. },
  1262. __onmousemove : function (params) {
  1263. if (!this._mousedown || !this._isAlive) {
  1264. return;
  1265. }
  1266. var event = params.event;
  1267. var mx = zrEvent.getX(event);
  1268. var my = zrEvent.getY(event);
  1269. var transform = this._mapDataMap[this._curMapType].transform;
  1270. transform.hasRoam = true;
  1271. transform.left -= this._mx - mx;
  1272. transform.top -= this._my - my;
  1273. this._mx = mx;
  1274. this._my = my;
  1275. this._mapDataMap[this._curMapType].transform = transform;
  1276. for (var i = 0, l = this.shapeList.length; i < l; i++) {
  1277. if(this.shapeList[i]._mapType == this._curMapType) {
  1278. this.shapeList[i].position[0] = transform.left;
  1279. this.shapeList[i].position[1] = transform.top;
  1280. this.zr.modShape(this.shapeList[i].id);
  1281. }
  1282. }
  1283. this.messageCenter.dispatch(
  1284. ecConfig.EVENT.MAP_ROAM,
  1285. params.event,
  1286. {type : 'move'},
  1287. this.myChart
  1288. );
  1289. this.clearEffectShape(true);
  1290. this.zr.refreshNextFrame();
  1291. this._justMove = true;
  1292. zrEvent.stop(event);
  1293. },
  1294. __onmouseup : function (params) {
  1295. var event = params.event;
  1296. this._mx = zrEvent.getX(event);
  1297. this._my = zrEvent.getY(event);
  1298. this._mousedown = false;
  1299. var self = this;
  1300. setTimeout(function (){
  1301. self._justMove && self.animationEffect();
  1302. self._justMove = false;
  1303. self.zr.un(zrConfig.EVENT.MOUSEMOVE, self._onmousemove);
  1304. self.zr.un(zrConfig.EVENT.MOUSEUP, self._onmouseup);
  1305. },120);
  1306. },
  1307. /**
  1308. * 漫游组件事件响应
  1309. */
  1310. __onroamcontroller: function(params) {
  1311. var event = params.event;
  1312. event.zrenderX = this.zr.getWidth() / 2;
  1313. event.zrenderY = this.zr.getHeight() / 2;
  1314. var mapTypeControl = params.mapTypeControl;
  1315. var top = 0;
  1316. var left = 0;
  1317. var step = params.step;
  1318. switch(params.roamType) {
  1319. case 'scaleUp':
  1320. event.zrenderDelta = 1;
  1321. this.__onmousewheel({
  1322. event: event,
  1323. mapTypeControl: mapTypeControl
  1324. });
  1325. return;
  1326. case 'scaleDown':
  1327. event.zrenderDelta = -1;
  1328. this.__onmousewheel({
  1329. event: event,
  1330. mapTypeControl: mapTypeControl
  1331. });
  1332. return;
  1333. case 'up':
  1334. top = -step;
  1335. break;
  1336. case 'down':
  1337. top = step;
  1338. break;
  1339. case 'left':
  1340. left = -step;
  1341. break;
  1342. case 'right':
  1343. left = step;
  1344. break;
  1345. }
  1346. var transform;
  1347. var curMapType;
  1348. for (curMapType in mapTypeControl) {
  1349. if (!this._mapDataMap[curMapType] || !this._activeMapType[curMapType]) {
  1350. continue;
  1351. }
  1352. transform = this._mapDataMap[curMapType].transform;
  1353. transform.hasRoam = true;
  1354. transform.left -= left;
  1355. transform.top -= top;
  1356. this._mapDataMap[curMapType].transform = transform;
  1357. }
  1358. for (var i = 0, l = this.shapeList.length; i < l; i++) {
  1359. curMapType = this.shapeList[i]._mapType;
  1360. if (!mapTypeControl[curMapType] || !this._activeMapType[curMapType]) {
  1361. continue;
  1362. }
  1363. transform = this._mapDataMap[curMapType].transform;
  1364. this.shapeList[i].position[0] = transform.left;
  1365. this.shapeList[i].position[1] = transform.top;
  1366. this.zr.modShape(this.shapeList[i].id);
  1367. }
  1368. this.messageCenter.dispatch(
  1369. ecConfig.EVENT.MAP_ROAM,
  1370. params.event,
  1371. {type : 'move'},
  1372. this.myChart
  1373. );
  1374. this.clearEffectShape(true);
  1375. this.zr.refreshNextFrame();
  1376. clearTimeout(this.dircetionTimer);
  1377. var self = this;
  1378. this.dircetionTimer = setTimeout(function() {
  1379. self.animationEffect();
  1380. }, 150);
  1381. },
  1382. /**
  1383. * dataRange hoverlink 事件响应
  1384. */
  1385. __ondrhoverlink : function(param) {
  1386. var curMapType;
  1387. var value;
  1388. for (var i = 0, l = this.shapeList.length; i < l; i++) {
  1389. curMapType = this.shapeList[i]._mapType;
  1390. if (!this._hoverLinkMap[curMapType] || !this._activeMapType[curMapType]) {
  1391. continue;
  1392. }
  1393. value = ecData.get(this.shapeList[i], 'value');
  1394. if (value != null && value >= param.valueMin && value <= param.valueMax) {
  1395. this.zr.addHoverShape(this.shapeList[i]);
  1396. }
  1397. }
  1398. },
  1399. /**
  1400. * 点击响应
  1401. */
  1402. onclick : function (params) {
  1403. if (!this.isClick || !params.target || this._justMove || params.target.type == 'icon') {
  1404. // 没有在当前实例上发生点击直接返回
  1405. return;
  1406. }
  1407. this.isClick = false;
  1408. var target = params.target;
  1409. var name = target.style._name;
  1410. var len = this.shapeList.length;
  1411. var mapType = target._mapType || '';
  1412. if (this._selectedMode[mapType] == 'single') {
  1413. for (var p in this._selected) {
  1414. // 同一地图类型
  1415. if (this._selected[p] && this._mapTypeMap[p] == mapType) {
  1416. // 复位那些生效shape(包括文字)
  1417. for (var i = 0; i < len; i++) {
  1418. if (this.shapeList[i].style._name == p
  1419. && this.shapeList[i]._mapType == mapType
  1420. ) {
  1421. this.shapeList[i].style = this.shapeList[i]._style;
  1422. this.zr.modShape(this.shapeList[i].id);
  1423. }
  1424. }
  1425. p != name && (this._selected[p] = false);
  1426. }
  1427. }
  1428. }
  1429. this._selected[name] = !this._selected[name];
  1430. // 更新当前点击shape(包括文字)
  1431. for (var i = 0; i < len; i++) {
  1432. if (this.shapeList[i].style._name == name
  1433. && this.shapeList[i]._mapType == mapType
  1434. ) {
  1435. if (this._selected[name]) {
  1436. this.shapeList[i].style = this.shapeList[i].highlightStyle;
  1437. }
  1438. else {
  1439. this.shapeList[i].style = this.shapeList[i]._style;
  1440. }
  1441. this.zr.modShape(this.shapeList[i].id);
  1442. }
  1443. }
  1444. this.messageCenter.dispatch(
  1445. ecConfig.EVENT.MAP_SELECTED,
  1446. params.event,
  1447. {
  1448. selected : this._selected,
  1449. target : name
  1450. },
  1451. this.myChart
  1452. );
  1453. this.zr.refreshNextFrame();
  1454. var self = this;
  1455. setTimeout(function(){
  1456. self.zr.trigger(
  1457. zrConfig.EVENT.MOUSEMOVE,
  1458. params.event
  1459. );
  1460. },100);
  1461. },
  1462. /**
  1463. * 刷新
  1464. */
  1465. refresh : function (newOption) {
  1466. if (newOption) {
  1467. this.option = newOption;
  1468. this.series = newOption.series;
  1469. }
  1470. if (this._mapDataRequireCounter > 0) {
  1471. this.clear();
  1472. }
  1473. else {
  1474. this.backupShapeList();
  1475. }
  1476. this._buildShape();
  1477. this.zr.refreshHover();
  1478. },
  1479. /**
  1480. * 值域响应
  1481. * @param {Object} param
  1482. * @param {Object} status
  1483. */
  1484. ondataRange : function (param, status) {
  1485. if (this.component.dataRange) {
  1486. this.refresh();
  1487. status.needRefresh = true;
  1488. }
  1489. return;
  1490. },
  1491. /**
  1492. * 平面坐标转经纬度
  1493. */
  1494. pos2geo : function (mapType, p) {
  1495. if (!this._mapDataMap[mapType].transform) {
  1496. return null;
  1497. }
  1498. return this._mapDataMap[mapType].projection.pos2geo(
  1499. this._mapDataMap[mapType].transform, p
  1500. );
  1501. },
  1502. /**
  1503. * 公开接口 : 平面坐标转经纬度
  1504. */
  1505. getGeoByPos : function (mapType, p) {
  1506. if (!this._mapDataMap[mapType].transform) {
  1507. return null;
  1508. }
  1509. var position = [
  1510. this._mapDataMap[mapType].transform.left,
  1511. this._mapDataMap[mapType].transform.top
  1512. ];
  1513. if (p instanceof Array) {
  1514. p[0] -= position[0];
  1515. p[1] -= position[1];
  1516. }
  1517. else {
  1518. p.x -= position[0];
  1519. p.y -= position[1];
  1520. }
  1521. return this.pos2geo(mapType, p);
  1522. },
  1523. /**
  1524. * 经纬度转平面坐标
  1525. * @param {Object} p
  1526. */
  1527. geo2pos : function (mapType, p) {
  1528. if (!this._mapDataMap[mapType].transform) {
  1529. return null;
  1530. }
  1531. return this._mapDataMap[mapType].projection.geo2pos(
  1532. this._mapDataMap[mapType].transform, p
  1533. );
  1534. },
  1535. /**
  1536. * 公开接口 : 经纬度转平面坐标
  1537. */
  1538. getPosByGeo : function (mapType, p) {
  1539. if (!this._mapDataMap[mapType].transform) {
  1540. return null;
  1541. }
  1542. var pos = this.geo2pos(mapType, p);
  1543. pos[0] += this._mapDataMap[mapType].transform.left;
  1544. pos[1] += this._mapDataMap[mapType].transform.top;
  1545. return pos;
  1546. },
  1547. /**
  1548. * 公开接口 : 地图参考坐标
  1549. */
  1550. getMapPosition : function (mapType) {
  1551. if (!this._mapDataMap[mapType].transform) {
  1552. return null;
  1553. }
  1554. return [
  1555. this._mapDataMap[mapType].transform.left,
  1556. this._mapDataMap[mapType].transform.top
  1557. ];
  1558. },
  1559. /*
  1560. appendShape : function (mapType, shapeList) {
  1561. shapeList = shapeList instanceof Array
  1562. ? shapeList : [shapeList];
  1563. for (var i = 0, l = shapeList.length; i < l; i++) {
  1564. if (typeof shapeList[i].zlevel == 'undefined') {
  1565. shapeList[i].zlevel = this.getZlevelBase();
  1566. shapeList[i].z = this.getZBase() + 1;
  1567. }
  1568. shapeList[i]._mapType = mapType;
  1569. this.shapeList.push(shapeList[i]);
  1570. this.zr.addShape(shapeList[i]);
  1571. }
  1572. this.zr.refresh();
  1573. },
  1574. */
  1575. /**
  1576. * 释放后实例不可用
  1577. */
  1578. onbeforDispose : function () {
  1579. this._isAlive = false;
  1580. this.zr.un(zrConfig.EVENT.MOUSEWHEEL, this._onmousewheel);
  1581. this.zr.un(zrConfig.EVENT.MOUSEDOWN, this._onmousedown);
  1582. this.messageCenter.unbind(
  1583. ecConfig.EVENT.ROAMCONTROLLER, this._onroamcontroller
  1584. );
  1585. this.messageCenter.unbind(
  1586. ecConfig.EVENT.DATA_RANGE_HOVERLINK, this._ondrhoverlink
  1587. );
  1588. }
  1589. };
  1590. zrUtil.inherits(Map, ChartBase);
  1591. // 图表注册
  1592. require('../chart').define('map', Map);
  1593. return Map;
  1594. });