pinch.js 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. "use strict";
  2. var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
  3. var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));
  4. var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
  5. var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
  6. var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose"));
  7. function _createSuper(Derived) { return function () { var Super = (0, _getPrototypeOf2["default"])(Derived), result; if (_isNativeReflectConstruct()) { var NewTarget = (0, _getPrototypeOf2["default"])(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2["default"])(this, result); }; }
  8. function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
  9. var Util = require('../util/common');
  10. var Helper = require('./helper');
  11. var Interaction = require('./base');
  12. var Chart = require('../chart/chart');
  13. var FilterPlugin = require('../plugin/filter');
  14. var updateScaleMixin = require('./mixin/update-scale');
  15. var Pinch = /*#__PURE__*/function (_Interaction) {
  16. (0, _inheritsLoose2["default"])(Pinch, _Interaction);
  17. var _super = _createSuper(Pinch);
  18. var _proto = Pinch.prototype;
  19. _proto.getDefaultCfg = function getDefaultCfg() {
  20. var defaultCfg = _Interaction.prototype.getDefaultCfg.call(this);
  21. return Util.mix({}, defaultCfg, {
  22. startEvent: 'pinchstart',
  23. processEvent: 'pinch',
  24. endEvent: 'pinchend',
  25. resetEvent: 'touchend',
  26. pressThreshold: 9,
  27. // Minimal movement that is allowed while pressing
  28. pressTime: 251,
  29. // Minimal press time in ms
  30. mode: 'x',
  31. currentPinchScaling: null,
  32. originValues: null,
  33. minScale: null,
  34. maxScale: null,
  35. limitRange: {},
  36. sensitivity: 1,
  37. _pinchCumulativeDelta: 0,
  38. _timestamp: 0
  39. });
  40. };
  41. function Pinch(cfg, chart) {
  42. var _this;
  43. _this = _Interaction.call(this, cfg, chart) || this;
  44. var self = (0, _assertThisInitialized2["default"])(_this);
  45. var hammer = self.hammer;
  46. hammer.get('pinch').set({
  47. // open pinch recognizer
  48. enable: true
  49. });
  50. chart.registerPlugins([FilterPlugin, {
  51. changeData: function changeData() {
  52. self.limitRange = {};
  53. self.originTicks = null;
  54. },
  55. clear: function clear() {
  56. self.limitRange = {};
  57. self.originTicks = null;
  58. }
  59. }]);
  60. Util.mix(self, updateScaleMixin);
  61. return _this;
  62. }
  63. _proto.start = function start() {
  64. if (this.pressed) return;
  65. this.currentPinchScaling = 1;
  66. };
  67. _proto.process = function process(e) {
  68. if (this.pressed) return;
  69. this._handlePinch(e);
  70. };
  71. _proto.end = function end(e) {
  72. if (this.pressed) return;
  73. this._handlePinch(e);
  74. this.currentPinchScaling = null; // reset
  75. this.pinchCumulativeDelta = 0;
  76. };
  77. _proto._handlePinch = function _handlePinch(e) {
  78. var currentPinchScaling = this.currentPinchScaling;
  79. var diff = 1 / currentPinchScaling * e.scale;
  80. var rect = e.target.getBoundingClientRect();
  81. var offsetX = e.center.x - rect.left;
  82. var offsetY = e.center.y - rect.top;
  83. var center = {
  84. x: offsetX,
  85. y: offsetY
  86. }; // fingers position difference
  87. var x = Math.abs(e.pointers[0].clientX - e.pointers[1].clientX);
  88. var y = Math.abs(e.pointers[0].clientY - e.pointers[1].clientY); // diagonal fingers will change both (xy) axes
  89. var p = x / y;
  90. var xy;
  91. if (p > 0.3 && p < 1.7) {
  92. xy = 'xy';
  93. } else if (x > y) {
  94. xy = 'x';
  95. } else {
  96. xy = 'y';
  97. }
  98. var lastTimestamp = this._timestamp;
  99. var now = +new Date();
  100. if (now - lastTimestamp > 16) {
  101. this._doZoom(diff, center, xy);
  102. this._timestamp = now;
  103. } // Keep track of overall scale
  104. this.currentPinchScaling = e.scale;
  105. };
  106. _proto._doZoom = function _doZoom(diff, center, whichAxes) {
  107. var self = this;
  108. var mode = self.mode,
  109. chart = self.chart,
  110. limitRange = self.limitRange; // Which axe should be modified when figers were used.
  111. var _whichAxes;
  112. if (mode === 'xy' && whichAxes !== undefined) {
  113. // based on fingers positions
  114. _whichAxes = whichAxes;
  115. } else {
  116. _whichAxes = 'xy';
  117. }
  118. var data = chart.get('data');
  119. if (Util.directionEnabled(mode, 'x') && Util.directionEnabled(_whichAxes, 'x')) {
  120. // x
  121. var xScale = chart.getXScale();
  122. var xField = xScale.field;
  123. if (!limitRange[xField]) {
  124. limitRange[xField] = Helper.getLimitRange(data, xScale);
  125. }
  126. if (xScale.isCategory) {
  127. // 横轴为分类类型
  128. self._zoomCatScale(xScale, diff, center);
  129. } else if (xScale.isLinear) {
  130. self._zoomLinearScale(xScale, diff, center, 'x');
  131. }
  132. this.xRange = Helper.getFieldRange(xScale, limitRange[xField], xScale.type);
  133. }
  134. if (Util.directionEnabled(mode, 'y') && Util.directionEnabled(_whichAxes, 'y')) {
  135. // y
  136. var yScales = chart.getYScales();
  137. Util.each(yScales, function (yScale) {
  138. var yField = yScale.field;
  139. if (!limitRange[yField]) {
  140. limitRange[yField] = Helper.getLimitRange(data, yScale);
  141. }
  142. yScale.isLinear && self._zoomLinearScale(yScale, diff, center, 'y');
  143. });
  144. var scale = yScales[0];
  145. this.yRange = Helper.getFieldRange(scale, limitRange[scale.field], scale.type);
  146. }
  147. chart.repaint();
  148. };
  149. _proto._zoomLinearScale = function _zoomLinearScale(scale, zoom, center, flag) {
  150. var chart = this.chart;
  151. var min = scale.min,
  152. max = scale.max,
  153. field = scale.field;
  154. var valueRange = max - min;
  155. var limitRange = this.limitRange;
  156. var originRange = limitRange[field].max - limitRange[field].min;
  157. var coord = chart.get('coord');
  158. var newDiff = valueRange * (zoom - 1);
  159. if (this.minScale && zoom < 1) {
  160. // zoom in
  161. var maxRange = originRange / this.minScale;
  162. newDiff = Math.max(valueRange - maxRange, newDiff);
  163. }
  164. if (this.maxScale && zoom >= 1) {
  165. // zoom out
  166. var minRange = originRange / this.maxScale;
  167. newDiff = Math.min(valueRange - minRange, newDiff);
  168. }
  169. var offsetPoint = coord.invertPoint(center);
  170. var percent = flag === 'x' ? offsetPoint.x : offsetPoint.y;
  171. var minDelta = newDiff * percent;
  172. var maxDelta = newDiff * (1 - percent);
  173. var newMax = max - maxDelta;
  174. var newMin = min + minDelta;
  175. this.updateLinearScale(field, newMin, newMax);
  176. } // 针对分类类型
  177. ;
  178. _proto._zoomCatScale = function _zoomCatScale(scale, zoom, center) {
  179. var pinchCumulativeDelta = this._pinchCumulativeDelta;
  180. var sensitivity = this.sensitivity;
  181. pinchCumulativeDelta = zoom > 1 ? pinchCumulativeDelta + 1 : pinchCumulativeDelta - 1;
  182. this._pinchCumulativeDelta = pinchCumulativeDelta;
  183. var field = scale.field,
  184. values = scale.values;
  185. var chart = this.chart;
  186. var coord = chart.get('coord');
  187. if (!this.originTicks) {
  188. this.originTicks = scale.ticks;
  189. }
  190. var originValues = this.limitRange[field];
  191. var originValuesLen = originValues.length;
  192. var minScale = this.minScale || 1;
  193. var maxScale = this.maxScale || 5;
  194. var minCount = parseInt(originValuesLen / maxScale);
  195. var maxCount = parseInt(originValuesLen / minScale);
  196. var currentLen = values.length;
  197. if (pinchCumulativeDelta > 0 && currentLen <= minCount) {
  198. return null;
  199. }
  200. if (pinchCumulativeDelta < 0 && currentLen >= maxCount) {
  201. return null;
  202. }
  203. var lastLabelIndex = originValuesLen - 1;
  204. var firstValue = values[0];
  205. var lastValue = values[currentLen - 1];
  206. var minIndex = originValues.indexOf(firstValue);
  207. var maxIndex = originValues.indexOf(lastValue);
  208. var chartCenter = (coord.start.x + coord.end.x) / 2;
  209. var centerPointer = center.x;
  210. if (Math.abs(pinchCumulativeDelta) > sensitivity) {
  211. var deltaCount = Math.max(1, parseInt(currentLen * Math.abs(zoom - 1)));
  212. if (pinchCumulativeDelta < 0) {
  213. if (centerPointer >= chartCenter) {
  214. if (minIndex <= 0) {
  215. maxIndex = Math.min(lastLabelIndex, maxIndex + deltaCount);
  216. } else {
  217. minIndex = Math.max(0, minIndex - deltaCount);
  218. }
  219. } else if (centerPointer < chartCenter) {
  220. if (maxIndex >= lastLabelIndex) {
  221. minIndex = Math.max(0, minIndex - deltaCount);
  222. } else {
  223. maxIndex = Math.min(lastLabelIndex, maxIndex + deltaCount);
  224. }
  225. }
  226. this._pinchCumulativeDelta = 0;
  227. } else if (pinchCumulativeDelta > 0) {
  228. if (centerPointer >= chartCenter) {
  229. minIndex = minIndex < maxIndex ? minIndex = Math.min(maxIndex, minIndex + deltaCount) : minIndex;
  230. } else if (centerPointer < chartCenter) {
  231. maxIndex = maxIndex > minIndex ? maxIndex = Math.max(minIndex, maxIndex - deltaCount) : maxIndex;
  232. }
  233. this._pinchCumulativeDelta = 0;
  234. }
  235. var newValues = originValues.slice(minIndex, maxIndex + 1);
  236. this.updateCatScale(field, newValues, this.originTicks, originValues, minIndex, maxIndex);
  237. }
  238. };
  239. return Pinch;
  240. }(Interaction);
  241. Chart.registerInteraction('pinch', Pinch);
  242. module.exports = Pinch;