k.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. define('echarts/chart/k', [
  2. 'require',
  3. './base',
  4. '../util/shape/Candle',
  5. '../component/axis',
  6. '../component/grid',
  7. '../component/dataZoom',
  8. '../config',
  9. '../util/ecData',
  10. 'zrender/tool/util',
  11. '../chart'
  12. ], function (require) {
  13. var ChartBase = require('./base');
  14. var CandleShape = require('../util/shape/Candle');
  15. require('../component/axis');
  16. require('../component/grid');
  17. require('../component/dataZoom');
  18. var ecConfig = require('../config');
  19. ecConfig.k = {
  20. zlevel: 0,
  21. z: 2,
  22. clickable: true,
  23. hoverable: true,
  24. legendHoverLink: false,
  25. xAxisIndex: 0,
  26. yAxisIndex: 0,
  27. itemStyle: {
  28. normal: {
  29. color: '#fff',
  30. color0: '#00aa11',
  31. lineStyle: {
  32. width: 1,
  33. color: '#ff3200',
  34. color0: '#00aa11'
  35. },
  36. label: { show: false }
  37. },
  38. emphasis: { label: { show: false } }
  39. }
  40. };
  41. var ecData = require('../util/ecData');
  42. var zrUtil = require('zrender/tool/util');
  43. function K(ecTheme, messageCenter, zr, option, myChart) {
  44. ChartBase.call(this, ecTheme, messageCenter, zr, option, myChart);
  45. this.refresh(option);
  46. }
  47. K.prototype = {
  48. type: ecConfig.CHART_TYPE_K,
  49. _buildShape: function () {
  50. var series = this.series;
  51. this.selectedMap = {};
  52. var _position2sIndexMap = {
  53. top: [],
  54. bottom: []
  55. };
  56. var xAxis;
  57. for (var i = 0, l = series.length; i < l; i++) {
  58. if (series[i].type === ecConfig.CHART_TYPE_K) {
  59. series[i] = this.reformOption(series[i]);
  60. this.legendHoverLink = series[i].legendHoverLink || this.legendHoverLink;
  61. xAxis = this.component.xAxis.getAxis(series[i].xAxisIndex);
  62. if (xAxis.type === ecConfig.COMPONENT_TYPE_AXIS_CATEGORY) {
  63. _position2sIndexMap[xAxis.getPosition()].push(i);
  64. }
  65. }
  66. }
  67. for (var position in _position2sIndexMap) {
  68. if (_position2sIndexMap[position].length > 0) {
  69. this._buildSinglePosition(position, _position2sIndexMap[position]);
  70. }
  71. }
  72. this.addShapeList();
  73. },
  74. _buildSinglePosition: function (position, seriesArray) {
  75. var mapData = this._mapData(seriesArray);
  76. var locationMap = mapData.locationMap;
  77. var maxDataLength = mapData.maxDataLength;
  78. if (maxDataLength === 0 || locationMap.length === 0) {
  79. return;
  80. }
  81. this._buildHorizontal(seriesArray, maxDataLength, locationMap);
  82. for (var i = 0, l = seriesArray.length; i < l; i++) {
  83. this.buildMark(seriesArray[i]);
  84. }
  85. },
  86. _mapData: function (seriesArray) {
  87. var series = this.series;
  88. var serie;
  89. var serieName;
  90. var legend = this.component.legend;
  91. var locationMap = [];
  92. var maxDataLength = 0;
  93. for (var i = 0, l = seriesArray.length; i < l; i++) {
  94. serie = series[seriesArray[i]];
  95. serieName = serie.name;
  96. this.selectedMap[serieName] = legend ? legend.isSelected(serieName) : true;
  97. if (this.selectedMap[serieName]) {
  98. locationMap.push(seriesArray[i]);
  99. }
  100. maxDataLength = Math.max(maxDataLength, serie.data.length);
  101. }
  102. return {
  103. locationMap: locationMap,
  104. maxDataLength: maxDataLength
  105. };
  106. },
  107. _buildHorizontal: function (seriesArray, maxDataLength, locationMap) {
  108. var series = this.series;
  109. var seriesIndex;
  110. var serie;
  111. var xAxisIndex;
  112. var categoryAxis;
  113. var yAxisIndex;
  114. var valueAxis;
  115. var pointList = {};
  116. var candleWidth;
  117. var data;
  118. var value;
  119. var barMaxWidth;
  120. for (var j = 0, k = locationMap.length; j < k; j++) {
  121. seriesIndex = locationMap[j];
  122. serie = series[seriesIndex];
  123. xAxisIndex = serie.xAxisIndex || 0;
  124. categoryAxis = this.component.xAxis.getAxis(xAxisIndex);
  125. candleWidth = serie.barWidth || Math.floor(categoryAxis.getGap() / 2);
  126. barMaxWidth = serie.barMaxWidth;
  127. if (barMaxWidth && barMaxWidth < candleWidth) {
  128. candleWidth = barMaxWidth;
  129. }
  130. yAxisIndex = serie.yAxisIndex || 0;
  131. valueAxis = this.component.yAxis.getAxis(yAxisIndex);
  132. pointList[seriesIndex] = [];
  133. for (var i = 0, l = maxDataLength; i < l; i++) {
  134. if (categoryAxis.getNameByIndex(i) == null) {
  135. break;
  136. }
  137. data = serie.data[i];
  138. value = this.getDataFromOption(data, '-');
  139. if (value === '-' || value.length != 4) {
  140. continue;
  141. }
  142. pointList[seriesIndex].push([
  143. categoryAxis.getCoordByIndex(i),
  144. candleWidth,
  145. valueAxis.getCoord(value[0]),
  146. valueAxis.getCoord(value[1]),
  147. valueAxis.getCoord(value[2]),
  148. valueAxis.getCoord(value[3]),
  149. i,
  150. categoryAxis.getNameByIndex(i)
  151. ]);
  152. }
  153. }
  154. this._buildKLine(seriesArray, pointList);
  155. },
  156. _buildKLine: function (seriesArray, pointList) {
  157. var series = this.series;
  158. var nLineWidth;
  159. var nLineColor;
  160. var nLineColor0;
  161. var nColor;
  162. var nColor0;
  163. var eLineWidth;
  164. var eLineColor;
  165. var eLineColor0;
  166. var eColor;
  167. var eColor0;
  168. var serie;
  169. var queryTarget;
  170. var data;
  171. var seriesPL;
  172. var singlePoint;
  173. var candleType;
  174. var seriesIndex;
  175. for (var sIdx = 0, len = seriesArray.length; sIdx < len; sIdx++) {
  176. seriesIndex = seriesArray[sIdx];
  177. serie = series[seriesIndex];
  178. seriesPL = pointList[seriesIndex];
  179. if (this._isLarge(seriesPL)) {
  180. seriesPL = this._getLargePointList(seriesPL);
  181. }
  182. if (serie.type === ecConfig.CHART_TYPE_K && seriesPL != null) {
  183. queryTarget = serie;
  184. nLineWidth = this.query(queryTarget, 'itemStyle.normal.lineStyle.width');
  185. nLineColor = this.query(queryTarget, 'itemStyle.normal.lineStyle.color');
  186. nLineColor0 = this.query(queryTarget, 'itemStyle.normal.lineStyle.color0');
  187. nColor = this.query(queryTarget, 'itemStyle.normal.color');
  188. nColor0 = this.query(queryTarget, 'itemStyle.normal.color0');
  189. eLineWidth = this.query(queryTarget, 'itemStyle.emphasis.lineStyle.width');
  190. eLineColor = this.query(queryTarget, 'itemStyle.emphasis.lineStyle.color');
  191. eLineColor0 = this.query(queryTarget, 'itemStyle.emphasis.lineStyle.color0');
  192. eColor = this.query(queryTarget, 'itemStyle.emphasis.color');
  193. eColor0 = this.query(queryTarget, 'itemStyle.emphasis.color0');
  194. for (var i = 0, l = seriesPL.length; i < l; i++) {
  195. singlePoint = seriesPL[i];
  196. data = serie.data[singlePoint[6]];
  197. queryTarget = data;
  198. candleType = singlePoint[3] < singlePoint[2];
  199. this.shapeList.push(this._getCandle(seriesIndex, singlePoint[6], singlePoint[7], singlePoint[0], singlePoint[1], singlePoint[2], singlePoint[3], singlePoint[4], singlePoint[5], candleType ? this.query(queryTarget, 'itemStyle.normal.color') || nColor : this.query(queryTarget, 'itemStyle.normal.color0') || nColor0, this.query(queryTarget, 'itemStyle.normal.lineStyle.width') || nLineWidth, candleType ? this.query(queryTarget, 'itemStyle.normal.lineStyle.color') || nLineColor : this.query(queryTarget, 'itemStyle.normal.lineStyle.color0') || nLineColor0, candleType ? this.query(queryTarget, 'itemStyle.emphasis.color') || eColor || nColor : this.query(queryTarget, 'itemStyle.emphasis.color0') || eColor0 || nColor0, this.query(queryTarget, 'itemStyle.emphasis.lineStyle.width') || eLineWidth || nLineWidth, candleType ? this.query(queryTarget, 'itemStyle.emphasis.lineStyle.color') || eLineColor || nLineColor : this.query(queryTarget, 'itemStyle.emphasis.lineStyle.color0') || eLineColor0 || nLineColor0));
  200. }
  201. }
  202. }
  203. },
  204. _isLarge: function (singlePL) {
  205. return singlePL[0][1] < 0.5;
  206. },
  207. _getLargePointList: function (singlePL) {
  208. var total = this.component.grid.getWidth();
  209. var len = singlePL.length;
  210. var newList = [];
  211. for (var i = 0; i < total; i++) {
  212. newList[i] = singlePL[Math.floor(len / total * i)];
  213. }
  214. return newList;
  215. },
  216. _getCandle: function (seriesIndex, dataIndex, name, x, width, y0, y1, y2, y3, nColor, nLinewidth, nLineColor, eColor, eLinewidth, eLineColor) {
  217. var series = this.series;
  218. var serie = series[seriesIndex];
  219. var data = serie.data[dataIndex];
  220. var queryTarget = [
  221. data,
  222. serie
  223. ];
  224. var itemShape = {
  225. zlevel: this.getZlevelBase(),
  226. z: this.getZBase(),
  227. clickable: this.deepQuery(queryTarget, 'clickable'),
  228. hoverable: this.deepQuery(queryTarget, 'hoverable'),
  229. style: {
  230. x: x,
  231. y: [
  232. y0,
  233. y1,
  234. y2,
  235. y3
  236. ],
  237. width: width,
  238. color: nColor,
  239. strokeColor: nLineColor,
  240. lineWidth: nLinewidth,
  241. brushType: 'both'
  242. },
  243. highlightStyle: {
  244. color: eColor,
  245. strokeColor: eLineColor,
  246. lineWidth: eLinewidth
  247. },
  248. _seriesIndex: seriesIndex
  249. };
  250. itemShape = this.addLabel(itemShape, serie, data, name);
  251. ecData.pack(itemShape, serie, seriesIndex, data, dataIndex, name);
  252. itemShape = new CandleShape(itemShape);
  253. return itemShape;
  254. },
  255. getMarkCoord: function (seriesIndex, mpData) {
  256. var serie = this.series[seriesIndex];
  257. var xAxis = this.component.xAxis.getAxis(serie.xAxisIndex);
  258. var yAxis = this.component.yAxis.getAxis(serie.yAxisIndex);
  259. return [
  260. typeof mpData.xAxis != 'string' && xAxis.getCoordByIndex ? xAxis.getCoordByIndex(mpData.xAxis || 0) : xAxis.getCoord(mpData.xAxis || 0),
  261. typeof mpData.yAxis != 'string' && yAxis.getCoordByIndex ? yAxis.getCoordByIndex(mpData.yAxis || 0) : yAxis.getCoord(mpData.yAxis || 0)
  262. ];
  263. },
  264. refresh: function (newOption) {
  265. if (newOption) {
  266. this.option = newOption;
  267. this.series = newOption.series;
  268. }
  269. this.backupShapeList();
  270. this._buildShape();
  271. },
  272. addDataAnimation: function (params, done) {
  273. var series = this.series;
  274. var aniMap = {};
  275. for (var i = 0, l = params.length; i < l; i++) {
  276. aniMap[params[i][0]] = params[i];
  277. }
  278. var x;
  279. var dx;
  280. var y;
  281. var serie;
  282. var seriesIndex;
  283. var dataIndex;
  284. var aniCount = 0;
  285. function animationDone() {
  286. aniCount--;
  287. if (aniCount === 0) {
  288. done && done();
  289. }
  290. }
  291. for (var i = 0, l = this.shapeList.length; i < l; i++) {
  292. seriesIndex = this.shapeList[i]._seriesIndex;
  293. if (aniMap[seriesIndex] && !aniMap[seriesIndex][3]) {
  294. if (this.shapeList[i].type === 'candle') {
  295. dataIndex = ecData.get(this.shapeList[i], 'dataIndex');
  296. serie = series[seriesIndex];
  297. if (aniMap[seriesIndex][2] && dataIndex === serie.data.length - 1) {
  298. this.zr.delShape(this.shapeList[i].id);
  299. continue;
  300. } else if (!aniMap[seriesIndex][2] && dataIndex === 0) {
  301. this.zr.delShape(this.shapeList[i].id);
  302. continue;
  303. }
  304. dx = this.component.xAxis.getAxis(serie.xAxisIndex || 0).getGap();
  305. x = aniMap[seriesIndex][2] ? dx : -dx;
  306. y = 0;
  307. aniCount++;
  308. this.zr.animate(this.shapeList[i].id, '').when(this.query(this.option, 'animationDurationUpdate'), {
  309. position: [
  310. x,
  311. y
  312. ]
  313. }).done(animationDone).start();
  314. }
  315. }
  316. }
  317. if (!aniCount) {
  318. animationDone();
  319. }
  320. }
  321. };
  322. zrUtil.inherits(K, ChartBase);
  323. require('../chart').define('k', K);
  324. return K;
  325. });