scatter.js 67 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588
  1. define('echarts/chart/scatter', [
  2. 'require',
  3. './base',
  4. '../util/shape/Symbol',
  5. '../component/axis',
  6. '../component/grid',
  7. '../component/dataZoom',
  8. '../component/dataRange',
  9. '../config',
  10. 'zrender/tool/util',
  11. 'zrender/tool/color',
  12. '../chart'
  13. ], function (require) {
  14. var ChartBase = require('./base');
  15. var SymbolShape = require('../util/shape/Symbol');
  16. require('../component/axis');
  17. require('../component/grid');
  18. require('../component/dataZoom');
  19. require('../component/dataRange');
  20. var ecConfig = require('../config');
  21. ecConfig.scatter = {
  22. zlevel: 0,
  23. z: 2,
  24. clickable: true,
  25. legendHoverLink: true,
  26. xAxisIndex: 0,
  27. yAxisIndex: 0,
  28. symbolSize: 4,
  29. large: false,
  30. largeThreshold: 2000,
  31. itemStyle: {
  32. normal: { label: { show: false } },
  33. emphasis: { label: { show: false } }
  34. }
  35. };
  36. var zrUtil = require('zrender/tool/util');
  37. var zrColor = require('zrender/tool/color');
  38. function Scatter(ecTheme, messageCenter, zr, option, myChart) {
  39. ChartBase.call(this, ecTheme, messageCenter, zr, option, myChart);
  40. this.refresh(option);
  41. }
  42. Scatter.prototype = {
  43. type: ecConfig.CHART_TYPE_SCATTER,
  44. _buildShape: function () {
  45. var series = this.series;
  46. this._sIndex2ColorMap = {};
  47. this._symbol = this.option.symbolList;
  48. this._sIndex2ShapeMap = {};
  49. this.selectedMap = {};
  50. this.xMarkMap = {};
  51. var legend = this.component.legend;
  52. var seriesArray = [];
  53. var serie;
  54. var serieName;
  55. var iconShape;
  56. var iconType;
  57. for (var i = 0, l = series.length; i < l; i++) {
  58. serie = series[i];
  59. serieName = serie.name;
  60. if (serie.type === ecConfig.CHART_TYPE_SCATTER) {
  61. series[i] = this.reformOption(series[i]);
  62. this.legendHoverLink = series[i].legendHoverLink || this.legendHoverLink;
  63. this._sIndex2ShapeMap[i] = this.query(serie, 'symbol') || this._symbol[i % this._symbol.length];
  64. if (legend) {
  65. this.selectedMap[serieName] = legend.isSelected(serieName);
  66. this._sIndex2ColorMap[i] = zrColor.alpha(legend.getColor(serieName), 0.5);
  67. iconShape = legend.getItemShape(serieName);
  68. if (iconShape) {
  69. var iconType = this._sIndex2ShapeMap[i];
  70. iconShape.style.brushType = iconType.match('empty') ? 'stroke' : 'both';
  71. iconType = iconType.replace('empty', '').toLowerCase();
  72. if (iconType.match('rectangle')) {
  73. iconShape.style.x += Math.round((iconShape.style.width - iconShape.style.height) / 2);
  74. iconShape.style.width = iconShape.style.height;
  75. }
  76. if (iconType.match('star')) {
  77. iconShape.style.n = iconType.replace('star', '') - 0 || 5;
  78. iconType = 'star';
  79. }
  80. if (iconType.match('image')) {
  81. iconShape.style.image = iconType.replace(new RegExp('^image:\\/\\/'), '');
  82. iconShape.style.x += Math.round((iconShape.style.width - iconShape.style.height) / 2);
  83. iconShape.style.width = iconShape.style.height;
  84. iconType = 'image';
  85. }
  86. iconShape.style.iconType = iconType;
  87. legend.setItemShape(serieName, iconShape);
  88. }
  89. } else {
  90. this.selectedMap[serieName] = true;
  91. this._sIndex2ColorMap[i] = zrColor.alpha(this.zr.getColor(i), 0.5);
  92. }
  93. if (this.selectedMap[serieName]) {
  94. seriesArray.push(i);
  95. }
  96. }
  97. }
  98. this._buildSeries(seriesArray);
  99. this.addShapeList();
  100. },
  101. _buildSeries: function (seriesArray) {
  102. if (seriesArray.length === 0) {
  103. return;
  104. }
  105. var series = this.series;
  106. var seriesIndex;
  107. var serie;
  108. var data;
  109. var value;
  110. var xAxis;
  111. var yAxis;
  112. var pointList = {};
  113. var x;
  114. var y;
  115. for (var j = 0, k = seriesArray.length; j < k; j++) {
  116. seriesIndex = seriesArray[j];
  117. serie = series[seriesIndex];
  118. if (serie.data.length === 0) {
  119. continue;
  120. }
  121. xAxis = this.component.xAxis.getAxis(serie.xAxisIndex || 0);
  122. yAxis = this.component.yAxis.getAxis(serie.yAxisIndex || 0);
  123. pointList[seriesIndex] = [];
  124. for (var i = 0, l = serie.data.length; i < l; i++) {
  125. data = serie.data[i];
  126. value = this.getDataFromOption(data, '-');
  127. if (value === '-' || value.length < 2) {
  128. continue;
  129. }
  130. x = xAxis.getCoord(value[0]);
  131. y = yAxis.getCoord(value[1]);
  132. pointList[seriesIndex].push([
  133. x,
  134. y,
  135. i,
  136. data.name || ''
  137. ]);
  138. }
  139. this.xMarkMap[seriesIndex] = this._markMap(xAxis, yAxis, serie.data, pointList[seriesIndex]);
  140. this.buildMark(seriesIndex);
  141. }
  142. this._buildPointList(pointList);
  143. },
  144. _markMap: function (xAxis, yAxis, data, pointList) {
  145. var xMarkMap = {
  146. min0: Number.POSITIVE_INFINITY,
  147. max0: Number.NEGATIVE_INFINITY,
  148. sum0: 0,
  149. counter0: 0,
  150. average0: 0,
  151. min1: Number.POSITIVE_INFINITY,
  152. max1: Number.NEGATIVE_INFINITY,
  153. sum1: 0,
  154. counter1: 0,
  155. average1: 0
  156. };
  157. var value;
  158. for (var i = 0, l = pointList.length; i < l; i++) {
  159. value = data[pointList[i][2]].value || data[pointList[i][2]];
  160. if (xMarkMap.min0 > value[0]) {
  161. xMarkMap.min0 = value[0];
  162. xMarkMap.minY0 = pointList[i][1];
  163. xMarkMap.minX0 = pointList[i][0];
  164. }
  165. if (xMarkMap.max0 < value[0]) {
  166. xMarkMap.max0 = value[0];
  167. xMarkMap.maxY0 = pointList[i][1];
  168. xMarkMap.maxX0 = pointList[i][0];
  169. }
  170. xMarkMap.sum0 += value[0];
  171. xMarkMap.counter0++;
  172. if (xMarkMap.min1 > value[1]) {
  173. xMarkMap.min1 = value[1];
  174. xMarkMap.minY1 = pointList[i][1];
  175. xMarkMap.minX1 = pointList[i][0];
  176. }
  177. if (xMarkMap.max1 < value[1]) {
  178. xMarkMap.max1 = value[1];
  179. xMarkMap.maxY1 = pointList[i][1];
  180. xMarkMap.maxX1 = pointList[i][0];
  181. }
  182. xMarkMap.sum1 += value[1];
  183. xMarkMap.counter1++;
  184. }
  185. var gridX = this.component.grid.getX();
  186. var gridXend = this.component.grid.getXend();
  187. var gridY = this.component.grid.getY();
  188. var gridYend = this.component.grid.getYend();
  189. xMarkMap.average0 = xMarkMap.sum0 / xMarkMap.counter0;
  190. var x = xAxis.getCoord(xMarkMap.average0);
  191. xMarkMap.averageLine0 = [
  192. [
  193. x,
  194. gridYend
  195. ],
  196. [
  197. x,
  198. gridY
  199. ]
  200. ];
  201. xMarkMap.minLine0 = [
  202. [
  203. xMarkMap.minX0,
  204. gridYend
  205. ],
  206. [
  207. xMarkMap.minX0,
  208. gridY
  209. ]
  210. ];
  211. xMarkMap.maxLine0 = [
  212. [
  213. xMarkMap.maxX0,
  214. gridYend
  215. ],
  216. [
  217. xMarkMap.maxX0,
  218. gridY
  219. ]
  220. ];
  221. xMarkMap.average1 = xMarkMap.sum1 / xMarkMap.counter1;
  222. var y = yAxis.getCoord(xMarkMap.average1);
  223. xMarkMap.averageLine1 = [
  224. [
  225. gridX,
  226. y
  227. ],
  228. [
  229. gridXend,
  230. y
  231. ]
  232. ];
  233. xMarkMap.minLine1 = [
  234. [
  235. gridX,
  236. xMarkMap.minY1
  237. ],
  238. [
  239. gridXend,
  240. xMarkMap.minY1
  241. ]
  242. ];
  243. xMarkMap.maxLine1 = [
  244. [
  245. gridX,
  246. xMarkMap.maxY1
  247. ],
  248. [
  249. gridXend,
  250. xMarkMap.maxY1
  251. ]
  252. ];
  253. return xMarkMap;
  254. },
  255. _buildPointList: function (pointList) {
  256. var series = this.series;
  257. var serie;
  258. var seriesPL;
  259. var singlePoint;
  260. var shape;
  261. for (var seriesIndex in pointList) {
  262. serie = series[seriesIndex];
  263. seriesPL = pointList[seriesIndex];
  264. if (serie.large && serie.data.length > serie.largeThreshold) {
  265. this.shapeList.push(this._getLargeSymbol(seriesPL, this.getItemStyleColor(this.query(serie, 'itemStyle.normal.color'), seriesIndex, -1) || this._sIndex2ColorMap[seriesIndex]));
  266. continue;
  267. }
  268. for (var i = 0, l = seriesPL.length; i < l; i++) {
  269. singlePoint = seriesPL[i];
  270. shape = this._getSymbol(seriesIndex, singlePoint[2], singlePoint[3], singlePoint[0], singlePoint[1]);
  271. shape && this.shapeList.push(shape);
  272. }
  273. }
  274. },
  275. _getSymbol: function (seriesIndex, dataIndex, name, x, y) {
  276. var series = this.series;
  277. var serie = series[seriesIndex];
  278. var data = serie.data[dataIndex];
  279. var dataRange = this.component.dataRange;
  280. var rangColor;
  281. if (dataRange) {
  282. rangColor = isNaN(data[2]) ? this._sIndex2ColorMap[seriesIndex] : dataRange.getColor(data[2]);
  283. if (!rangColor) {
  284. return null;
  285. }
  286. } else {
  287. rangColor = this._sIndex2ColorMap[seriesIndex];
  288. }
  289. var itemShape = this.getSymbolShape(serie, seriesIndex, data, dataIndex, name, x, y, this._sIndex2ShapeMap[seriesIndex], rangColor, 'rgba(0,0,0,0)', 'vertical');
  290. itemShape.zlevel = this.getZlevelBase();
  291. itemShape.z = this.getZBase();
  292. itemShape._main = true;
  293. return itemShape;
  294. },
  295. _getLargeSymbol: function (pointList, nColor) {
  296. return new SymbolShape({
  297. zlevel: this.getZlevelBase(),
  298. z: this.getZBase(),
  299. _main: true,
  300. hoverable: false,
  301. style: {
  302. pointList: pointList,
  303. color: nColor,
  304. strokeColor: nColor
  305. },
  306. highlightStyle: { pointList: [] }
  307. });
  308. },
  309. getMarkCoord: function (seriesIndex, mpData) {
  310. var serie = this.series[seriesIndex];
  311. var xMarkMap = this.xMarkMap[seriesIndex];
  312. var xAxis = this.component.xAxis.getAxis(serie.xAxisIndex);
  313. var yAxis = this.component.yAxis.getAxis(serie.yAxisIndex);
  314. var pos;
  315. if (mpData.type && (mpData.type === 'max' || mpData.type === 'min' || mpData.type === 'average')) {
  316. var valueIndex = mpData.valueIndex != null ? mpData.valueIndex : 1;
  317. pos = [
  318. xMarkMap[mpData.type + 'X' + valueIndex],
  319. xMarkMap[mpData.type + 'Y' + valueIndex],
  320. xMarkMap[mpData.type + 'Line' + valueIndex],
  321. xMarkMap[mpData.type + valueIndex]
  322. ];
  323. } else {
  324. pos = [
  325. typeof mpData.xAxis != 'string' && xAxis.getCoordByIndex ? xAxis.getCoordByIndex(mpData.xAxis || 0) : xAxis.getCoord(mpData.xAxis || 0),
  326. typeof mpData.yAxis != 'string' && yAxis.getCoordByIndex ? yAxis.getCoordByIndex(mpData.yAxis || 0) : yAxis.getCoord(mpData.yAxis || 0)
  327. ];
  328. }
  329. return pos;
  330. },
  331. refresh: function (newOption) {
  332. if (newOption) {
  333. this.option = newOption;
  334. this.series = newOption.series;
  335. }
  336. this.backupShapeList();
  337. this._buildShape();
  338. },
  339. ondataRange: function (param, status) {
  340. if (this.component.dataRange) {
  341. this.refresh();
  342. status.needRefresh = true;
  343. }
  344. return;
  345. }
  346. };
  347. zrUtil.inherits(Scatter, ChartBase);
  348. require('../chart').define('scatter', Scatter);
  349. return Scatter;
  350. });define('echarts/component/dataRange', [
  351. 'require',
  352. './base',
  353. 'zrender/shape/Text',
  354. 'zrender/shape/Rectangle',
  355. '../util/shape/HandlePolygon',
  356. '../config',
  357. 'zrender/tool/util',
  358. 'zrender/tool/event',
  359. 'zrender/tool/area',
  360. 'zrender/tool/color',
  361. '../component'
  362. ], function (require) {
  363. var Base = require('./base');
  364. var TextShape = require('zrender/shape/Text');
  365. var RectangleShape = require('zrender/shape/Rectangle');
  366. var HandlePolygonShape = require('../util/shape/HandlePolygon');
  367. var ecConfig = require('../config');
  368. ecConfig.dataRange = {
  369. zlevel: 0,
  370. z: 4,
  371. show: true,
  372. orient: 'vertical',
  373. x: 'left',
  374. y: 'bottom',
  375. backgroundColor: 'rgba(0,0,0,0)',
  376. borderColor: '#ccc',
  377. borderWidth: 0,
  378. padding: 5,
  379. itemGap: 10,
  380. itemWidth: 20,
  381. itemHeight: 14,
  382. precision: 0,
  383. splitNumber: 5,
  384. calculable: false,
  385. selectedMode: true,
  386. hoverLink: true,
  387. realtime: true,
  388. color: [
  389. '#006edd',
  390. '#e0ffff'
  391. ],
  392. textStyle: { color: '#333' }
  393. };
  394. var zrUtil = require('zrender/tool/util');
  395. var zrEvent = require('zrender/tool/event');
  396. var zrArea = require('zrender/tool/area');
  397. var zrColor = require('zrender/tool/color');
  398. function DataRange(ecTheme, messageCenter, zr, option, myChart) {
  399. if (typeof this.query(option, 'dataRange.min') == 'undefined' || typeof this.query(option, 'dataRange.max') == 'undefined') {
  400. console.error('option.dataRange.min or option.dataRange.max has not been defined.');
  401. return;
  402. }
  403. Base.call(this, ecTheme, messageCenter, zr, option, myChart);
  404. var self = this;
  405. self._ondrift = function (dx, dy) {
  406. return self.__ondrift(this, dx, dy);
  407. };
  408. self._ondragend = function () {
  409. return self.__ondragend();
  410. };
  411. self._dataRangeSelected = function (param) {
  412. return self.__dataRangeSelected(param);
  413. };
  414. self._dispatchHoverLink = function (param) {
  415. return self.__dispatchHoverLink(param);
  416. };
  417. self._onhoverlink = function (params) {
  418. return self.__onhoverlink(params);
  419. };
  420. this._selectedMap = {};
  421. this._range = {};
  422. this.refresh(option);
  423. messageCenter.bind(ecConfig.EVENT.HOVER, this._onhoverlink);
  424. }
  425. DataRange.prototype = {
  426. type: ecConfig.COMPONENT_TYPE_DATARANGE,
  427. _textGap: 10,
  428. _buildShape: function () {
  429. this._itemGroupLocation = this._getItemGroupLocation();
  430. this._buildBackground();
  431. if (this.dataRangeOption.splitNumber <= 0 || this.dataRangeOption.calculable) {
  432. this._buildGradient();
  433. } else {
  434. this._buildItem();
  435. }
  436. if (this.dataRangeOption.show) {
  437. for (var i = 0, l = this.shapeList.length; i < l; i++) {
  438. this.zr.addShape(this.shapeList[i]);
  439. }
  440. }
  441. this._syncShapeFromRange();
  442. },
  443. _buildItem: function () {
  444. var data = this._valueTextList;
  445. var dataLength = data.length;
  446. var itemName;
  447. var itemShape;
  448. var textShape;
  449. var font = this.getFont(this.dataRangeOption.textStyle);
  450. var lastX = this._itemGroupLocation.x;
  451. var lastY = this._itemGroupLocation.y;
  452. var itemWidth = this.dataRangeOption.itemWidth;
  453. var itemHeight = this.dataRangeOption.itemHeight;
  454. var itemGap = this.dataRangeOption.itemGap;
  455. var textHeight = zrArea.getTextHeight('国', font);
  456. var color;
  457. if (this.dataRangeOption.orient == 'vertical' && this.dataRangeOption.x == 'right') {
  458. lastX = this._itemGroupLocation.x + this._itemGroupLocation.width - itemWidth;
  459. }
  460. var needValueText = true;
  461. if (this.dataRangeOption.text) {
  462. needValueText = false;
  463. if (this.dataRangeOption.text[0]) {
  464. textShape = this._getTextShape(lastX, lastY, this.dataRangeOption.text[0]);
  465. if (this.dataRangeOption.orient == 'horizontal') {
  466. lastX += zrArea.getTextWidth(this.dataRangeOption.text[0], font) + this._textGap;
  467. } else {
  468. lastY += textHeight + this._textGap;
  469. textShape.style.y += textHeight / 2 + this._textGap;
  470. textShape.style.textBaseline = 'bottom';
  471. }
  472. this.shapeList.push(new TextShape(textShape));
  473. }
  474. }
  475. for (var i = 0; i < dataLength; i++) {
  476. itemName = data[i];
  477. color = this.getColorByIndex(i);
  478. itemShape = this._getItemShape(lastX, lastY, itemWidth, itemHeight, this._selectedMap[i] ? color : '#ccc');
  479. itemShape._idx = i;
  480. itemShape.onmousemove = this._dispatchHoverLink;
  481. if (this.dataRangeOption.selectedMode) {
  482. itemShape.clickable = true;
  483. itemShape.onclick = this._dataRangeSelected;
  484. }
  485. this.shapeList.push(new RectangleShape(itemShape));
  486. if (needValueText) {
  487. textShape = {
  488. zlevel: this.getZlevelBase(),
  489. z: this.getZBase(),
  490. style: {
  491. x: lastX + itemWidth + 5,
  492. y: lastY,
  493. color: this._selectedMap[i] ? this.dataRangeOption.textStyle.color : '#ccc',
  494. text: data[i],
  495. textFont: font,
  496. textBaseline: 'top'
  497. },
  498. highlightStyle: { brushType: 'fill' }
  499. };
  500. if (this.dataRangeOption.orient == 'vertical' && this.dataRangeOption.x == 'right') {
  501. textShape.style.x -= itemWidth + 10;
  502. textShape.style.textAlign = 'right';
  503. }
  504. textShape._idx = i;
  505. textShape.onmousemove = this._dispatchHoverLink;
  506. if (this.dataRangeOption.selectedMode) {
  507. textShape.clickable = true;
  508. textShape.onclick = this._dataRangeSelected;
  509. }
  510. this.shapeList.push(new TextShape(textShape));
  511. }
  512. if (this.dataRangeOption.orient == 'horizontal') {
  513. lastX += itemWidth + (needValueText ? 5 : 0) + (needValueText ? zrArea.getTextWidth(itemName, font) : 0) + itemGap;
  514. } else {
  515. lastY += itemHeight + itemGap;
  516. }
  517. }
  518. if (!needValueText && this.dataRangeOption.text[1]) {
  519. if (this.dataRangeOption.orient == 'horizontal') {
  520. lastX = lastX - itemGap + this._textGap;
  521. } else {
  522. lastY = lastY - itemGap + this._textGap;
  523. }
  524. textShape = this._getTextShape(lastX, lastY, this.dataRangeOption.text[1]);
  525. if (this.dataRangeOption.orient != 'horizontal') {
  526. textShape.style.y -= 5;
  527. textShape.style.textBaseline = 'top';
  528. }
  529. this.shapeList.push(new TextShape(textShape));
  530. }
  531. },
  532. _buildGradient: function () {
  533. var itemShape;
  534. var textShape;
  535. var font = this.getFont(this.dataRangeOption.textStyle);
  536. var lastX = this._itemGroupLocation.x;
  537. var lastY = this._itemGroupLocation.y;
  538. var itemWidth = this.dataRangeOption.itemWidth;
  539. var itemHeight = this.dataRangeOption.itemHeight;
  540. var textHeight = zrArea.getTextHeight('国', font);
  541. var mSize = 10;
  542. var needValueText = true;
  543. if (this.dataRangeOption.text) {
  544. needValueText = false;
  545. if (this.dataRangeOption.text[0]) {
  546. textShape = this._getTextShape(lastX, lastY, this.dataRangeOption.text[0]);
  547. if (this.dataRangeOption.orient == 'horizontal') {
  548. lastX += zrArea.getTextWidth(this.dataRangeOption.text[0], font) + this._textGap;
  549. } else {
  550. lastY += textHeight + this._textGap;
  551. textShape.style.y += textHeight / 2 + this._textGap;
  552. textShape.style.textBaseline = 'bottom';
  553. }
  554. this.shapeList.push(new TextShape(textShape));
  555. }
  556. }
  557. var zrColor = require('zrender/tool/color');
  558. var per = 1 / (this.dataRangeOption.color.length - 1);
  559. var colorList = [];
  560. for (var i = 0, l = this.dataRangeOption.color.length; i < l; i++) {
  561. colorList.push([
  562. i * per,
  563. this.dataRangeOption.color[i]
  564. ]);
  565. }
  566. if (this.dataRangeOption.orient == 'horizontal') {
  567. itemShape = {
  568. zlevel: this.getZlevelBase(),
  569. z: this.getZBase(),
  570. style: {
  571. x: lastX,
  572. y: lastY,
  573. width: itemWidth * mSize,
  574. height: itemHeight,
  575. color: zrColor.getLinearGradient(lastX, lastY, lastX + itemWidth * mSize, lastY, colorList)
  576. },
  577. hoverable: false
  578. };
  579. lastX += itemWidth * mSize + this._textGap;
  580. } else {
  581. itemShape = {
  582. zlevel: this.getZlevelBase(),
  583. z: this.getZBase(),
  584. style: {
  585. x: lastX,
  586. y: lastY,
  587. width: itemWidth,
  588. height: itemHeight * mSize,
  589. color: zrColor.getLinearGradient(lastX, lastY, lastX, lastY + itemHeight * mSize, colorList)
  590. },
  591. hoverable: false
  592. };
  593. lastY += itemHeight * mSize + this._textGap;
  594. }
  595. this.shapeList.push(new RectangleShape(itemShape));
  596. this._calculableLocation = itemShape.style;
  597. if (this.dataRangeOption.calculable) {
  598. this._buildFiller();
  599. this._bulidMask();
  600. this._bulidHandle();
  601. }
  602. this._buildIndicator();
  603. if (!needValueText && this.dataRangeOption.text[1]) {
  604. textShape = this._getTextShape(lastX, lastY, this.dataRangeOption.text[1]);
  605. this.shapeList.push(new TextShape(textShape));
  606. }
  607. },
  608. _buildIndicator: function () {
  609. var x = this._calculableLocation.x;
  610. var y = this._calculableLocation.y;
  611. var width = this._calculableLocation.width;
  612. var height = this._calculableLocation.height;
  613. var size = 5;
  614. var pointList;
  615. var textPosition;
  616. if (this.dataRangeOption.orient == 'horizontal') {
  617. if (this.dataRangeOption.y != 'bottom') {
  618. pointList = [
  619. [
  620. x,
  621. y + height
  622. ],
  623. [
  624. x - size,
  625. y + height + size
  626. ],
  627. [
  628. x + size,
  629. y + height + size
  630. ]
  631. ];
  632. textPosition = 'bottom';
  633. } else {
  634. pointList = [
  635. [
  636. x,
  637. y
  638. ],
  639. [
  640. x - size,
  641. y - size
  642. ],
  643. [
  644. x + size,
  645. y - size
  646. ]
  647. ];
  648. textPosition = 'top';
  649. }
  650. } else {
  651. if (this.dataRangeOption.x != 'right') {
  652. pointList = [
  653. [
  654. x + width,
  655. y
  656. ],
  657. [
  658. x + width + size,
  659. y - size
  660. ],
  661. [
  662. x + width + size,
  663. y + size
  664. ]
  665. ];
  666. textPosition = 'right';
  667. } else {
  668. pointList = [
  669. [
  670. x,
  671. y
  672. ],
  673. [
  674. x - size,
  675. y - size
  676. ],
  677. [
  678. x - size,
  679. y + size
  680. ]
  681. ];
  682. textPosition = 'left';
  683. }
  684. }
  685. this._indicatorShape = {
  686. style: {
  687. pointList: pointList,
  688. color: '#fff',
  689. __rect: {
  690. x: Math.min(pointList[0][0], pointList[1][0]),
  691. y: Math.min(pointList[0][1], pointList[1][1]),
  692. width: size * (this.dataRangeOption.orient == 'horizontal' ? 2 : 1),
  693. height: size * (this.dataRangeOption.orient == 'horizontal' ? 1 : 2)
  694. }
  695. },
  696. highlightStyle: {
  697. brushType: 'fill',
  698. textPosition: textPosition,
  699. textColor: this.dataRangeOption.textStyle.color
  700. },
  701. hoverable: false
  702. };
  703. this._indicatorShape = new HandlePolygonShape(this._indicatorShape);
  704. },
  705. _buildFiller: function () {
  706. this._fillerShape = {
  707. zlevel: this.getZlevelBase(),
  708. z: this.getZBase() + 1,
  709. style: {
  710. x: this._calculableLocation.x,
  711. y: this._calculableLocation.y,
  712. width: this._calculableLocation.width,
  713. height: this._calculableLocation.height,
  714. color: 'rgba(255,255,255,0)'
  715. },
  716. highlightStyle: {
  717. strokeColor: 'rgba(255,255,255,0.5)',
  718. lineWidth: 1
  719. },
  720. draggable: true,
  721. ondrift: this._ondrift,
  722. ondragend: this._ondragend,
  723. onmousemove: this._dispatchHoverLink,
  724. _type: 'filler'
  725. };
  726. this._fillerShape = new RectangleShape(this._fillerShape);
  727. this.shapeList.push(this._fillerShape);
  728. },
  729. _bulidHandle: function () {
  730. var x = this._calculableLocation.x;
  731. var y = this._calculableLocation.y;
  732. var width = this._calculableLocation.width;
  733. var height = this._calculableLocation.height;
  734. var font = this.getFont(this.dataRangeOption.textStyle);
  735. var textHeight = zrArea.getTextHeight('国', font);
  736. var textWidth = Math.max(zrArea.getTextWidth(this._textFormat(this.dataRangeOption.max), font), zrArea.getTextWidth(this._textFormat(this.dataRangeOption.min), font)) + 2;
  737. var pointListStart;
  738. var textXStart;
  739. var textYStart;
  740. var coverRectStart;
  741. var pointListEnd;
  742. var textXEnd;
  743. var textYEnd;
  744. var coverRectEnd;
  745. if (this.dataRangeOption.orient == 'horizontal') {
  746. if (this.dataRangeOption.y != 'bottom') {
  747. pointListStart = [
  748. [
  749. x,
  750. y
  751. ],
  752. [
  753. x,
  754. y + height + textHeight
  755. ],
  756. [
  757. x - textHeight,
  758. y + height + textHeight
  759. ],
  760. [
  761. x - 1,
  762. y + height
  763. ],
  764. [
  765. x - 1,
  766. y
  767. ]
  768. ];
  769. textXStart = x - textWidth / 2 - textHeight;
  770. textYStart = y + height + textHeight / 2 + 2;
  771. coverRectStart = {
  772. x: x - textWidth - textHeight,
  773. y: y + height,
  774. width: textWidth + textHeight,
  775. height: textHeight
  776. };
  777. pointListEnd = [
  778. [
  779. x + width,
  780. y
  781. ],
  782. [
  783. x + width,
  784. y + height + textHeight
  785. ],
  786. [
  787. x + width + textHeight,
  788. y + height + textHeight
  789. ],
  790. [
  791. x + width + 1,
  792. y + height
  793. ],
  794. [
  795. x + width + 1,
  796. y
  797. ]
  798. ];
  799. textXEnd = x + width + textWidth / 2 + textHeight;
  800. textYEnd = textYStart;
  801. coverRectEnd = {
  802. x: x + width,
  803. y: y + height,
  804. width: textWidth + textHeight,
  805. height: textHeight
  806. };
  807. } else {
  808. pointListStart = [
  809. [
  810. x,
  811. y + height
  812. ],
  813. [
  814. x,
  815. y - textHeight
  816. ],
  817. [
  818. x - textHeight,
  819. y - textHeight
  820. ],
  821. [
  822. x - 1,
  823. y
  824. ],
  825. [
  826. x - 1,
  827. y + height
  828. ]
  829. ];
  830. textXStart = x - textWidth / 2 - textHeight;
  831. textYStart = y - textHeight / 2 - 2;
  832. coverRectStart = {
  833. x: x - textWidth - textHeight,
  834. y: y - textHeight,
  835. width: textWidth + textHeight,
  836. height: textHeight
  837. };
  838. pointListEnd = [
  839. [
  840. x + width,
  841. y + height
  842. ],
  843. [
  844. x + width,
  845. y - textHeight
  846. ],
  847. [
  848. x + width + textHeight,
  849. y - textHeight
  850. ],
  851. [
  852. x + width + 1,
  853. y
  854. ],
  855. [
  856. x + width + 1,
  857. y + height
  858. ]
  859. ];
  860. textXEnd = x + width + textWidth / 2 + textHeight;
  861. textYEnd = textYStart;
  862. coverRectEnd = {
  863. x: x + width,
  864. y: y - textHeight,
  865. width: textWidth + textHeight,
  866. height: textHeight
  867. };
  868. }
  869. } else {
  870. textWidth += textHeight;
  871. if (this.dataRangeOption.x != 'right') {
  872. pointListStart = [
  873. [
  874. x,
  875. y
  876. ],
  877. [
  878. x + width + textHeight,
  879. y
  880. ],
  881. [
  882. x + width + textHeight,
  883. y - textHeight
  884. ],
  885. [
  886. x + width,
  887. y - 1
  888. ],
  889. [
  890. x,
  891. y - 1
  892. ]
  893. ];
  894. textXStart = x + width + textWidth / 2 + textHeight / 2;
  895. textYStart = y - textHeight / 2;
  896. coverRectStart = {
  897. x: x + width,
  898. y: y - textHeight,
  899. width: textWidth + textHeight,
  900. height: textHeight
  901. };
  902. pointListEnd = [
  903. [
  904. x,
  905. y + height
  906. ],
  907. [
  908. x + width + textHeight,
  909. y + height
  910. ],
  911. [
  912. x + width + textHeight,
  913. y + textHeight + height
  914. ],
  915. [
  916. x + width,
  917. y + 1 + height
  918. ],
  919. [
  920. x,
  921. y + height + 1
  922. ]
  923. ];
  924. textXEnd = textXStart;
  925. textYEnd = y + height + textHeight / 2;
  926. coverRectEnd = {
  927. x: x + width,
  928. y: y + height,
  929. width: textWidth + textHeight,
  930. height: textHeight
  931. };
  932. } else {
  933. pointListStart = [
  934. [
  935. x + width,
  936. y
  937. ],
  938. [
  939. x - textHeight,
  940. y
  941. ],
  942. [
  943. x - textHeight,
  944. y - textHeight
  945. ],
  946. [
  947. x,
  948. y - 1
  949. ],
  950. [
  951. x + width,
  952. y - 1
  953. ]
  954. ];
  955. textXStart = x - textWidth / 2 - textHeight / 2;
  956. textYStart = y - textHeight / 2;
  957. coverRectStart = {
  958. x: x - textWidth - textHeight,
  959. y: y - textHeight,
  960. width: textWidth + textHeight,
  961. height: textHeight
  962. };
  963. pointListEnd = [
  964. [
  965. x + width,
  966. y + height
  967. ],
  968. [
  969. x - textHeight,
  970. y + height
  971. ],
  972. [
  973. x - textHeight,
  974. y + textHeight + height
  975. ],
  976. [
  977. x,
  978. y + 1 + height
  979. ],
  980. [
  981. x + width,
  982. y + height + 1
  983. ]
  984. ];
  985. textXEnd = textXStart;
  986. textYEnd = y + height + textHeight / 2;
  987. coverRectEnd = {
  988. x: x - textWidth - textHeight,
  989. y: y + height,
  990. width: textWidth + textHeight,
  991. height: textHeight
  992. };
  993. }
  994. }
  995. this._startShape = {
  996. style: {
  997. pointList: pointListStart,
  998. text: this._textFormat(this.dataRangeOption.max),
  999. textX: textXStart,
  1000. textY: textYStart,
  1001. textFont: font,
  1002. color: this.getColor(this.dataRangeOption.max),
  1003. rect: coverRectStart,
  1004. x: pointListStart[0][0],
  1005. y: pointListStart[0][1],
  1006. _x: pointListStart[0][0],
  1007. _y: pointListStart[0][1]
  1008. }
  1009. };
  1010. this._startShape.highlightStyle = {
  1011. strokeColor: this._startShape.style.color,
  1012. lineWidth: 1
  1013. };
  1014. this._endShape = {
  1015. style: {
  1016. pointList: pointListEnd,
  1017. text: this._textFormat(this.dataRangeOption.min),
  1018. textX: textXEnd,
  1019. textY: textYEnd,
  1020. textFont: font,
  1021. color: this.getColor(this.dataRangeOption.min),
  1022. rect: coverRectEnd,
  1023. x: pointListEnd[0][0],
  1024. y: pointListEnd[0][1],
  1025. _x: pointListEnd[0][0],
  1026. _y: pointListEnd[0][1]
  1027. }
  1028. };
  1029. this._endShape.highlightStyle = {
  1030. strokeColor: this._endShape.style.color,
  1031. lineWidth: 1
  1032. };
  1033. this._startShape.zlevel = this._endShape.zlevel = this.getZlevelBase();
  1034. this._startShape.z = this._endShape.z = this.getZBase() + 1;
  1035. this._startShape.draggable = this._endShape.draggable = true;
  1036. this._startShape.ondrift = this._endShape.ondrift = this._ondrift;
  1037. this._startShape.ondragend = this._endShape.ondragend = this._ondragend;
  1038. this._startShape.style.textColor = this._endShape.style.textColor = this.dataRangeOption.textStyle.color;
  1039. this._startShape.style.textAlign = this._endShape.style.textAlign = 'center';
  1040. this._startShape.style.textPosition = this._endShape.style.textPosition = 'specific';
  1041. this._startShape.style.textBaseline = this._endShape.style.textBaseline = 'middle';
  1042. this._startShape.style.width = this._endShape.style.width = 0;
  1043. this._startShape.style.height = this._endShape.style.height = 0;
  1044. this._startShape.style.textPosition = this._endShape.style.textPosition = 'specific';
  1045. this._startShape = new HandlePolygonShape(this._startShape);
  1046. this._endShape = new HandlePolygonShape(this._endShape);
  1047. this.shapeList.push(this._startShape);
  1048. this.shapeList.push(this._endShape);
  1049. },
  1050. _bulidMask: function () {
  1051. var x = this._calculableLocation.x;
  1052. var y = this._calculableLocation.y;
  1053. var width = this._calculableLocation.width;
  1054. var height = this._calculableLocation.height;
  1055. this._startMask = {
  1056. zlevel: this.getZlevelBase(),
  1057. z: this.getZBase() + 1,
  1058. style: {
  1059. x: x,
  1060. y: y,
  1061. width: this.dataRangeOption.orient == 'horizontal' ? 0 : width,
  1062. height: this.dataRangeOption.orient == 'horizontal' ? height : 0,
  1063. color: '#ccc'
  1064. },
  1065. hoverable: false
  1066. };
  1067. this._endMask = {
  1068. zlevel: this.getZlevelBase(),
  1069. z: this.getZBase() + 1,
  1070. style: {
  1071. x: this.dataRangeOption.orient == 'horizontal' ? x + width : x,
  1072. y: this.dataRangeOption.orient == 'horizontal' ? y : y + height,
  1073. width: this.dataRangeOption.orient == 'horizontal' ? 0 : width,
  1074. height: this.dataRangeOption.orient == 'horizontal' ? height : 0,
  1075. color: '#ccc'
  1076. },
  1077. hoverable: false
  1078. };
  1079. this._startMask = new RectangleShape(this._startMask);
  1080. this._endMask = new RectangleShape(this._endMask);
  1081. this.shapeList.push(this._startMask);
  1082. this.shapeList.push(this._endMask);
  1083. },
  1084. _buildBackground: function () {
  1085. var padding = this.reformCssArray(this.dataRangeOption.padding);
  1086. this.shapeList.push(new RectangleShape({
  1087. zlevel: this.getZlevelBase(),
  1088. z: this.getZBase(),
  1089. hoverable: false,
  1090. style: {
  1091. x: this._itemGroupLocation.x - padding[3],
  1092. y: this._itemGroupLocation.y - padding[0],
  1093. width: this._itemGroupLocation.width + padding[3] + padding[1],
  1094. height: this._itemGroupLocation.height + padding[0] + padding[2],
  1095. brushType: this.dataRangeOption.borderWidth === 0 ? 'fill' : 'both',
  1096. color: this.dataRangeOption.backgroundColor,
  1097. strokeColor: this.dataRangeOption.borderColor,
  1098. lineWidth: this.dataRangeOption.borderWidth
  1099. }
  1100. }));
  1101. },
  1102. _getItemGroupLocation: function () {
  1103. var data = this._valueTextList;
  1104. var dataLength = data.length;
  1105. var itemGap = this.dataRangeOption.itemGap;
  1106. var itemWidth = this.dataRangeOption.itemWidth;
  1107. var itemHeight = this.dataRangeOption.itemHeight;
  1108. var totalWidth = 0;
  1109. var totalHeight = 0;
  1110. var font = this.getFont(this.dataRangeOption.textStyle);
  1111. var textHeight = zrArea.getTextHeight('国', font);
  1112. var mSize = 10;
  1113. if (this.dataRangeOption.orient == 'horizontal') {
  1114. if (this.dataRangeOption.text || this.dataRangeOption.splitNumber <= 0 || this.dataRangeOption.calculable) {
  1115. totalWidth = (this.dataRangeOption.splitNumber <= 0 || this.dataRangeOption.calculable ? itemWidth * mSize + itemGap : dataLength * (itemWidth + itemGap)) + (this.dataRangeOption.text && typeof this.dataRangeOption.text[0] != 'undefined' ? zrArea.getTextWidth(this.dataRangeOption.text[0], font) + this._textGap : 0) + (this.dataRangeOption.text && typeof this.dataRangeOption.text[1] != 'undefined' ? zrArea.getTextWidth(this.dataRangeOption.text[1], font) + this._textGap : 0);
  1116. } else {
  1117. itemWidth += 5;
  1118. for (var i = 0; i < dataLength; i++) {
  1119. totalWidth += itemWidth + zrArea.getTextWidth(data[i], font) + itemGap;
  1120. }
  1121. }
  1122. totalWidth -= itemGap;
  1123. totalHeight = Math.max(textHeight, itemHeight);
  1124. } else {
  1125. var maxWidth;
  1126. if (this.dataRangeOption.text || this.dataRangeOption.splitNumber <= 0 || this.dataRangeOption.calculable) {
  1127. totalHeight = (this.dataRangeOption.splitNumber <= 0 || this.dataRangeOption.calculable ? itemHeight * mSize + itemGap : dataLength * (itemHeight + itemGap)) + (this.dataRangeOption.text && typeof this.dataRangeOption.text[0] != 'undefined' ? this._textGap + textHeight : 0) + (this.dataRangeOption.text && typeof this.dataRangeOption.text[1] != 'undefined' ? this._textGap + textHeight : 0);
  1128. maxWidth = Math.max(zrArea.getTextWidth(this.dataRangeOption.text && this.dataRangeOption.text[0] || '', font), zrArea.getTextWidth(this.dataRangeOption.text && this.dataRangeOption.text[1] || '', font));
  1129. totalWidth = Math.max(itemWidth, maxWidth);
  1130. } else {
  1131. totalHeight = (itemHeight + itemGap) * dataLength;
  1132. itemWidth += 5;
  1133. maxWidth = 0;
  1134. for (var i = 0; i < dataLength; i++) {
  1135. maxWidth = Math.max(maxWidth, zrArea.getTextWidth(data[i], font));
  1136. }
  1137. totalWidth = itemWidth + maxWidth;
  1138. }
  1139. totalHeight -= itemGap;
  1140. }
  1141. var padding = this.reformCssArray(this.dataRangeOption.padding);
  1142. var x;
  1143. var zrWidth = this.zr.getWidth();
  1144. switch (this.dataRangeOption.x) {
  1145. case 'center':
  1146. x = Math.floor((zrWidth - totalWidth) / 2);
  1147. break;
  1148. case 'left':
  1149. x = padding[3] + this.dataRangeOption.borderWidth;
  1150. break;
  1151. case 'right':
  1152. x = zrWidth - totalWidth - padding[1] - this.dataRangeOption.borderWidth;
  1153. break;
  1154. default:
  1155. x = this.parsePercent(this.dataRangeOption.x, zrWidth);
  1156. x = isNaN(x) ? 0 : x;
  1157. break;
  1158. }
  1159. var y;
  1160. var zrHeight = this.zr.getHeight();
  1161. switch (this.dataRangeOption.y) {
  1162. case 'top':
  1163. y = padding[0] + this.dataRangeOption.borderWidth;
  1164. break;
  1165. case 'bottom':
  1166. y = zrHeight - totalHeight - padding[2] - this.dataRangeOption.borderWidth;
  1167. break;
  1168. case 'center':
  1169. y = Math.floor((zrHeight - totalHeight) / 2);
  1170. break;
  1171. default:
  1172. y = this.parsePercent(this.dataRangeOption.y, zrHeight);
  1173. y = isNaN(y) ? 0 : y;
  1174. break;
  1175. }
  1176. if (this.dataRangeOption.calculable) {
  1177. var handlerWidth = Math.max(zrArea.getTextWidth(this.dataRangeOption.max, font), zrArea.getTextWidth(this.dataRangeOption.min, font)) + textHeight;
  1178. if (this.dataRangeOption.orient == 'horizontal') {
  1179. if (x < handlerWidth) {
  1180. x = handlerWidth;
  1181. }
  1182. if (x + totalWidth + handlerWidth > zrWidth) {
  1183. x -= handlerWidth;
  1184. }
  1185. } else {
  1186. if (y < textHeight) {
  1187. y = textHeight;
  1188. }
  1189. if (y + totalHeight + textHeight > zrHeight) {
  1190. y -= textHeight;
  1191. }
  1192. }
  1193. }
  1194. return {
  1195. x: x,
  1196. y: y,
  1197. width: totalWidth,
  1198. height: totalHeight
  1199. };
  1200. },
  1201. _getTextShape: function (x, y, text) {
  1202. return {
  1203. zlevel: this.getZlevelBase(),
  1204. z: this.getZBase(),
  1205. style: {
  1206. x: this.dataRangeOption.orient == 'horizontal' ? x : this._itemGroupLocation.x + this._itemGroupLocation.width / 2,
  1207. y: this.dataRangeOption.orient == 'horizontal' ? this._itemGroupLocation.y + this._itemGroupLocation.height / 2 : y,
  1208. color: this.dataRangeOption.textStyle.color,
  1209. text: text,
  1210. textFont: this.getFont(this.dataRangeOption.textStyle),
  1211. textBaseline: this.dataRangeOption.orient == 'horizontal' ? 'middle' : 'top',
  1212. textAlign: this.dataRangeOption.orient == 'horizontal' ? 'left' : 'center'
  1213. },
  1214. hoverable: false
  1215. };
  1216. },
  1217. _getItemShape: function (x, y, width, height, color) {
  1218. return {
  1219. zlevel: this.getZlevelBase(),
  1220. z: this.getZBase(),
  1221. style: {
  1222. x: x,
  1223. y: y + 1,
  1224. width: width,
  1225. height: height - 2,
  1226. color: color
  1227. },
  1228. highlightStyle: {
  1229. strokeColor: color,
  1230. lineWidth: 1
  1231. }
  1232. };
  1233. },
  1234. __ondrift: function (shape, dx, dy) {
  1235. var x = this._calculableLocation.x;
  1236. var y = this._calculableLocation.y;
  1237. var width = this._calculableLocation.width;
  1238. var height = this._calculableLocation.height;
  1239. if (this.dataRangeOption.orient == 'horizontal') {
  1240. if (shape.style.x + dx <= x) {
  1241. shape.style.x = x;
  1242. } else if (shape.style.x + dx + shape.style.width >= x + width) {
  1243. shape.style.x = x + width - shape.style.width;
  1244. } else {
  1245. shape.style.x += dx;
  1246. }
  1247. } else {
  1248. if (shape.style.y + dy <= y) {
  1249. shape.style.y = y;
  1250. } else if (shape.style.y + dy + shape.style.height >= y + height) {
  1251. shape.style.y = y + height - shape.style.height;
  1252. } else {
  1253. shape.style.y += dy;
  1254. }
  1255. }
  1256. if (shape._type == 'filler') {
  1257. this._syncHandleShape();
  1258. } else {
  1259. this._syncFillerShape(shape);
  1260. }
  1261. if (this.dataRangeOption.realtime) {
  1262. this._dispatchDataRange();
  1263. }
  1264. return true;
  1265. },
  1266. __ondragend: function () {
  1267. this.isDragend = true;
  1268. },
  1269. ondragend: function (param, status) {
  1270. if (!this.isDragend || !param.target) {
  1271. return;
  1272. }
  1273. status.dragOut = true;
  1274. status.dragIn = true;
  1275. if (!this.dataRangeOption.realtime) {
  1276. this._dispatchDataRange();
  1277. }
  1278. status.needRefresh = false;
  1279. this.isDragend = false;
  1280. return;
  1281. },
  1282. _syncShapeFromRange: function () {
  1283. var range = this.dataRangeOption.range || {};
  1284. this._range.end = typeof this._range.end != 'undefined' ? this._range.end : typeof range.start != 'undefined' ? range.start : 0;
  1285. this._range.start = typeof this._range.start != 'undefined' ? this._range.start : typeof range.end != 'undefined' ? range.end : 100;
  1286. if (this._range.start != 100 || this._range.end !== 0) {
  1287. if (this.dataRangeOption.orient == 'horizontal') {
  1288. var width = this._fillerShape.style.width;
  1289. this._fillerShape.style.x += width * (100 - this._range.start) / 100;
  1290. this._fillerShape.style.width = width * (this._range.start - this._range.end) / 100;
  1291. } else {
  1292. var height = this._fillerShape.style.height;
  1293. this._fillerShape.style.y += height * (100 - this._range.start) / 100;
  1294. this._fillerShape.style.height = height * (this._range.start - this._range.end) / 100;
  1295. }
  1296. this.zr.modShape(this._fillerShape.id);
  1297. this._syncHandleShape();
  1298. }
  1299. },
  1300. _syncHandleShape: function () {
  1301. var x = this._calculableLocation.x;
  1302. var y = this._calculableLocation.y;
  1303. var width = this._calculableLocation.width;
  1304. var height = this._calculableLocation.height;
  1305. if (this.dataRangeOption.orient == 'horizontal') {
  1306. this._startShape.style.x = this._fillerShape.style.x;
  1307. this._startMask.style.width = this._startShape.style.x - x;
  1308. this._endShape.style.x = this._fillerShape.style.x + this._fillerShape.style.width;
  1309. this._endMask.style.x = this._endShape.style.x;
  1310. this._endMask.style.width = x + width - this._endShape.style.x;
  1311. this._range.start = Math.ceil(100 - (this._startShape.style.x - x) / width * 100);
  1312. this._range.end = Math.floor(100 - (this._endShape.style.x - x) / width * 100);
  1313. } else {
  1314. this._startShape.style.y = this._fillerShape.style.y;
  1315. this._startMask.style.height = this._startShape.style.y - y;
  1316. this._endShape.style.y = this._fillerShape.style.y + this._fillerShape.style.height;
  1317. this._endMask.style.y = this._endShape.style.y;
  1318. this._endMask.style.height = y + height - this._endShape.style.y;
  1319. this._range.start = Math.ceil(100 - (this._startShape.style.y - y) / height * 100);
  1320. this._range.end = Math.floor(100 - (this._endShape.style.y - y) / height * 100);
  1321. }
  1322. this._syncShape();
  1323. },
  1324. _syncFillerShape: function (e) {
  1325. var x = this._calculableLocation.x;
  1326. var y = this._calculableLocation.y;
  1327. var width = this._calculableLocation.width;
  1328. var height = this._calculableLocation.height;
  1329. var a;
  1330. var b;
  1331. if (this.dataRangeOption.orient == 'horizontal') {
  1332. a = this._startShape.style.x;
  1333. b = this._endShape.style.x;
  1334. if (e.id == this._startShape.id && a >= b) {
  1335. b = a;
  1336. this._endShape.style.x = a;
  1337. } else if (e.id == this._endShape.id && a >= b) {
  1338. a = b;
  1339. this._startShape.style.x = a;
  1340. }
  1341. this._fillerShape.style.x = a;
  1342. this._fillerShape.style.width = b - a;
  1343. this._startMask.style.width = a - x;
  1344. this._endMask.style.x = b;
  1345. this._endMask.style.width = x + width - b;
  1346. this._range.start = Math.ceil(100 - (a - x) / width * 100);
  1347. this._range.end = Math.floor(100 - (b - x) / width * 100);
  1348. } else {
  1349. a = this._startShape.style.y;
  1350. b = this._endShape.style.y;
  1351. if (e.id == this._startShape.id && a >= b) {
  1352. b = a;
  1353. this._endShape.style.y = a;
  1354. } else if (e.id == this._endShape.id && a >= b) {
  1355. a = b;
  1356. this._startShape.style.y = a;
  1357. }
  1358. this._fillerShape.style.y = a;
  1359. this._fillerShape.style.height = b - a;
  1360. this._startMask.style.height = a - y;
  1361. this._endMask.style.y = b;
  1362. this._endMask.style.height = y + height - b;
  1363. this._range.start = Math.ceil(100 - (a - y) / height * 100);
  1364. this._range.end = Math.floor(100 - (b - y) / height * 100);
  1365. }
  1366. this._syncShape();
  1367. },
  1368. _syncShape: function () {
  1369. this._startShape.position = [
  1370. this._startShape.style.x - this._startShape.style._x,
  1371. this._startShape.style.y - this._startShape.style._y
  1372. ];
  1373. this._startShape.style.text = this._textFormat(this._gap * this._range.start + this.dataRangeOption.min);
  1374. this._startShape.style.color = this._startShape.highlightStyle.strokeColor = this.getColor(this._gap * this._range.start + this.dataRangeOption.min);
  1375. this._endShape.position = [
  1376. this._endShape.style.x - this._endShape.style._x,
  1377. this._endShape.style.y - this._endShape.style._y
  1378. ];
  1379. this._endShape.style.text = this._textFormat(this._gap * this._range.end + this.dataRangeOption.min);
  1380. this._endShape.style.color = this._endShape.highlightStyle.strokeColor = this.getColor(this._gap * this._range.end + this.dataRangeOption.min);
  1381. this.zr.modShape(this._startShape.id);
  1382. this.zr.modShape(this._endShape.id);
  1383. this.zr.modShape(this._startMask.id);
  1384. this.zr.modShape(this._endMask.id);
  1385. this.zr.modShape(this._fillerShape.id);
  1386. this.zr.refreshNextFrame();
  1387. },
  1388. _dispatchDataRange: function () {
  1389. this.messageCenter.dispatch(ecConfig.EVENT.DATA_RANGE, null, {
  1390. range: {
  1391. start: this._range.end,
  1392. end: this._range.start
  1393. }
  1394. }, this.myChart);
  1395. },
  1396. __dataRangeSelected: function (param) {
  1397. if (this.dataRangeOption.selectedMode === 'single') {
  1398. for (var k in this._selectedMap) {
  1399. this._selectedMap[k] = false;
  1400. }
  1401. }
  1402. var idx = param.target._idx;
  1403. this._selectedMap[idx] = !this._selectedMap[idx];
  1404. var valueMax = (this._colorList.length - idx) * this._gap + this.dataRangeOption.min;
  1405. this.messageCenter.dispatch(ecConfig.EVENT.DATA_RANGE_SELECTED, param.event, {
  1406. selected: this._selectedMap,
  1407. target: idx,
  1408. valueMax: valueMax,
  1409. valueMin: valueMax - this._gap
  1410. }, this.myChart);
  1411. this.messageCenter.dispatch(ecConfig.EVENT.REFRESH, null, null, this.myChart);
  1412. },
  1413. __dispatchHoverLink: function (param) {
  1414. var valueMin;
  1415. var valueMax;
  1416. if (this.dataRangeOption.calculable) {
  1417. var totalValue = this.dataRangeOption.max - this.dataRangeOption.min;
  1418. var curValue;
  1419. if (this.dataRangeOption.orient == 'horizontal') {
  1420. curValue = (1 - (zrEvent.getX(param.event) - this._calculableLocation.x) / this._calculableLocation.width) * totalValue;
  1421. } else {
  1422. curValue = (1 - (zrEvent.getY(param.event) - this._calculableLocation.y) / this._calculableLocation.height) * totalValue;
  1423. }
  1424. valueMin = curValue - totalValue * 0.05;
  1425. valueMax = curValue + totalValue * 0.05;
  1426. } else {
  1427. var idx = param.target._idx;
  1428. valueMax = (this._colorList.length - idx) * this._gap + this.dataRangeOption.min;
  1429. valueMin = valueMax - this._gap;
  1430. }
  1431. this.messageCenter.dispatch(ecConfig.EVENT.DATA_RANGE_HOVERLINK, param.event, {
  1432. valueMin: valueMin,
  1433. valueMax: valueMax
  1434. }, this.myChart);
  1435. return;
  1436. },
  1437. __onhoverlink: function (param) {
  1438. if (this.dataRangeOption.show && this.dataRangeOption.hoverLink && this._indicatorShape && param && param.seriesIndex != null && param.dataIndex != null) {
  1439. var curValue = param.value;
  1440. if (curValue === '' || isNaN(curValue)) {
  1441. return;
  1442. }
  1443. if (curValue < this.dataRangeOption.min) {
  1444. curValue = this.dataRangeOption.min;
  1445. } else if (curValue > this.dataRangeOption.max) {
  1446. curValue = this.dataRangeOption.max;
  1447. }
  1448. if (this.dataRangeOption.orient == 'horizontal') {
  1449. this._indicatorShape.position = [
  1450. (this.dataRangeOption.max - curValue) / (this.dataRangeOption.max - this.dataRangeOption.min) * this._calculableLocation.width,
  1451. 0
  1452. ];
  1453. } else {
  1454. this._indicatorShape.position = [
  1455. 0,
  1456. (this.dataRangeOption.max - curValue) / (this.dataRangeOption.max - this.dataRangeOption.min) * this._calculableLocation.height
  1457. ];
  1458. }
  1459. this._indicatorShape.style.text = this._textFormat(param.value);
  1460. this._indicatorShape.style.color = this.getColor(curValue);
  1461. this.zr.addHoverShape(this._indicatorShape);
  1462. }
  1463. },
  1464. _textFormat: function (valueStart, valueEnd) {
  1465. valueStart = (+valueStart).toFixed(this.dataRangeOption.precision);
  1466. valueEnd = valueEnd != null ? (+valueEnd).toFixed(this.dataRangeOption.precision) : '';
  1467. if (this.dataRangeOption.formatter) {
  1468. if (typeof this.dataRangeOption.formatter == 'string') {
  1469. return this.dataRangeOption.formatter.replace('{value}', valueStart).replace('{value2}', valueEnd);
  1470. } else if (typeof this.dataRangeOption.formatter == 'function') {
  1471. return this.dataRangeOption.formatter.call(this.myChart, valueStart, valueEnd);
  1472. }
  1473. }
  1474. if (valueEnd !== '') {
  1475. return valueStart + ' - ' + valueEnd;
  1476. }
  1477. return valueStart;
  1478. },
  1479. refresh: function (newOption) {
  1480. if (newOption) {
  1481. this.option = newOption;
  1482. this.option.dataRange = this.reformOption(this.option.dataRange);
  1483. this.dataRangeOption = this.option.dataRange;
  1484. if (!this.myChart.canvasSupported) {
  1485. this.dataRangeOption.realtime = false;
  1486. }
  1487. var splitNumber = this.dataRangeOption.splitNumber <= 0 || this.dataRangeOption.calculable ? 100 : this.dataRangeOption.splitNumber;
  1488. this._colorList = zrColor.getGradientColors(this.dataRangeOption.color, Math.max((splitNumber - this.dataRangeOption.color.length) / (this.dataRangeOption.color.length - 1), 0) + 1);
  1489. if (this._colorList.length > splitNumber) {
  1490. var len = this._colorList.length;
  1491. var newColorList = [this._colorList[0]];
  1492. var step = len / (splitNumber - 1);
  1493. for (var i = 1; i < splitNumber - 1; i++) {
  1494. newColorList.push(this._colorList[Math.floor(i * step)]);
  1495. }
  1496. newColorList.push(this._colorList[len - 1]);
  1497. this._colorList = newColorList;
  1498. }
  1499. var precision = this.dataRangeOption.precision;
  1500. this._gap = (this.dataRangeOption.max - this.dataRangeOption.min) / splitNumber;
  1501. while (this._gap.toFixed(precision) - 0 != this._gap && precision < 5) {
  1502. precision++;
  1503. }
  1504. this.dataRangeOption.precision = precision;
  1505. this._gap = ((this.dataRangeOption.max - this.dataRangeOption.min) / splitNumber).toFixed(precision) - 0;
  1506. this._valueTextList = [];
  1507. for (var i = 0; i < splitNumber; i++) {
  1508. this._selectedMap[i] = true;
  1509. this._valueTextList.unshift(this._textFormat(i * this._gap + this.dataRangeOption.min, (i + 1) * this._gap + this.dataRangeOption.min));
  1510. }
  1511. }
  1512. this.clear();
  1513. this._buildShape();
  1514. },
  1515. getColor: function (value) {
  1516. if (isNaN(value)) {
  1517. return null;
  1518. }
  1519. if (this.dataRangeOption.min == this.dataRangeOption.max) {
  1520. return this._colorList[0];
  1521. }
  1522. if (value < this.dataRangeOption.min) {
  1523. value = this.dataRangeOption.min;
  1524. } else if (value > this.dataRangeOption.max) {
  1525. value = this.dataRangeOption.max;
  1526. }
  1527. if (this.dataRangeOption.calculable) {
  1528. if (value - (this._gap * this._range.start + this.dataRangeOption.min) > 0.00005 || value - (this._gap * this._range.end + this.dataRangeOption.min) < -0.00005) {
  1529. return null;
  1530. }
  1531. }
  1532. var idx = this._colorList.length - Math.ceil((value - this.dataRangeOption.min) / (this.dataRangeOption.max - this.dataRangeOption.min) * this._colorList.length);
  1533. if (idx == this._colorList.length) {
  1534. idx--;
  1535. }
  1536. if (this._selectedMap[idx]) {
  1537. return this._colorList[idx];
  1538. } else {
  1539. return null;
  1540. }
  1541. },
  1542. getColorByIndex: function (idx) {
  1543. if (idx >= this._colorList.length) {
  1544. idx = this._colorList.length - 1;
  1545. } else if (idx < 0) {
  1546. idx = 0;
  1547. }
  1548. return this._colorList[idx];
  1549. },
  1550. onbeforDispose: function () {
  1551. this.messageCenter.unbind(ecConfig.EVENT.HOVER, this._onhoverlink);
  1552. }
  1553. };
  1554. zrUtil.inherits(DataRange, Base);
  1555. require('../component').define('dataRange', DataRange);
  1556. return DataRange;
  1557. });define('echarts/util/shape/HandlePolygon', [
  1558. 'require',
  1559. 'zrender/shape/Base',
  1560. 'zrender/shape/Polygon',
  1561. 'zrender/tool/util'
  1562. ], function (require) {
  1563. var Base = require('zrender/shape/Base');
  1564. var PolygonShape = require('zrender/shape/Polygon');
  1565. var zrUtil = require('zrender/tool/util');
  1566. function HandlePolygon(options) {
  1567. Base.call(this, options);
  1568. }
  1569. HandlePolygon.prototype = {
  1570. type: 'handle-polygon',
  1571. buildPath: function (ctx, style) {
  1572. PolygonShape.prototype.buildPath(ctx, style);
  1573. },
  1574. isCover: function (x, y) {
  1575. var originPos = this.transformCoordToLocal(x, y);
  1576. x = originPos[0];
  1577. y = originPos[1];
  1578. var rect = this.style.rect;
  1579. if (x >= rect.x && x <= rect.x + rect.width && y >= rect.y && y <= rect.y + rect.height) {
  1580. return true;
  1581. } else {
  1582. return false;
  1583. }
  1584. }
  1585. };
  1586. zrUtil.inherits(HandlePolygon, Base);
  1587. return HandlePolygon;
  1588. });