roamHelper.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing,
  13. * software distributed under the License is distributed on an
  14. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  15. * KIND, either express or implied. See the License for the
  16. * specific language governing permissions and limitations
  17. * under the License.
  18. */
  19. /**
  20. * AUTO-GENERATED FILE. DO NOT MODIFY.
  21. */
  22. /*
  23. * Licensed to the Apache Software Foundation (ASF) under one
  24. * or more contributor license agreements. See the NOTICE file
  25. * distributed with this work for additional information
  26. * regarding copyright ownership. The ASF licenses this file
  27. * to you under the Apache License, Version 2.0 (the
  28. * "License"); you may not use this file except in compliance
  29. * with the License. You may obtain a copy of the License at
  30. *
  31. * http://www.apache.org/licenses/LICENSE-2.0
  32. *
  33. * Unless required by applicable law or agreed to in writing,
  34. * software distributed under the License is distributed on an
  35. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  36. * KIND, either express or implied. See the License for the
  37. * specific language governing permissions and limitations
  38. * under the License.
  39. */
  40. import { BoundingRect } from '../../util/graphic.js';
  41. /**
  42. * [CAVEAT] `updateViewOnPan` and `updateViewOnZoom` modifies the group transform directly,
  43. * but the 'center' and 'zoom' in echarts option and 'View' coordinate system are not updated yet,
  44. * which must be performed later in 'xxxRoam' action by calling `updateCenterAndZoom`.
  45. * @see {updateCenterAndZoomInAction}
  46. */
  47. export function updateViewOnPan(controllerHost, dx, dy) {
  48. var target = controllerHost.target;
  49. target.x += dx;
  50. target.y += dy;
  51. target.dirty();
  52. }
  53. export function updateViewOnZoom(controllerHost, zoomDelta, zoomX, zoomY) {
  54. var target = controllerHost.target;
  55. var zoomLimit = controllerHost.zoomLimit;
  56. var newZoom = controllerHost.zoom = controllerHost.zoom || 1;
  57. newZoom *= zoomDelta;
  58. newZoom = clampByZoomLimit(newZoom, zoomLimit);
  59. var zoomScale = newZoom / controllerHost.zoom;
  60. controllerHost.zoom = newZoom;
  61. zoomTransformableByOrigin(target, zoomX, zoomY, zoomScale);
  62. target.dirty();
  63. }
  64. /**
  65. * A abstraction for some similar impl in roaming.
  66. */
  67. export function updateController(seriesModel, api, pointerCheckerEl, controller, controllerHost, clipRect) {
  68. var tmpRect = new BoundingRect(0, 0, 0, 0);
  69. controller.enable(seriesModel.get('roam'), {
  70. api: api,
  71. zInfo: {
  72. component: seriesModel
  73. },
  74. triggerInfo: {
  75. roamTrigger: seriesModel.get('roamTrigger'),
  76. isInSelf: function (e, x, y) {
  77. tmpRect.copy(pointerCheckerEl.getBoundingRect());
  78. tmpRect.applyTransform(pointerCheckerEl.getComputedTransform());
  79. return tmpRect.contain(x, y);
  80. },
  81. isInClip: function (e, x, y) {
  82. return !clipRect || clipRect.contain(x, y);
  83. }
  84. }
  85. });
  86. controllerHost.zoomLimit = seriesModel.get('scaleLimit');
  87. var coordinate = seriesModel.coordinateSystem;
  88. controllerHost.zoom = coordinate ? coordinate.getZoom() : 1;
  89. var type = seriesModel.subType + 'Roam';
  90. controller.off('pan').off('zoom').on('pan', function (e) {
  91. updateViewOnPan(controllerHost, e.dx, e.dy);
  92. api.dispatchAction({
  93. seriesId: seriesModel.id,
  94. type: type,
  95. dx: e.dx,
  96. dy: e.dy
  97. });
  98. }).on('zoom', function (e) {
  99. /**
  100. * FIXME: should do nothing except `api.dispatchAction` here, the other logic
  101. * should be performed in the action handler and `updateTransform`; otherwise,
  102. * they are inconsistent if user triggers this action explicitly.
  103. */
  104. updateViewOnZoom(controllerHost, e.scale, e.originX, e.originY);
  105. api.dispatchAction({
  106. seriesId: seriesModel.id,
  107. type: type,
  108. zoom: e.scale,
  109. originX: e.originX,
  110. originY: e.originY
  111. });
  112. // Only update label layout on zoom
  113. api.updateLabelLayout();
  114. });
  115. }
  116. function getCenterCoord(view, point) {
  117. // Use projected coord as center because it's linear.
  118. return view.pointToProjected ? view.pointToProjected(point) : view.pointToData(point);
  119. }
  120. /**
  121. * Should be called only in action handler.
  122. * @see {updateViewOnPan|updateViewOnZoom}
  123. */
  124. export function updateCenterAndZoomInAction(view, payload, zoomLimit) {
  125. var previousZoom = view.getZoom();
  126. var center = view.getCenter();
  127. var deltaZoom = payload.zoom;
  128. var point = view.projectedToPoint ? view.projectedToPoint(center) : view.dataToPoint(center);
  129. if (payload.dx != null && payload.dy != null) {
  130. point[0] -= payload.dx;
  131. point[1] -= payload.dy;
  132. view.setCenter(getCenterCoord(view, point));
  133. }
  134. if (deltaZoom != null) {
  135. deltaZoom = clampByZoomLimit(previousZoom * deltaZoom, zoomLimit) / previousZoom;
  136. zoomTransformableByOrigin(view, payload.originX, payload.originY, deltaZoom);
  137. view.updateTransform();
  138. // [NOTICE] Tricky: `getCetnerCoord` uses `this.invTransform` modified by the `updateTransform` above.
  139. view.setCenter(getCenterCoord(view, point));
  140. view.setZoom(deltaZoom * previousZoom);
  141. }
  142. return {
  143. center: view.getCenter(),
  144. zoom: view.getZoom()
  145. };
  146. }
  147. function zoomTransformableByOrigin(target, originX, originY, deltaZoom) {
  148. // Keep the mouse center when scaling.
  149. target.x -= (originX - target.x) * (deltaZoom - 1);
  150. target.y -= (originY - target.y) * (deltaZoom - 1);
  151. target.scaleX *= deltaZoom;
  152. target.scaleY *= deltaZoom;
  153. }
  154. export function clampByZoomLimit(zoom, zoomLimit) {
  155. if (zoomLimit) {
  156. var zoomMin = zoomLimit.min || 0;
  157. var zoomMax = zoomLimit.max || Infinity;
  158. zoom = Math.max(Math.min(zoomMax, zoom), zoomMin);
  159. }
  160. return zoom;
  161. }