move.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. var Util = require('../../util/common');
  2. var Helper = require('../helper');
  3. var TOUCH_EVENTS = ['touchstart', 'touchmove', 'touchend', 'touchStart', 'touchMove', 'touchEnd'];
  4. var DAY_TIMESTAMPS = 86400000;
  5. module.exports = {
  6. _handleMove: function _handleMove(e) {
  7. if (e.type === 'swipe' && e.deltaTime > 350) {
  8. // 区分 pan 操作和 swipe 操作
  9. return null;
  10. }
  11. var currentDeltaX = this.currentDeltaX,
  12. currentDeltaY = this.currentDeltaY,
  13. lastPoint = this.lastPoint;
  14. var deltaX;
  15. var deltaY;
  16. if (TOUCH_EVENTS.indexOf(e.type) !== -1) {
  17. // support touch and miniprogram
  18. var currentPoint = e.touches[0];
  19. deltaX = currentPoint.x - lastPoint.x;
  20. deltaY = currentPoint.y - lastPoint.y;
  21. this.lastPoint = currentPoint;
  22. } else if (currentDeltaX !== null && currentDeltaY !== null) {
  23. deltaX = e.deltaX - currentDeltaX;
  24. deltaY = e.deltaY - currentDeltaY;
  25. this.currentDeltaX = e.deltaX;
  26. this.currentDeltaY = e.deltaY;
  27. }
  28. if (Math.abs(deltaX) > 0 || Math.abs(deltaY) > 0) {
  29. var lastTimestamp = this._timestamp;
  30. var now = +new Date();
  31. if (now - lastTimestamp > 16) {
  32. this._doMove(deltaX, deltaY);
  33. this._timestamp = now;
  34. }
  35. }
  36. },
  37. _doMove: function _doMove(deltaX, deltaY) {
  38. var self = this;
  39. var mode = self.mode,
  40. chart = self.chart,
  41. limitRange = self.limitRange;
  42. var coord = chart.get('coord');
  43. var start = coord.start,
  44. end = coord.end;
  45. var data = chart.get('data');
  46. if (Util.directionEnabled(mode, 'x') && deltaX !== 0) {
  47. var xScale = chart.getXScale();
  48. var xField = xScale.field;
  49. if (!limitRange[xField]) {
  50. limitRange[xField] = Helper.getLimitRange(data, xScale);
  51. }
  52. var coordWidth = end.x - start.x;
  53. if (xScale.isCategory) {
  54. self._handleCatScale(xScale, deltaX, coordWidth);
  55. } else if (xScale.isLinear) {
  56. self._handleLinearScale(xScale, deltaX, coordWidth, 'x');
  57. }
  58. var xDef = Helper.getColDef(chart, xField);
  59. self.xRange = Helper.getFieldRange(xDef, limitRange[xField], xScale.type);
  60. }
  61. if (Util.directionEnabled(mode, 'y') && deltaY !== 0) {
  62. var coordHeight = start.y - end.y;
  63. var yScales = chart.getYScales();
  64. Util.each(yScales, function (yScale) {
  65. var yField = yScale.field;
  66. if (!limitRange[yField]) {
  67. limitRange[yField] = Helper.getLimitRange(data, yScale);
  68. }
  69. yScale.isLinear && self._handleLinearScale(yScale, deltaY, coordHeight, 'y');
  70. });
  71. var yDef = Helper.getColDef(chart, yScales[0].field);
  72. self.yRange = Helper.getFieldRange(yDef, limitRange[yScales[0].field], yScales[0].type);
  73. }
  74. chart.repaint();
  75. },
  76. _handleLinearScale: function _handleLinearScale(scale, delta, range, flag) {
  77. var field = scale.field,
  78. min = scale.min,
  79. max = scale.max;
  80. var limitRange = this.limitRange;
  81. if (min === limitRange[field].min && max === limitRange[field].max) return;
  82. var ratio = delta / range;
  83. var panValue = ratio * (max - min);
  84. var newMax = flag === 'x' ? max - panValue : max + panValue;
  85. var newMin = flag === 'x' ? min - panValue : min + panValue;
  86. if (limitRange[field] && !Util.isNil(limitRange[field].min) && newMin <= limitRange[field].min) {
  87. newMin = limitRange[field].min;
  88. newMax = max - min + newMin;
  89. }
  90. if (limitRange[field] && !Util.isNil(limitRange[field].max) && newMax >= limitRange[field].max) {
  91. newMax = limitRange[field].max;
  92. newMin = newMax - (max - min);
  93. }
  94. this.updateLinearScale(field, newMin, newMax);
  95. },
  96. _handleCatScale: function _handleCatScale(scale, delta, range) {
  97. var type = scale.type,
  98. field = scale.field,
  99. values = scale.values,
  100. ticks = scale.ticks;
  101. var originValues = this.limitRange[field];
  102. var lastValueIndex = originValues.length - 1;
  103. var currentLength = values.length;
  104. var speed = this.speed || 1;
  105. var step = range / (currentLength * speed);
  106. var firstIndex = originValues.indexOf(values[0]);
  107. var lastIndex = originValues.indexOf(values[currentLength - 1]);
  108. var minIndex = firstIndex;
  109. var maxIndex = lastIndex;
  110. var ratio = Math.abs(delta / range);
  111. var panStep = this.step || Math.max(1, parseInt(ratio * currentLength));
  112. this._panCumulativeDelta += delta;
  113. minIndex = this._panCumulativeDelta > step ? Math.max(0, minIndex - panStep) : this._panCumulativeDelta < -step ? Math.min(lastValueIndex - currentLength + 1, minIndex + panStep) : minIndex;
  114. maxIndex = Math.min(lastValueIndex, minIndex + currentLength - 1);
  115. if (minIndex === firstIndex && maxIndex === lastIndex) {
  116. return null;
  117. }
  118. var newValues = originValues.slice(minIndex, maxIndex + 1);
  119. var newTicks = null;
  120. if (type === 'timeCat') {
  121. var tickGap = ticks.length > 2 ? ticks[1] - ticks[0] : DAY_TIMESTAMPS;
  122. if (this._panCumulativeDelta > step) {
  123. for (var i = ticks[0] - tickGap; i >= newValues[0]; i -= tickGap) {
  124. ticks.unshift(i);
  125. }
  126. } else if (this._panCumulativeDelta < -step) {
  127. for (var _i = ticks[ticks.length - 1] + tickGap; _i <= newValues[newValues.length - 1]; _i += tickGap) {
  128. ticks.push(_i);
  129. }
  130. }
  131. newTicks = ticks;
  132. }
  133. this.updateCatScale(field, newValues, newTicks, originValues, minIndex, maxIndex);
  134. this._panCumulativeDelta = minIndex !== firstIndex ? 0 : this._panCumulativeDelta;
  135. }
  136. };