969730acc9d8b691b95b961835abb53778236de1.svn-base 72 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708
  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(serie, 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 = serie.zlevel;
  291. itemShape.z = serie.z;
  292. itemShape._main = true;
  293. return itemShape;
  294. },
  295. _getLargeSymbol: function (serie, pointList, nColor) {
  296. return new SymbolShape({
  297. zlevel: serie.zlevel,
  298. z: serie.z,
  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. splitList: null,
  385. calculable: false,
  386. selectedMode: true,
  387. hoverLink: true,
  388. realtime: true,
  389. color: [
  390. '#006edd',
  391. '#e0ffff'
  392. ],
  393. textStyle: { color: '#333' }
  394. };
  395. var zrUtil = require('zrender/tool/util');
  396. var zrEvent = require('zrender/tool/event');
  397. var zrArea = require('zrender/tool/area');
  398. var zrColor = require('zrender/tool/color');
  399. function DataRange(ecTheme, messageCenter, zr, option, myChart) {
  400. Base.call(this, ecTheme, messageCenter, zr, option, myChart);
  401. var self = this;
  402. self._ondrift = function (dx, dy) {
  403. return self.__ondrift(this, dx, dy);
  404. };
  405. self._ondragend = function () {
  406. return self.__ondragend();
  407. };
  408. self._dataRangeSelected = function (param) {
  409. return self.__dataRangeSelected(param);
  410. };
  411. self._dispatchHoverLink = function (param) {
  412. return self.__dispatchHoverLink(param);
  413. };
  414. self._onhoverlink = function (params) {
  415. return self.__onhoverlink(params);
  416. };
  417. this._selectedMap = {};
  418. this._range = {};
  419. this.refresh(option);
  420. messageCenter.bind(ecConfig.EVENT.HOVER, this._onhoverlink);
  421. }
  422. DataRange.prototype = {
  423. type: ecConfig.COMPONENT_TYPE_DATARANGE,
  424. _textGap: 10,
  425. _buildShape: function () {
  426. this._itemGroupLocation = this._getItemGroupLocation();
  427. this._buildBackground();
  428. if (this._isContinuity()) {
  429. this._buildGradient();
  430. } else {
  431. this._buildItem();
  432. }
  433. if (this.dataRangeOption.show) {
  434. for (var i = 0, l = this.shapeList.length; i < l; i++) {
  435. this.zr.addShape(this.shapeList[i]);
  436. }
  437. }
  438. this._syncShapeFromRange();
  439. },
  440. _buildItem: function () {
  441. var data = this._valueTextList;
  442. var dataLength = data.length;
  443. var itemName;
  444. var itemShape;
  445. var textShape;
  446. var font = this.getFont(this.dataRangeOption.textStyle);
  447. var lastX = this._itemGroupLocation.x;
  448. var lastY = this._itemGroupLocation.y;
  449. var itemWidth = this.dataRangeOption.itemWidth;
  450. var itemHeight = this.dataRangeOption.itemHeight;
  451. var itemGap = this.dataRangeOption.itemGap;
  452. var textHeight = zrArea.getTextHeight('国', font);
  453. var color;
  454. if (this.dataRangeOption.orient == 'vertical' && this.dataRangeOption.x == 'right') {
  455. lastX = this._itemGroupLocation.x + this._itemGroupLocation.width - itemWidth;
  456. }
  457. var needValueText = true;
  458. if (this.dataRangeOption.text) {
  459. needValueText = false;
  460. if (this.dataRangeOption.text[0]) {
  461. textShape = this._getTextShape(lastX, lastY, this.dataRangeOption.text[0]);
  462. if (this.dataRangeOption.orient == 'horizontal') {
  463. lastX += zrArea.getTextWidth(this.dataRangeOption.text[0], font) + this._textGap;
  464. } else {
  465. lastY += textHeight + this._textGap;
  466. textShape.style.y += textHeight / 2 + this._textGap;
  467. textShape.style.textBaseline = 'bottom';
  468. }
  469. this.shapeList.push(new TextShape(textShape));
  470. }
  471. }
  472. for (var i = 0; i < dataLength; i++) {
  473. itemName = data[i];
  474. color = this.getColorByIndex(i);
  475. itemShape = this._getItemShape(lastX, lastY, itemWidth, itemHeight, this._selectedMap[i] ? color : '#ccc');
  476. itemShape._idx = i;
  477. itemShape.onmousemove = this._dispatchHoverLink;
  478. if (this.dataRangeOption.selectedMode) {
  479. itemShape.clickable = true;
  480. itemShape.onclick = this._dataRangeSelected;
  481. }
  482. this.shapeList.push(new RectangleShape(itemShape));
  483. if (needValueText) {
  484. textShape = {
  485. zlevel: this.getZlevelBase(),
  486. z: this.getZBase(),
  487. style: {
  488. x: lastX + itemWidth + 5,
  489. y: lastY,
  490. color: this._selectedMap[i] ? this.dataRangeOption.textStyle.color : '#ccc',
  491. text: data[i],
  492. textFont: font,
  493. textBaseline: 'top'
  494. },
  495. highlightStyle: { brushType: 'fill' }
  496. };
  497. if (this.dataRangeOption.orient == 'vertical' && this.dataRangeOption.x == 'right') {
  498. textShape.style.x -= itemWidth + 10;
  499. textShape.style.textAlign = 'right';
  500. }
  501. textShape._idx = i;
  502. textShape.onmousemove = this._dispatchHoverLink;
  503. if (this.dataRangeOption.selectedMode) {
  504. textShape.clickable = true;
  505. textShape.onclick = this._dataRangeSelected;
  506. }
  507. this.shapeList.push(new TextShape(textShape));
  508. }
  509. if (this.dataRangeOption.orient == 'horizontal') {
  510. lastX += itemWidth + (needValueText ? 5 : 0) + (needValueText ? zrArea.getTextWidth(itemName, font) : 0) + itemGap;
  511. } else {
  512. lastY += itemHeight + itemGap;
  513. }
  514. }
  515. if (!needValueText && this.dataRangeOption.text[1]) {
  516. if (this.dataRangeOption.orient == 'horizontal') {
  517. lastX = lastX - itemGap + this._textGap;
  518. } else {
  519. lastY = lastY - itemGap + this._textGap;
  520. }
  521. textShape = this._getTextShape(lastX, lastY, this.dataRangeOption.text[1]);
  522. if (this.dataRangeOption.orient != 'horizontal') {
  523. textShape.style.y -= 5;
  524. textShape.style.textBaseline = 'top';
  525. }
  526. this.shapeList.push(new TextShape(textShape));
  527. }
  528. },
  529. _buildGradient: function () {
  530. var itemShape;
  531. var textShape;
  532. var font = this.getFont(this.dataRangeOption.textStyle);
  533. var lastX = this._itemGroupLocation.x;
  534. var lastY = this._itemGroupLocation.y;
  535. var itemWidth = this.dataRangeOption.itemWidth;
  536. var itemHeight = this.dataRangeOption.itemHeight;
  537. var textHeight = zrArea.getTextHeight('国', font);
  538. var mSize = 10;
  539. var needValueText = true;
  540. if (this.dataRangeOption.text) {
  541. needValueText = false;
  542. if (this.dataRangeOption.text[0]) {
  543. textShape = this._getTextShape(lastX, lastY, this.dataRangeOption.text[0]);
  544. if (this.dataRangeOption.orient == 'horizontal') {
  545. lastX += zrArea.getTextWidth(this.dataRangeOption.text[0], font) + this._textGap;
  546. } else {
  547. lastY += textHeight + this._textGap;
  548. textShape.style.y += textHeight / 2 + this._textGap;
  549. textShape.style.textBaseline = 'bottom';
  550. }
  551. this.shapeList.push(new TextShape(textShape));
  552. }
  553. }
  554. var zrColor = require('zrender/tool/color');
  555. var per = 1 / (this.dataRangeOption.color.length - 1);
  556. var colorList = [];
  557. for (var i = 0, l = this.dataRangeOption.color.length; i < l; i++) {
  558. colorList.push([
  559. i * per,
  560. this.dataRangeOption.color[i]
  561. ]);
  562. }
  563. if (this.dataRangeOption.orient == 'horizontal') {
  564. itemShape = {
  565. zlevel: this.getZlevelBase(),
  566. z: this.getZBase(),
  567. style: {
  568. x: lastX,
  569. y: lastY,
  570. width: itemWidth * mSize,
  571. height: itemHeight,
  572. color: zrColor.getLinearGradient(lastX, lastY, lastX + itemWidth * mSize, lastY, colorList)
  573. },
  574. hoverable: false
  575. };
  576. lastX += itemWidth * mSize + this._textGap;
  577. } else {
  578. itemShape = {
  579. zlevel: this.getZlevelBase(),
  580. z: this.getZBase(),
  581. style: {
  582. x: lastX,
  583. y: lastY,
  584. width: itemWidth,
  585. height: itemHeight * mSize,
  586. color: zrColor.getLinearGradient(lastX, lastY, lastX, lastY + itemHeight * mSize, colorList)
  587. },
  588. hoverable: false
  589. };
  590. lastY += itemHeight * mSize + this._textGap;
  591. }
  592. this.shapeList.push(new RectangleShape(itemShape));
  593. this._calculableLocation = itemShape.style;
  594. if (this.dataRangeOption.calculable) {
  595. this._buildFiller();
  596. this._bulidMask();
  597. this._bulidHandle();
  598. }
  599. this._buildIndicator();
  600. if (!needValueText && this.dataRangeOption.text[1]) {
  601. textShape = this._getTextShape(lastX, lastY, this.dataRangeOption.text[1]);
  602. this.shapeList.push(new TextShape(textShape));
  603. }
  604. },
  605. _buildIndicator: function () {
  606. var x = this._calculableLocation.x;
  607. var y = this._calculableLocation.y;
  608. var width = this._calculableLocation.width;
  609. var height = this._calculableLocation.height;
  610. var size = 5;
  611. var pointList;
  612. var textPosition;
  613. if (this.dataRangeOption.orient == 'horizontal') {
  614. if (this.dataRangeOption.y != 'bottom') {
  615. pointList = [
  616. [
  617. x,
  618. y + height
  619. ],
  620. [
  621. x - size,
  622. y + height + size
  623. ],
  624. [
  625. x + size,
  626. y + height + size
  627. ]
  628. ];
  629. textPosition = 'bottom';
  630. } else {
  631. pointList = [
  632. [
  633. x,
  634. y
  635. ],
  636. [
  637. x - size,
  638. y - size
  639. ],
  640. [
  641. x + size,
  642. y - size
  643. ]
  644. ];
  645. textPosition = 'top';
  646. }
  647. } else {
  648. if (this.dataRangeOption.x != 'right') {
  649. pointList = [
  650. [
  651. x + width,
  652. y
  653. ],
  654. [
  655. x + width + size,
  656. y - size
  657. ],
  658. [
  659. x + width + size,
  660. y + size
  661. ]
  662. ];
  663. textPosition = 'right';
  664. } else {
  665. pointList = [
  666. [
  667. x,
  668. y
  669. ],
  670. [
  671. x - size,
  672. y - size
  673. ],
  674. [
  675. x - size,
  676. y + size
  677. ]
  678. ];
  679. textPosition = 'left';
  680. }
  681. }
  682. this._indicatorShape = {
  683. style: {
  684. pointList: pointList,
  685. color: '#fff',
  686. __rect: {
  687. x: Math.min(pointList[0][0], pointList[1][0]),
  688. y: Math.min(pointList[0][1], pointList[1][1]),
  689. width: size * (this.dataRangeOption.orient == 'horizontal' ? 2 : 1),
  690. height: size * (this.dataRangeOption.orient == 'horizontal' ? 1 : 2)
  691. }
  692. },
  693. highlightStyle: {
  694. brushType: 'fill',
  695. textPosition: textPosition,
  696. textColor: this.dataRangeOption.textStyle.color
  697. },
  698. hoverable: false
  699. };
  700. this._indicatorShape = new HandlePolygonShape(this._indicatorShape);
  701. },
  702. _buildFiller: function () {
  703. this._fillerShape = {
  704. zlevel: this.getZlevelBase(),
  705. z: this.getZBase() + 1,
  706. style: {
  707. x: this._calculableLocation.x,
  708. y: this._calculableLocation.y,
  709. width: this._calculableLocation.width,
  710. height: this._calculableLocation.height,
  711. color: 'rgba(255,255,255,0)'
  712. },
  713. highlightStyle: {
  714. strokeColor: 'rgba(255,255,255,0.5)',
  715. lineWidth: 1
  716. },
  717. draggable: true,
  718. ondrift: this._ondrift,
  719. ondragend: this._ondragend,
  720. onmousemove: this._dispatchHoverLink,
  721. _type: 'filler'
  722. };
  723. this._fillerShape = new RectangleShape(this._fillerShape);
  724. this.shapeList.push(this._fillerShape);
  725. },
  726. _bulidHandle: function () {
  727. var x = this._calculableLocation.x;
  728. var y = this._calculableLocation.y;
  729. var width = this._calculableLocation.width;
  730. var height = this._calculableLocation.height;
  731. var font = this.getFont(this.dataRangeOption.textStyle);
  732. var textHeight = zrArea.getTextHeight('国', font);
  733. var textWidth = Math.max(zrArea.getTextWidth(this._textFormat(this.dataRangeOption.max), font), zrArea.getTextWidth(this._textFormat(this.dataRangeOption.min), font)) + 2;
  734. var pointListStart;
  735. var textXStart;
  736. var textYStart;
  737. var coverRectStart;
  738. var pointListEnd;
  739. var textXEnd;
  740. var textYEnd;
  741. var coverRectEnd;
  742. if (this.dataRangeOption.orient == 'horizontal') {
  743. if (this.dataRangeOption.y != 'bottom') {
  744. pointListStart = [
  745. [
  746. x,
  747. y
  748. ],
  749. [
  750. x,
  751. y + height + textHeight
  752. ],
  753. [
  754. x - textHeight,
  755. y + height + textHeight
  756. ],
  757. [
  758. x - 1,
  759. y + height
  760. ],
  761. [
  762. x - 1,
  763. y
  764. ]
  765. ];
  766. textXStart = x - textWidth / 2 - textHeight;
  767. textYStart = y + height + textHeight / 2 + 2;
  768. coverRectStart = {
  769. x: x - textWidth - textHeight,
  770. y: y + height,
  771. width: textWidth + textHeight,
  772. height: textHeight
  773. };
  774. pointListEnd = [
  775. [
  776. x + width,
  777. y
  778. ],
  779. [
  780. x + width,
  781. y + height + textHeight
  782. ],
  783. [
  784. x + width + textHeight,
  785. y + height + textHeight
  786. ],
  787. [
  788. x + width + 1,
  789. y + height
  790. ],
  791. [
  792. x + width + 1,
  793. y
  794. ]
  795. ];
  796. textXEnd = x + width + textWidth / 2 + textHeight;
  797. textYEnd = textYStart;
  798. coverRectEnd = {
  799. x: x + width,
  800. y: y + height,
  801. width: textWidth + textHeight,
  802. height: textHeight
  803. };
  804. } else {
  805. pointListStart = [
  806. [
  807. x,
  808. y + height
  809. ],
  810. [
  811. x,
  812. y - textHeight
  813. ],
  814. [
  815. x - textHeight,
  816. y - textHeight
  817. ],
  818. [
  819. x - 1,
  820. y
  821. ],
  822. [
  823. x - 1,
  824. y + height
  825. ]
  826. ];
  827. textXStart = x - textWidth / 2 - textHeight;
  828. textYStart = y - textHeight / 2 - 2;
  829. coverRectStart = {
  830. x: x - textWidth - textHeight,
  831. y: y - textHeight,
  832. width: textWidth + textHeight,
  833. height: textHeight
  834. };
  835. pointListEnd = [
  836. [
  837. x + width,
  838. y + height
  839. ],
  840. [
  841. x + width,
  842. y - textHeight
  843. ],
  844. [
  845. x + width + textHeight,
  846. y - textHeight
  847. ],
  848. [
  849. x + width + 1,
  850. y
  851. ],
  852. [
  853. x + width + 1,
  854. y + height
  855. ]
  856. ];
  857. textXEnd = x + width + textWidth / 2 + textHeight;
  858. textYEnd = textYStart;
  859. coverRectEnd = {
  860. x: x + width,
  861. y: y - textHeight,
  862. width: textWidth + textHeight,
  863. height: textHeight
  864. };
  865. }
  866. } else {
  867. textWidth += textHeight;
  868. if (this.dataRangeOption.x != 'right') {
  869. pointListStart = [
  870. [
  871. x,
  872. y
  873. ],
  874. [
  875. x + width + textHeight,
  876. y
  877. ],
  878. [
  879. x + width + textHeight,
  880. y - textHeight
  881. ],
  882. [
  883. x + width,
  884. y - 1
  885. ],
  886. [
  887. x,
  888. y - 1
  889. ]
  890. ];
  891. textXStart = x + width + textWidth / 2 + textHeight / 2;
  892. textYStart = y - textHeight / 2;
  893. coverRectStart = {
  894. x: x + width,
  895. y: y - textHeight,
  896. width: textWidth + textHeight,
  897. height: textHeight
  898. };
  899. pointListEnd = [
  900. [
  901. x,
  902. y + height
  903. ],
  904. [
  905. x + width + textHeight,
  906. y + height
  907. ],
  908. [
  909. x + width + textHeight,
  910. y + textHeight + height
  911. ],
  912. [
  913. x + width,
  914. y + 1 + height
  915. ],
  916. [
  917. x,
  918. y + height + 1
  919. ]
  920. ];
  921. textXEnd = textXStart;
  922. textYEnd = y + height + textHeight / 2;
  923. coverRectEnd = {
  924. x: x + width,
  925. y: y + height,
  926. width: textWidth + textHeight,
  927. height: textHeight
  928. };
  929. } else {
  930. pointListStart = [
  931. [
  932. x + width,
  933. y
  934. ],
  935. [
  936. x - textHeight,
  937. y
  938. ],
  939. [
  940. x - textHeight,
  941. y - textHeight
  942. ],
  943. [
  944. x,
  945. y - 1
  946. ],
  947. [
  948. x + width,
  949. y - 1
  950. ]
  951. ];
  952. textXStart = x - textWidth / 2 - textHeight / 2;
  953. textYStart = y - textHeight / 2;
  954. coverRectStart = {
  955. x: x - textWidth - textHeight,
  956. y: y - textHeight,
  957. width: textWidth + textHeight,
  958. height: textHeight
  959. };
  960. pointListEnd = [
  961. [
  962. x + width,
  963. y + height
  964. ],
  965. [
  966. x - textHeight,
  967. y + height
  968. ],
  969. [
  970. x - textHeight,
  971. y + textHeight + height
  972. ],
  973. [
  974. x,
  975. y + 1 + height
  976. ],
  977. [
  978. x + width,
  979. y + height + 1
  980. ]
  981. ];
  982. textXEnd = textXStart;
  983. textYEnd = y + height + textHeight / 2;
  984. coverRectEnd = {
  985. x: x - textWidth - textHeight,
  986. y: y + height,
  987. width: textWidth + textHeight,
  988. height: textHeight
  989. };
  990. }
  991. }
  992. this._startShape = {
  993. style: {
  994. pointList: pointListStart,
  995. text: this._textFormat(this.dataRangeOption.max),
  996. textX: textXStart,
  997. textY: textYStart,
  998. textFont: font,
  999. color: this.getColor(this.dataRangeOption.max),
  1000. rect: coverRectStart,
  1001. x: pointListStart[0][0],
  1002. y: pointListStart[0][1],
  1003. _x: pointListStart[0][0],
  1004. _y: pointListStart[0][1]
  1005. }
  1006. };
  1007. this._startShape.highlightStyle = {
  1008. strokeColor: this._startShape.style.color,
  1009. lineWidth: 1
  1010. };
  1011. this._endShape = {
  1012. style: {
  1013. pointList: pointListEnd,
  1014. text: this._textFormat(this.dataRangeOption.min),
  1015. textX: textXEnd,
  1016. textY: textYEnd,
  1017. textFont: font,
  1018. color: this.getColor(this.dataRangeOption.min),
  1019. rect: coverRectEnd,
  1020. x: pointListEnd[0][0],
  1021. y: pointListEnd[0][1],
  1022. _x: pointListEnd[0][0],
  1023. _y: pointListEnd[0][1]
  1024. }
  1025. };
  1026. this._endShape.highlightStyle = {
  1027. strokeColor: this._endShape.style.color,
  1028. lineWidth: 1
  1029. };
  1030. this._startShape.zlevel = this._endShape.zlevel = this.getZlevelBase();
  1031. this._startShape.z = this._endShape.z = this.getZBase() + 1;
  1032. this._startShape.draggable = this._endShape.draggable = true;
  1033. this._startShape.ondrift = this._endShape.ondrift = this._ondrift;
  1034. this._startShape.ondragend = this._endShape.ondragend = this._ondragend;
  1035. this._startShape.style.textColor = this._endShape.style.textColor = this.dataRangeOption.textStyle.color;
  1036. this._startShape.style.textAlign = this._endShape.style.textAlign = 'center';
  1037. this._startShape.style.textPosition = this._endShape.style.textPosition = 'specific';
  1038. this._startShape.style.textBaseline = this._endShape.style.textBaseline = 'middle';
  1039. this._startShape.style.width = this._endShape.style.width = 0;
  1040. this._startShape.style.height = this._endShape.style.height = 0;
  1041. this._startShape.style.textPosition = this._endShape.style.textPosition = 'specific';
  1042. this._startShape = new HandlePolygonShape(this._startShape);
  1043. this._endShape = new HandlePolygonShape(this._endShape);
  1044. this.shapeList.push(this._startShape);
  1045. this.shapeList.push(this._endShape);
  1046. },
  1047. _bulidMask: function () {
  1048. var x = this._calculableLocation.x;
  1049. var y = this._calculableLocation.y;
  1050. var width = this._calculableLocation.width;
  1051. var height = this._calculableLocation.height;
  1052. this._startMask = {
  1053. zlevel: this.getZlevelBase(),
  1054. z: this.getZBase() + 1,
  1055. style: {
  1056. x: x,
  1057. y: y,
  1058. width: this.dataRangeOption.orient == 'horizontal' ? 0 : width,
  1059. height: this.dataRangeOption.orient == 'horizontal' ? height : 0,
  1060. color: '#ccc'
  1061. },
  1062. hoverable: false
  1063. };
  1064. this._endMask = {
  1065. zlevel: this.getZlevelBase(),
  1066. z: this.getZBase() + 1,
  1067. style: {
  1068. x: this.dataRangeOption.orient == 'horizontal' ? x + width : x,
  1069. y: this.dataRangeOption.orient == 'horizontal' ? y : y + height,
  1070. width: this.dataRangeOption.orient == 'horizontal' ? 0 : width,
  1071. height: this.dataRangeOption.orient == 'horizontal' ? height : 0,
  1072. color: '#ccc'
  1073. },
  1074. hoverable: false
  1075. };
  1076. this._startMask = new RectangleShape(this._startMask);
  1077. this._endMask = new RectangleShape(this._endMask);
  1078. this.shapeList.push(this._startMask);
  1079. this.shapeList.push(this._endMask);
  1080. },
  1081. _buildBackground: function () {
  1082. var padding = this.reformCssArray(this.dataRangeOption.padding);
  1083. this.shapeList.push(new RectangleShape({
  1084. zlevel: this.getZlevelBase(),
  1085. z: this.getZBase(),
  1086. hoverable: false,
  1087. style: {
  1088. x: this._itemGroupLocation.x - padding[3],
  1089. y: this._itemGroupLocation.y - padding[0],
  1090. width: this._itemGroupLocation.width + padding[3] + padding[1],
  1091. height: this._itemGroupLocation.height + padding[0] + padding[2],
  1092. brushType: this.dataRangeOption.borderWidth === 0 ? 'fill' : 'both',
  1093. color: this.dataRangeOption.backgroundColor,
  1094. strokeColor: this.dataRangeOption.borderColor,
  1095. lineWidth: this.dataRangeOption.borderWidth
  1096. }
  1097. }));
  1098. },
  1099. _getItemGroupLocation: function () {
  1100. var data = this._valueTextList;
  1101. var dataLength = data.length;
  1102. var itemGap = this.dataRangeOption.itemGap;
  1103. var itemWidth = this.dataRangeOption.itemWidth;
  1104. var itemHeight = this.dataRangeOption.itemHeight;
  1105. var totalWidth = 0;
  1106. var totalHeight = 0;
  1107. var font = this.getFont(this.dataRangeOption.textStyle);
  1108. var textHeight = zrArea.getTextHeight('国', font);
  1109. var mSize = 10;
  1110. if (this.dataRangeOption.orient == 'horizontal') {
  1111. if (this.dataRangeOption.text || this._isContinuity()) {
  1112. totalWidth = (this._isContinuity() ? 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);
  1113. } else {
  1114. itemWidth += 5;
  1115. for (var i = 0; i < dataLength; i++) {
  1116. totalWidth += itemWidth + zrArea.getTextWidth(data[i], font) + itemGap;
  1117. }
  1118. }
  1119. totalWidth -= itemGap;
  1120. totalHeight = Math.max(textHeight, itemHeight);
  1121. } else {
  1122. var maxWidth;
  1123. if (this.dataRangeOption.text || this._isContinuity()) {
  1124. totalHeight = (this._isContinuity() ? 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);
  1125. maxWidth = Math.max(zrArea.getTextWidth(this.dataRangeOption.text && this.dataRangeOption.text[0] || '', font), zrArea.getTextWidth(this.dataRangeOption.text && this.dataRangeOption.text[1] || '', font));
  1126. totalWidth = Math.max(itemWidth, maxWidth);
  1127. } else {
  1128. totalHeight = (itemHeight + itemGap) * dataLength;
  1129. itemWidth += 5;
  1130. maxWidth = 0;
  1131. for (var i = 0; i < dataLength; i++) {
  1132. maxWidth = Math.max(maxWidth, zrArea.getTextWidth(data[i], font));
  1133. }
  1134. totalWidth = itemWidth + maxWidth;
  1135. }
  1136. totalHeight -= itemGap;
  1137. }
  1138. var padding = this.reformCssArray(this.dataRangeOption.padding);
  1139. var x;
  1140. var zrWidth = this.zr.getWidth();
  1141. switch (this.dataRangeOption.x) {
  1142. case 'center':
  1143. x = Math.floor((zrWidth - totalWidth) / 2);
  1144. break;
  1145. case 'left':
  1146. x = padding[3] + this.dataRangeOption.borderWidth;
  1147. break;
  1148. case 'right':
  1149. x = zrWidth - totalWidth - padding[1] - this.dataRangeOption.borderWidth;
  1150. break;
  1151. default:
  1152. x = this.parsePercent(this.dataRangeOption.x, zrWidth);
  1153. x = isNaN(x) ? 0 : x;
  1154. break;
  1155. }
  1156. var y;
  1157. var zrHeight = this.zr.getHeight();
  1158. switch (this.dataRangeOption.y) {
  1159. case 'top':
  1160. y = padding[0] + this.dataRangeOption.borderWidth;
  1161. break;
  1162. case 'bottom':
  1163. y = zrHeight - totalHeight - padding[2] - this.dataRangeOption.borderWidth;
  1164. break;
  1165. case 'center':
  1166. y = Math.floor((zrHeight - totalHeight) / 2);
  1167. break;
  1168. default:
  1169. y = this.parsePercent(this.dataRangeOption.y, zrHeight);
  1170. y = isNaN(y) ? 0 : y;
  1171. break;
  1172. }
  1173. if (this.dataRangeOption.calculable) {
  1174. var handlerWidth = Math.max(zrArea.getTextWidth(this.dataRangeOption.max, font), zrArea.getTextWidth(this.dataRangeOption.min, font)) + textHeight;
  1175. if (this.dataRangeOption.orient == 'horizontal') {
  1176. if (x < handlerWidth) {
  1177. x = handlerWidth;
  1178. }
  1179. if (x + totalWidth + handlerWidth > zrWidth) {
  1180. x -= handlerWidth;
  1181. }
  1182. } else {
  1183. if (y < textHeight) {
  1184. y = textHeight;
  1185. }
  1186. if (y + totalHeight + textHeight > zrHeight) {
  1187. y -= textHeight;
  1188. }
  1189. }
  1190. }
  1191. return {
  1192. x: x,
  1193. y: y,
  1194. width: totalWidth,
  1195. height: totalHeight
  1196. };
  1197. },
  1198. _getTextShape: function (x, y, text) {
  1199. return {
  1200. zlevel: this.getZlevelBase(),
  1201. z: this.getZBase(),
  1202. style: {
  1203. x: this.dataRangeOption.orient == 'horizontal' ? x : this._itemGroupLocation.x + this._itemGroupLocation.width / 2,
  1204. y: this.dataRangeOption.orient == 'horizontal' ? this._itemGroupLocation.y + this._itemGroupLocation.height / 2 : y,
  1205. color: this.dataRangeOption.textStyle.color,
  1206. text: text,
  1207. textFont: this.getFont(this.dataRangeOption.textStyle),
  1208. textBaseline: this.dataRangeOption.orient == 'horizontal' ? 'middle' : 'top',
  1209. textAlign: this.dataRangeOption.orient == 'horizontal' ? 'left' : 'center'
  1210. },
  1211. hoverable: false
  1212. };
  1213. },
  1214. _getItemShape: function (x, y, width, height, color) {
  1215. return {
  1216. zlevel: this.getZlevelBase(),
  1217. z: this.getZBase(),
  1218. style: {
  1219. x: x,
  1220. y: y + 1,
  1221. width: width,
  1222. height: height - 2,
  1223. color: color
  1224. },
  1225. highlightStyle: {
  1226. strokeColor: color,
  1227. lineWidth: 1
  1228. }
  1229. };
  1230. },
  1231. __ondrift: function (shape, dx, dy) {
  1232. var x = this._calculableLocation.x;
  1233. var y = this._calculableLocation.y;
  1234. var width = this._calculableLocation.width;
  1235. var height = this._calculableLocation.height;
  1236. if (this.dataRangeOption.orient == 'horizontal') {
  1237. if (shape.style.x + dx <= x) {
  1238. shape.style.x = x;
  1239. } else if (shape.style.x + dx + shape.style.width >= x + width) {
  1240. shape.style.x = x + width - shape.style.width;
  1241. } else {
  1242. shape.style.x += dx;
  1243. }
  1244. } else {
  1245. if (shape.style.y + dy <= y) {
  1246. shape.style.y = y;
  1247. } else if (shape.style.y + dy + shape.style.height >= y + height) {
  1248. shape.style.y = y + height - shape.style.height;
  1249. } else {
  1250. shape.style.y += dy;
  1251. }
  1252. }
  1253. if (shape._type == 'filler') {
  1254. this._syncHandleShape();
  1255. } else {
  1256. this._syncFillerShape(shape);
  1257. }
  1258. if (this.dataRangeOption.realtime) {
  1259. this._dispatchDataRange();
  1260. }
  1261. return true;
  1262. },
  1263. __ondragend: function () {
  1264. this.isDragend = true;
  1265. },
  1266. ondragend: function (param, status) {
  1267. if (!this.isDragend || !param.target) {
  1268. return;
  1269. }
  1270. status.dragOut = true;
  1271. status.dragIn = true;
  1272. if (!this.dataRangeOption.realtime) {
  1273. this._dispatchDataRange();
  1274. }
  1275. status.needRefresh = false;
  1276. this.isDragend = false;
  1277. return;
  1278. },
  1279. _syncShapeFromRange: function () {
  1280. var range = this.dataRangeOption.range || {};
  1281. var optRangeStart = range.start;
  1282. var optRangeEnd = range.end;
  1283. if (optRangeEnd < optRangeStart) {
  1284. optRangeStart = [
  1285. optRangeEnd,
  1286. optRangeEnd = optRangeStart
  1287. ][0];
  1288. }
  1289. this._range.end = optRangeStart != null ? optRangeStart : this._range.end != null ? this._range.end : 0;
  1290. this._range.start = optRangeEnd != null ? optRangeEnd : this._range.start != null ? this._range.start : 100;
  1291. if (this._range.start != 100 || this._range.end !== 0) {
  1292. if (this.dataRangeOption.orient == 'horizontal') {
  1293. var width = this._fillerShape.style.width;
  1294. this._fillerShape.style.x += width * (100 - this._range.start) / 100;
  1295. this._fillerShape.style.width = width * (this._range.start - this._range.end) / 100;
  1296. } else {
  1297. var height = this._fillerShape.style.height;
  1298. this._fillerShape.style.y += height * (100 - this._range.start) / 100;
  1299. this._fillerShape.style.height = height * (this._range.start - this._range.end) / 100;
  1300. }
  1301. this.zr.modShape(this._fillerShape.id);
  1302. this._syncHandleShape();
  1303. }
  1304. },
  1305. _syncHandleShape: function () {
  1306. var x = this._calculableLocation.x;
  1307. var y = this._calculableLocation.y;
  1308. var width = this._calculableLocation.width;
  1309. var height = this._calculableLocation.height;
  1310. if (this.dataRangeOption.orient == 'horizontal') {
  1311. this._startShape.style.x = this._fillerShape.style.x;
  1312. this._startMask.style.width = this._startShape.style.x - x;
  1313. this._endShape.style.x = this._fillerShape.style.x + this._fillerShape.style.width;
  1314. this._endMask.style.x = this._endShape.style.x;
  1315. this._endMask.style.width = x + width - this._endShape.style.x;
  1316. this._range.start = Math.ceil(100 - (this._startShape.style.x - x) / width * 100);
  1317. this._range.end = Math.floor(100 - (this._endShape.style.x - x) / width * 100);
  1318. } else {
  1319. this._startShape.style.y = this._fillerShape.style.y;
  1320. this._startMask.style.height = this._startShape.style.y - y;
  1321. this._endShape.style.y = this._fillerShape.style.y + this._fillerShape.style.height;
  1322. this._endMask.style.y = this._endShape.style.y;
  1323. this._endMask.style.height = y + height - this._endShape.style.y;
  1324. this._range.start = Math.ceil(100 - (this._startShape.style.y - y) / height * 100);
  1325. this._range.end = Math.floor(100 - (this._endShape.style.y - y) / height * 100);
  1326. }
  1327. this._syncShape();
  1328. },
  1329. _syncFillerShape: function (e) {
  1330. var x = this._calculableLocation.x;
  1331. var y = this._calculableLocation.y;
  1332. var width = this._calculableLocation.width;
  1333. var height = this._calculableLocation.height;
  1334. var a;
  1335. var b;
  1336. if (this.dataRangeOption.orient == 'horizontal') {
  1337. a = this._startShape.style.x;
  1338. b = this._endShape.style.x;
  1339. if (e.id == this._startShape.id && a >= b) {
  1340. b = a;
  1341. this._endShape.style.x = a;
  1342. } else if (e.id == this._endShape.id && a >= b) {
  1343. a = b;
  1344. this._startShape.style.x = a;
  1345. }
  1346. this._fillerShape.style.x = a;
  1347. this._fillerShape.style.width = b - a;
  1348. this._startMask.style.width = a - x;
  1349. this._endMask.style.x = b;
  1350. this._endMask.style.width = x + width - b;
  1351. this._range.start = Math.ceil(100 - (a - x) / width * 100);
  1352. this._range.end = Math.floor(100 - (b - x) / width * 100);
  1353. } else {
  1354. a = this._startShape.style.y;
  1355. b = this._endShape.style.y;
  1356. if (e.id == this._startShape.id && a >= b) {
  1357. b = a;
  1358. this._endShape.style.y = a;
  1359. } else if (e.id == this._endShape.id && a >= b) {
  1360. a = b;
  1361. this._startShape.style.y = a;
  1362. }
  1363. this._fillerShape.style.y = a;
  1364. this._fillerShape.style.height = b - a;
  1365. this._startMask.style.height = a - y;
  1366. this._endMask.style.y = b;
  1367. this._endMask.style.height = y + height - b;
  1368. this._range.start = Math.ceil(100 - (a - y) / height * 100);
  1369. this._range.end = Math.floor(100 - (b - y) / height * 100);
  1370. }
  1371. this._syncShape();
  1372. },
  1373. _syncShape: function () {
  1374. this._startShape.position = [
  1375. this._startShape.style.x - this._startShape.style._x,
  1376. this._startShape.style.y - this._startShape.style._y
  1377. ];
  1378. this._startShape.style.text = this._textFormat(this._gap * this._range.start + this.dataRangeOption.min);
  1379. this._startShape.style.color = this._startShape.highlightStyle.strokeColor = this.getColor(this._gap * this._range.start + this.dataRangeOption.min);
  1380. this._endShape.position = [
  1381. this._endShape.style.x - this._endShape.style._x,
  1382. this._endShape.style.y - this._endShape.style._y
  1383. ];
  1384. this._endShape.style.text = this._textFormat(this._gap * this._range.end + this.dataRangeOption.min);
  1385. this._endShape.style.color = this._endShape.highlightStyle.strokeColor = this.getColor(this._gap * this._range.end + this.dataRangeOption.min);
  1386. this.zr.modShape(this._startShape.id);
  1387. this.zr.modShape(this._endShape.id);
  1388. this.zr.modShape(this._startMask.id);
  1389. this.zr.modShape(this._endMask.id);
  1390. this.zr.modShape(this._fillerShape.id);
  1391. this.zr.refreshNextFrame();
  1392. },
  1393. _dispatchDataRange: function () {
  1394. this.messageCenter.dispatch(ecConfig.EVENT.DATA_RANGE, null, {
  1395. range: {
  1396. start: this._range.end,
  1397. end: this._range.start
  1398. }
  1399. }, this.myChart);
  1400. },
  1401. __dataRangeSelected: function (param) {
  1402. if (this.dataRangeOption.selectedMode === 'single') {
  1403. for (var k in this._selectedMap) {
  1404. this._selectedMap[k] = false;
  1405. }
  1406. }
  1407. var idx = param.target._idx;
  1408. this._selectedMap[idx] = !this._selectedMap[idx];
  1409. var valueMax;
  1410. var valueMin;
  1411. if (this._useCustomizedSplit()) {
  1412. valueMax = this._splitList[idx].max;
  1413. valueMin = this._splitList[idx].min;
  1414. } else {
  1415. valueMax = (this._colorList.length - idx) * this._gap + this.dataRangeOption.min;
  1416. valueMin = valueMax - this._gap;
  1417. }
  1418. this.messageCenter.dispatch(ecConfig.EVENT.DATA_RANGE_SELECTED, param.event, {
  1419. selected: this._selectedMap,
  1420. target: idx,
  1421. valueMax: valueMax,
  1422. valueMin: valueMin
  1423. }, this.myChart);
  1424. this.messageCenter.dispatch(ecConfig.EVENT.REFRESH, null, null, this.myChart);
  1425. },
  1426. __dispatchHoverLink: function (param) {
  1427. var valueMin;
  1428. var valueMax;
  1429. if (this.dataRangeOption.calculable) {
  1430. var totalValue = this.dataRangeOption.max - this.dataRangeOption.min;
  1431. var curValue;
  1432. if (this.dataRangeOption.orient == 'horizontal') {
  1433. curValue = (1 - (zrEvent.getX(param.event) - this._calculableLocation.x) / this._calculableLocation.width) * totalValue;
  1434. } else {
  1435. curValue = (1 - (zrEvent.getY(param.event) - this._calculableLocation.y) / this._calculableLocation.height) * totalValue;
  1436. }
  1437. valueMin = curValue - totalValue * 0.05;
  1438. valueMax = curValue + totalValue * 0.05;
  1439. } else if (this._useCustomizedSplit()) {
  1440. var idx = param.target._idx;
  1441. valueMax = this._splitList[idx].max;
  1442. valueMin = this._splitList[idx].min;
  1443. } else {
  1444. var idx = param.target._idx;
  1445. valueMax = (this._colorList.length - idx) * this._gap + this.dataRangeOption.min;
  1446. valueMin = valueMax - this._gap;
  1447. }
  1448. this.messageCenter.dispatch(ecConfig.EVENT.DATA_RANGE_HOVERLINK, param.event, {
  1449. valueMin: valueMin,
  1450. valueMax: valueMax
  1451. }, this.myChart);
  1452. },
  1453. __onhoverlink: function (param) {
  1454. if (this.dataRangeOption.show && this.dataRangeOption.hoverLink && this._indicatorShape && param && param.seriesIndex != null && param.dataIndex != null) {
  1455. var curValue = param.value;
  1456. if (curValue === '' || isNaN(curValue)) {
  1457. return;
  1458. }
  1459. if (curValue < this.dataRangeOption.min) {
  1460. curValue = this.dataRangeOption.min;
  1461. } else if (curValue > this.dataRangeOption.max) {
  1462. curValue = this.dataRangeOption.max;
  1463. }
  1464. if (this.dataRangeOption.orient == 'horizontal') {
  1465. this._indicatorShape.position = [
  1466. (this.dataRangeOption.max - curValue) / (this.dataRangeOption.max - this.dataRangeOption.min) * this._calculableLocation.width,
  1467. 0
  1468. ];
  1469. } else {
  1470. this._indicatorShape.position = [
  1471. 0,
  1472. (this.dataRangeOption.max - curValue) / (this.dataRangeOption.max - this.dataRangeOption.min) * this._calculableLocation.height
  1473. ];
  1474. }
  1475. this._indicatorShape.style.text = this._textFormat(param.value);
  1476. this._indicatorShape.style.color = this.getColor(curValue);
  1477. this.zr.addHoverShape(this._indicatorShape);
  1478. }
  1479. },
  1480. _textFormat: function (valueStart, valueEnd) {
  1481. var dataRangeOption = this.dataRangeOption;
  1482. if (valueStart !== -Number.MAX_VALUE) {
  1483. valueStart = (+valueStart).toFixed(dataRangeOption.precision);
  1484. }
  1485. if (valueEnd != null && valueEnd !== Number.MAX_VALUE) {
  1486. valueEnd = (+valueEnd).toFixed(dataRangeOption.precision);
  1487. }
  1488. if (dataRangeOption.formatter) {
  1489. if (typeof dataRangeOption.formatter == 'string') {
  1490. return dataRangeOption.formatter.replace('{value}', valueStart === -Number.MAX_VALUE ? 'min' : valueStart).replace('{value2}', valueEnd === Number.MAX_VALUE ? 'max' : valueEnd);
  1491. } else if (typeof dataRangeOption.formatter == 'function') {
  1492. return dataRangeOption.formatter.call(this.myChart, valueStart, valueEnd);
  1493. }
  1494. }
  1495. if (valueEnd == null) {
  1496. return valueStart;
  1497. } else {
  1498. if (valueStart === -Number.MAX_VALUE) {
  1499. return '< ' + valueEnd;
  1500. } else if (valueEnd === Number.MAX_VALUE) {
  1501. return '> ' + valueStart;
  1502. } else {
  1503. return valueStart + ' - ' + valueEnd;
  1504. }
  1505. }
  1506. },
  1507. _isContinuity: function () {
  1508. var dataRangeOption = this.dataRangeOption;
  1509. return !(dataRangeOption.splitList ? dataRangeOption.splitList.length > 0 : dataRangeOption.splitNumber > 0) || dataRangeOption.calculable;
  1510. },
  1511. _useCustomizedSplit: function () {
  1512. var dataRangeOption = this.dataRangeOption;
  1513. return dataRangeOption.splitList && dataRangeOption.splitList.length > 0;
  1514. },
  1515. _buildColorList: function (splitNumber) {
  1516. this._colorList = zrColor.getGradientColors(this.dataRangeOption.color, Math.max((splitNumber - this.dataRangeOption.color.length) / (this.dataRangeOption.color.length - 1), 0) + 1);
  1517. if (this._colorList.length > splitNumber) {
  1518. var len = this._colorList.length;
  1519. var newColorList = [this._colorList[0]];
  1520. var step = len / (splitNumber - 1);
  1521. for (var i = 1; i < splitNumber - 1; i++) {
  1522. newColorList.push(this._colorList[Math.floor(i * step)]);
  1523. }
  1524. newColorList.push(this._colorList[len - 1]);
  1525. this._colorList = newColorList;
  1526. }
  1527. if (this._useCustomizedSplit()) {
  1528. var splitList = this._splitList;
  1529. for (var i = 0, len = splitList.length; i < len; i++) {
  1530. if (splitList[i].color) {
  1531. this._colorList[i] = splitList[i].color;
  1532. }
  1533. }
  1534. }
  1535. },
  1536. _buildGap: function (splitNumber) {
  1537. if (!this._useCustomizedSplit()) {
  1538. var precision = this.dataRangeOption.precision;
  1539. this._gap = (this.dataRangeOption.max - this.dataRangeOption.min) / splitNumber;
  1540. while (this._gap.toFixed(precision) - 0 != this._gap && precision < 5) {
  1541. precision++;
  1542. }
  1543. this.dataRangeOption.precision = precision;
  1544. this._gap = ((this.dataRangeOption.max - this.dataRangeOption.min) / splitNumber).toFixed(precision) - 0;
  1545. }
  1546. },
  1547. _buildDataList: function (splitNumber) {
  1548. var valueTextList = this._valueTextList = [];
  1549. var dataRangeOption = this.dataRangeOption;
  1550. var useCustomizedSplit = this._useCustomizedSplit();
  1551. for (var i = 0; i < splitNumber; i++) {
  1552. this._selectedMap[i] = true;
  1553. var text = '';
  1554. if (useCustomizedSplit) {
  1555. var splitListItem = this._splitList[splitNumber - 1 - i];
  1556. if (splitListItem.label != null) {
  1557. text = splitListItem.label;
  1558. } else if (splitListItem.single != null) {
  1559. text = this._textFormat(splitListItem.single);
  1560. } else {
  1561. text = this._textFormat(splitListItem.min, splitListItem.max);
  1562. }
  1563. } else {
  1564. text = this._textFormat(i * this._gap + dataRangeOption.min, (i + 1) * this._gap + dataRangeOption.min);
  1565. }
  1566. valueTextList.unshift(text);
  1567. }
  1568. },
  1569. _buildSplitList: function () {
  1570. if (!this._useCustomizedSplit()) {
  1571. return;
  1572. }
  1573. var splitList = this.dataRangeOption.splitList;
  1574. var splitRangeList = this._splitList = [];
  1575. for (var i = 0, len = splitList.length; i < len; i++) {
  1576. var splitListItem = splitList[i];
  1577. if (!splitListItem || splitListItem.start == null && splitListItem.end == null) {
  1578. throw new Error('Empty item exists in splitList!');
  1579. }
  1580. var reformedItem = {
  1581. label: splitListItem.label,
  1582. color: splitListItem.color
  1583. };
  1584. reformedItem.min = splitListItem.start;
  1585. reformedItem.max = splitListItem.end;
  1586. if (reformedItem.min > reformedItem.max) {
  1587. reformedItem.min = [
  1588. reformedItem.max,
  1589. reformedItem.max = reformedItem.min
  1590. ][0];
  1591. }
  1592. if (reformedItem.min === reformedItem.max) {
  1593. reformedItem.single = reformedItem.max;
  1594. }
  1595. if (reformedItem.min == null) {
  1596. reformedItem.min = -Number.MAX_VALUE;
  1597. }
  1598. if (reformedItem.max == null) {
  1599. reformedItem.max = Number.MAX_VALUE;
  1600. }
  1601. splitRangeList.push(reformedItem);
  1602. }
  1603. },
  1604. refresh: function (newOption) {
  1605. if (newOption) {
  1606. this.option = newOption;
  1607. this.option.dataRange = this.reformOption(this.option.dataRange);
  1608. var dataRangeOption = this.dataRangeOption = this.option.dataRange;
  1609. if (!this._useCustomizedSplit() && (dataRangeOption.min == null || dataRangeOption.max == null)) {
  1610. throw new Error('option.dataRange.min or option.dataRange.max has not been defined.');
  1611. }
  1612. if (!this.myChart.canvasSupported) {
  1613. dataRangeOption.realtime = false;
  1614. }
  1615. var splitNumber = this._isContinuity() ? 100 : this._useCustomizedSplit() ? dataRangeOption.splitList.length : dataRangeOption.splitNumber;
  1616. this._buildSplitList();
  1617. this._buildColorList(splitNumber);
  1618. this._buildGap(splitNumber);
  1619. this._buildDataList(splitNumber);
  1620. }
  1621. this.clear();
  1622. this._buildShape();
  1623. },
  1624. getColor: function (value) {
  1625. if (isNaN(value)) {
  1626. return null;
  1627. }
  1628. var idx;
  1629. if (!this._useCustomizedSplit()) {
  1630. if (this.dataRangeOption.min == this.dataRangeOption.max) {
  1631. return this._colorList[0];
  1632. }
  1633. if (value < this.dataRangeOption.min) {
  1634. value = this.dataRangeOption.min;
  1635. } else if (value > this.dataRangeOption.max) {
  1636. value = this.dataRangeOption.max;
  1637. }
  1638. if (this.dataRangeOption.calculable) {
  1639. if (value - (this._gap * this._range.start + this.dataRangeOption.min) > 0.00005 || value - (this._gap * this._range.end + this.dataRangeOption.min) < -0.00005) {
  1640. return null;
  1641. }
  1642. }
  1643. idx = this._colorList.length - Math.ceil((value - this.dataRangeOption.min) / (this.dataRangeOption.max - this.dataRangeOption.min) * this._colorList.length);
  1644. if (idx == this._colorList.length) {
  1645. idx--;
  1646. }
  1647. } else {
  1648. var splitRangeList = this._splitList;
  1649. for (var i = 0, len = splitRangeList.length; i < len; i++) {
  1650. if (splitRangeList[i].min <= value && splitRangeList[i].max >= value) {
  1651. idx = i;
  1652. break;
  1653. }
  1654. }
  1655. }
  1656. if (this._selectedMap[idx]) {
  1657. return this._colorList[idx];
  1658. } else {
  1659. return null;
  1660. }
  1661. },
  1662. getColorByIndex: function (idx) {
  1663. if (idx >= this._colorList.length) {
  1664. idx = this._colorList.length - 1;
  1665. } else if (idx < 0) {
  1666. idx = 0;
  1667. }
  1668. return this._colorList[idx];
  1669. },
  1670. onbeforDispose: function () {
  1671. this.messageCenter.unbind(ecConfig.EVENT.HOVER, this._onhoverlink);
  1672. }
  1673. };
  1674. zrUtil.inherits(DataRange, Base);
  1675. require('../component').define('dataRange', DataRange);
  1676. return DataRange;
  1677. });define('echarts/util/shape/HandlePolygon', [
  1678. 'require',
  1679. 'zrender/shape/Base',
  1680. 'zrender/shape/Polygon',
  1681. 'zrender/tool/util'
  1682. ], function (require) {
  1683. var Base = require('zrender/shape/Base');
  1684. var PolygonShape = require('zrender/shape/Polygon');
  1685. var zrUtil = require('zrender/tool/util');
  1686. function HandlePolygon(options) {
  1687. Base.call(this, options);
  1688. }
  1689. HandlePolygon.prototype = {
  1690. type: 'handle-polygon',
  1691. buildPath: function (ctx, style) {
  1692. PolygonShape.prototype.buildPath(ctx, style);
  1693. },
  1694. isCover: function (x, y) {
  1695. var originPos = this.transformCoordToLocal(x, y);
  1696. x = originPos[0];
  1697. y = originPos[1];
  1698. var rect = this.style.rect;
  1699. if (x >= rect.x && x <= rect.x + rect.width && y >= rect.y && y <= rect.y + rect.height) {
  1700. return true;
  1701. } else {
  1702. return false;
  1703. }
  1704. }
  1705. };
  1706. zrUtil.inherits(HandlePolygon, Base);
  1707. return HandlePolygon;
  1708. });