interval-select.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. import { mix, each, isWx, isMy, isObject, isObjectValueEqual, createEvent } from '../util/common';
  2. import { isPointInPlot } from '../util/helper';
  3. import Interaction from './base';
  4. import Chart from '../chart/chart';
  5. class IntervalSelect extends Interaction {
  6. getDefaultCfg() {
  7. var defaultCfg = super.getDefaultCfg();
  8. defaultCfg = mix({}, defaultCfg, {
  9. startEvent: 'tap',
  10. processEvent: null,
  11. selectAxis: true,
  12. selectAxisStyle: {
  13. fontWeight: 'bold'
  14. },
  15. mode: 'shape',
  16. selectStyle: {
  17. fillOpacity: 1
  18. },
  19. unSelectStyle: {
  20. fillOpacity: 0.4
  21. },
  22. cancelable: true,
  23. defaultSelected: null // set the default selected shape
  24. });
  25. if (isWx || isMy) {
  26. // 小程序
  27. defaultCfg.startEvent = 'touchstart';
  28. defaultCfg.endEvent = 'touchend';
  29. }
  30. return defaultCfg;
  31. }
  32. constructor(cfg, chart) {
  33. super(cfg, chart);
  34. var defaultSelected = this.defaultSelected;
  35. if (isObject(defaultSelected)) {
  36. var {
  37. selectedShape,
  38. unSelectedShapes
  39. } = this._selectShapesByData(defaultSelected);
  40. selectedShape && this._selectShapes(selectedShape, unSelectedShapes);
  41. this.selectedShape = selectedShape;
  42. }
  43. }
  44. _getIntervalShapes() {
  45. var children = [];
  46. var chart = this.chart;
  47. var geoms = chart.get('geoms');
  48. geoms.forEach(function (geom) {
  49. if (geom.get('type') === 'interval') {
  50. // only works for Interval geometry type
  51. var container = geom.get('container');
  52. children = children.concat(container.get('children'));
  53. }
  54. });
  55. return children;
  56. }
  57. _resetShape(shape) {
  58. var originAttrs = shape.get('_originAttrs');
  59. if (originAttrs) {
  60. shape._attrs.attrs = originAttrs;
  61. shape.set('_originAttrs', null);
  62. }
  63. }
  64. _setEventData(ev) {
  65. var selectedShape = this.selectedShape;
  66. if (selectedShape && !selectedShape.get('destroyed')) {
  67. ev.data = selectedShape.get('origin')._origin;
  68. ev.shapeInfo = selectedShape.get('origin');
  69. ev.shape = selectedShape;
  70. ev.selected = !!selectedShape.get('_selected');
  71. }
  72. }
  73. _selectShapesByData(data) {
  74. var children = this._getIntervalShapes();
  75. var selectedShape = null;
  76. var unSelectedShapes = [];
  77. each(children, function (child) {
  78. if (child.get('isShape') && child.get('className') === 'interval') {
  79. // get geometry's shape
  80. var shapeData = child.get('origin')._origin;
  81. if (isObjectValueEqual(shapeData, data)) {
  82. selectedShape = child;
  83. } else {
  84. unSelectedShapes.push(child);
  85. }
  86. }
  87. });
  88. return {
  89. selectedShape,
  90. unSelectedShapes
  91. };
  92. }
  93. _selectShapes(selectedShape, unSelectedShapes) {
  94. var {
  95. selectStyle,
  96. unSelectStyle,
  97. selectAxisStyle,
  98. chart
  99. } = this;
  100. if (!selectedShape.get('_originAttrs')) {
  101. var originAttrs = Object.assign({}, selectedShape.attr());
  102. selectedShape.set('_originAttrs', originAttrs);
  103. }
  104. selectedShape.attr(selectStyle);
  105. each(unSelectedShapes, function (child) {
  106. if (!child.get('_originAttrs')) {
  107. var _originAttrs = Object.assign({}, child.attr());
  108. child.set('_originAttrs', _originAttrs);
  109. } else {
  110. child.attr(child.get('_originAttrs'));
  111. }
  112. child.set('_selected', false);
  113. unSelectStyle && child.attr(unSelectStyle);
  114. });
  115. selectedShape.set('_selected', true);
  116. if (this.selectAxis) {
  117. if (this.selectedAxisShape) {
  118. this._resetShape(this.selectedAxisShape);
  119. }
  120. var xScale = chart.getXScale();
  121. var origin = selectedShape.get('origin')._origin;
  122. var {
  123. frontPlot,
  124. backPlot
  125. } = chart.get('axisController');
  126. var axisShape;
  127. each(frontPlot.get('children').concat(backPlot.get('children')), function (s) {
  128. if (s.get('value') === xScale.scale(origin[xScale.field])) {
  129. axisShape = s;
  130. return false;
  131. }
  132. });
  133. this.selectedAxisShape = axisShape;
  134. axisShape.set('_originAttrs', Object.assign({}, axisShape.attr()));
  135. axisShape.attr(selectAxisStyle);
  136. }
  137. this.canvas.draw();
  138. }
  139. reset() {
  140. var self = this;
  141. if (!self.selectedShape) {
  142. return;
  143. }
  144. var children = self._getIntervalShapes();
  145. each(children, function (child) {
  146. self._resetShape(child);
  147. child.set('_selected', false);
  148. });
  149. if (self.selectedAxisShape) {
  150. self._resetShape(self.selectedAxisShape);
  151. }
  152. self.canvas.draw();
  153. self.selectedShape = null;
  154. self.selectedAxisShape = null;
  155. }
  156. start(ev) {
  157. var chart = this.chart;
  158. if (ev.type === 'tap') {
  159. ev.clientX = ev.center.x;
  160. ev.clientY = ev.center.y;
  161. }
  162. var {
  163. x,
  164. y
  165. } = createEvent(ev, chart);
  166. var mode = this.mode;
  167. var children = this._getIntervalShapes();
  168. var selectedShape;
  169. var unSelectedShapes = [];
  170. if (mode === 'shape') {
  171. var plot = chart.get('plotRange');
  172. if (!isPointInPlot({
  173. x,
  174. y
  175. }, plot)) {
  176. this.reset();
  177. return;
  178. }
  179. each(children, function (child) {
  180. var box = child.getBBox();
  181. if (x >= box.x && x <= box.x + box.width && y >= box.y && y <= box.height + box.y) {
  182. // inbox
  183. selectedShape = child;
  184. } else {
  185. unSelectedShapes.push(child);
  186. }
  187. });
  188. } else if (mode === 'range') {
  189. var records = chart.getSnapRecords({
  190. x,
  191. y
  192. });
  193. if (!records.length) {
  194. this.reset();
  195. return;
  196. }
  197. var data = records[0]._origin;
  198. var result = this._selectShapesByData(data);
  199. selectedShape = result.selectedShape;
  200. unSelectedShapes = result.unSelectedShapes;
  201. }
  202. if (selectedShape) {
  203. this.selectedShape = selectedShape;
  204. if (selectedShape.get('_selected')) {
  205. if (!this.cancelable) {
  206. this._setEventData(ev);
  207. return;
  208. }
  209. this.reset();
  210. } else {
  211. this._selectShapes(selectedShape, unSelectedShapes);
  212. }
  213. } else {
  214. this.reset();
  215. }
  216. this._setEventData(ev);
  217. }
  218. end(ev) {
  219. this._setEventData(ev);
  220. }
  221. }
  222. Chart.registerInteraction('interval-select', IntervalSelect);
  223. export default IntervalSelect;