WhiskerBoxDraw.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. var zrUtil = require("zrender/lib/core/util");
  2. var graphic = require("../../util/graphic");
  3. var Path = require("zrender/lib/graphic/Path");
  4. /**
  5. * @module echarts/chart/helper/Symbol
  6. */
  7. var WhiskerPath = Path.extend({
  8. type: 'whiskerInBox',
  9. shape: {},
  10. buildPath: function (ctx, shape) {
  11. for (var i in shape) {
  12. if (shape.hasOwnProperty(i) && i.indexOf('ends') === 0) {
  13. var pts = shape[i];
  14. ctx.moveTo(pts[0][0], pts[0][1]);
  15. ctx.lineTo(pts[1][0], pts[1][1]);
  16. }
  17. }
  18. }
  19. });
  20. /**
  21. * @constructor
  22. * @alias {module:echarts/chart/helper/WhiskerBox}
  23. * @param {module:echarts/data/List} data
  24. * @param {number} idx
  25. * @param {Function} styleUpdater
  26. * @param {boolean} isInit
  27. * @extends {module:zrender/graphic/Group}
  28. */
  29. function WhiskerBox(data, idx, styleUpdater, isInit) {
  30. graphic.Group.call(this);
  31. /**
  32. * @type {number}
  33. * @readOnly
  34. */
  35. this.bodyIndex;
  36. /**
  37. * @type {number}
  38. * @readOnly
  39. */
  40. this.whiskerIndex;
  41. /**
  42. * @type {Function}
  43. */
  44. this.styleUpdater = styleUpdater;
  45. this._createContent(data, idx, isInit);
  46. this.updateData(data, idx, isInit);
  47. /**
  48. * Last series model.
  49. * @type {module:echarts/model/Series}
  50. */
  51. this._seriesModel;
  52. }
  53. var whiskerBoxProto = WhiskerBox.prototype;
  54. whiskerBoxProto._createContent = function (data, idx, isInit) {
  55. var itemLayout = data.getItemLayout(idx);
  56. var constDim = itemLayout.chartLayout === 'horizontal' ? 1 : 0;
  57. var count = 0; // Whisker element.
  58. this.add(new graphic.Polygon({
  59. shape: {
  60. points: isInit ? transInit(itemLayout.bodyEnds, constDim, itemLayout) : itemLayout.bodyEnds
  61. },
  62. style: {
  63. strokeNoScale: true
  64. },
  65. z2: 100
  66. }));
  67. this.bodyIndex = count++; // Box element.
  68. var whiskerEnds = zrUtil.map(itemLayout.whiskerEnds, function (ends) {
  69. return isInit ? transInit(ends, constDim, itemLayout) : ends;
  70. });
  71. this.add(new WhiskerPath({
  72. shape: makeWhiskerEndsShape(whiskerEnds),
  73. style: {
  74. strokeNoScale: true
  75. },
  76. z2: 100
  77. }));
  78. this.whiskerIndex = count++;
  79. };
  80. function transInit(points, dim, itemLayout) {
  81. return zrUtil.map(points, function (point) {
  82. point = point.slice();
  83. point[dim] = itemLayout.initBaseline;
  84. return point;
  85. });
  86. }
  87. function makeWhiskerEndsShape(whiskerEnds) {
  88. // zr animation only support 2-dim array.
  89. var shape = {};
  90. zrUtil.each(whiskerEnds, function (ends, i) {
  91. shape['ends' + i] = ends;
  92. });
  93. return shape;
  94. }
  95. /**
  96. * Update symbol properties
  97. * @param {module:echarts/data/List} data
  98. * @param {number} idx
  99. */
  100. whiskerBoxProto.updateData = function (data, idx, isInit) {
  101. var seriesModel = this._seriesModel = data.hostModel;
  102. var itemLayout = data.getItemLayout(idx);
  103. var updateMethod = graphic[isInit ? 'initProps' : 'updateProps']; // this.childAt(this.bodyIndex).stopAnimation(true);
  104. // this.childAt(this.whiskerIndex).stopAnimation(true);
  105. updateMethod(this.childAt(this.bodyIndex), {
  106. shape: {
  107. points: itemLayout.bodyEnds
  108. }
  109. }, seriesModel, idx);
  110. updateMethod(this.childAt(this.whiskerIndex), {
  111. shape: makeWhiskerEndsShape(itemLayout.whiskerEnds)
  112. }, seriesModel, idx);
  113. this.styleUpdater.call(null, this, data, idx);
  114. };
  115. zrUtil.inherits(WhiskerBox, graphic.Group);
  116. /**
  117. * @constructor
  118. * @alias module:echarts/chart/helper/WhiskerBoxDraw
  119. */
  120. function WhiskerBoxDraw(styleUpdater) {
  121. this.group = new graphic.Group();
  122. this.styleUpdater = styleUpdater;
  123. }
  124. var whiskerBoxDrawProto = WhiskerBoxDraw.prototype;
  125. /**
  126. * Update symbols draw by new data
  127. * @param {module:echarts/data/List} data
  128. */
  129. whiskerBoxDrawProto.updateData = function (data) {
  130. var group = this.group;
  131. var oldData = this._data;
  132. var styleUpdater = this.styleUpdater;
  133. data.diff(oldData).add(function (newIdx) {
  134. if (data.hasValue(newIdx)) {
  135. var symbolEl = new WhiskerBox(data, newIdx, styleUpdater, true);
  136. data.setItemGraphicEl(newIdx, symbolEl);
  137. group.add(symbolEl);
  138. }
  139. }).update(function (newIdx, oldIdx) {
  140. var symbolEl = oldData.getItemGraphicEl(oldIdx); // Empty data
  141. if (!data.hasValue(newIdx)) {
  142. group.remove(symbolEl);
  143. return;
  144. }
  145. if (!symbolEl) {
  146. symbolEl = new WhiskerBox(data, newIdx, styleUpdater);
  147. } else {
  148. symbolEl.updateData(data, newIdx);
  149. } // Add back
  150. group.add(symbolEl);
  151. data.setItemGraphicEl(newIdx, symbolEl);
  152. }).remove(function (oldIdx) {
  153. var el = oldData.getItemGraphicEl(oldIdx);
  154. el && group.remove(el);
  155. }).execute();
  156. this._data = data;
  157. };
  158. /**
  159. * Remove symbols.
  160. * @param {module:echarts/data/List} data
  161. */
  162. whiskerBoxDrawProto.remove = function () {
  163. var group = this.group;
  164. var data = this._data;
  165. this._data = null;
  166. data && data.eachItemGraphicEl(function (el) {
  167. el && group.remove(el);
  168. });
  169. };
  170. var _default = WhiskerBoxDraw;
  171. module.exports = _default;