View.js 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. var zrUtil = require("zrender/lib/core/util");
  2. var vector = require("zrender/lib/core/vector");
  3. var matrix = require("zrender/lib/core/matrix");
  4. var BoundingRect = require("zrender/lib/core/BoundingRect");
  5. var Transformable = require("zrender/lib/mixin/Transformable");
  6. /**
  7. * Simple view coordinate system
  8. * Mapping given x, y to transformd view x, y
  9. */
  10. var v2ApplyTransform = vector.applyTransform; // Dummy transform node
  11. function TransformDummy() {
  12. Transformable.call(this);
  13. }
  14. zrUtil.mixin(TransformDummy, Transformable);
  15. function View(name) {
  16. /**
  17. * @type {string}
  18. */
  19. this.name = name;
  20. /**
  21. * @type {Object}
  22. */
  23. this.zoomLimit;
  24. Transformable.call(this);
  25. this._roamTransform = new TransformDummy();
  26. this._viewTransform = new TransformDummy();
  27. this._center;
  28. this._zoom;
  29. }
  30. View.prototype = {
  31. constructor: View,
  32. type: 'view',
  33. /**
  34. * @param {Array.<string>}
  35. * @readOnly
  36. */
  37. dimensions: ['x', 'y'],
  38. /**
  39. * Set bounding rect
  40. * @param {number} x
  41. * @param {number} y
  42. * @param {number} width
  43. * @param {number} height
  44. */
  45. // PENDING to getRect
  46. setBoundingRect: function (x, y, width, height) {
  47. this._rect = new BoundingRect(x, y, width, height);
  48. return this._rect;
  49. },
  50. /**
  51. * @return {module:zrender/core/BoundingRect}
  52. */
  53. // PENDING to getRect
  54. getBoundingRect: function () {
  55. return this._rect;
  56. },
  57. /**
  58. * @param {number} x
  59. * @param {number} y
  60. * @param {number} width
  61. * @param {number} height
  62. */
  63. setViewRect: function (x, y, width, height) {
  64. this.transformTo(x, y, width, height);
  65. this._viewRect = new BoundingRect(x, y, width, height);
  66. },
  67. /**
  68. * Transformed to particular position and size
  69. * @param {number} x
  70. * @param {number} y
  71. * @param {number} width
  72. * @param {number} height
  73. */
  74. transformTo: function (x, y, width, height) {
  75. var rect = this.getBoundingRect();
  76. var viewTransform = this._viewTransform;
  77. viewTransform.transform = rect.calculateTransform(new BoundingRect(x, y, width, height));
  78. viewTransform.decomposeTransform();
  79. this._updateTransform();
  80. },
  81. /**
  82. * Set center of view
  83. * @param {Array.<number>} [centerCoord]
  84. */
  85. setCenter: function (centerCoord) {
  86. if (!centerCoord) {
  87. return;
  88. }
  89. this._center = centerCoord;
  90. this._updateCenterAndZoom();
  91. },
  92. /**
  93. * @param {number} zoom
  94. */
  95. setZoom: function (zoom) {
  96. zoom = zoom || 1;
  97. var zoomLimit = this.zoomLimit;
  98. if (zoomLimit) {
  99. if (zoomLimit.max != null) {
  100. zoom = Math.min(zoomLimit.max, zoom);
  101. }
  102. if (zoomLimit.min != null) {
  103. zoom = Math.max(zoomLimit.min, zoom);
  104. }
  105. }
  106. this._zoom = zoom;
  107. this._updateCenterAndZoom();
  108. },
  109. /**
  110. * Get default center without roam
  111. */
  112. getDefaultCenter: function () {
  113. // Rect before any transform
  114. var rawRect = this.getBoundingRect();
  115. var cx = rawRect.x + rawRect.width / 2;
  116. var cy = rawRect.y + rawRect.height / 2;
  117. return [cx, cy];
  118. },
  119. getCenter: function () {
  120. return this._center || this.getDefaultCenter();
  121. },
  122. getZoom: function () {
  123. return this._zoom || 1;
  124. },
  125. /**
  126. * @return {Array.<number}
  127. */
  128. getRoamTransform: function () {
  129. return this._roamTransform;
  130. },
  131. _updateCenterAndZoom: function () {
  132. // Must update after view transform updated
  133. var viewTransformMatrix = this._viewTransform.getLocalTransform();
  134. var roamTransform = this._roamTransform;
  135. var defaultCenter = this.getDefaultCenter();
  136. var center = this.getCenter();
  137. var zoom = this.getZoom();
  138. center = vector.applyTransform([], center, viewTransformMatrix);
  139. defaultCenter = vector.applyTransform([], defaultCenter, viewTransformMatrix);
  140. roamTransform.origin = center;
  141. roamTransform.position = [defaultCenter[0] - center[0], defaultCenter[1] - center[1]];
  142. roamTransform.scale = [zoom, zoom];
  143. this._updateTransform();
  144. },
  145. /**
  146. * Update transform from roam and mapLocation
  147. * @private
  148. */
  149. _updateTransform: function () {
  150. var roamTransform = this._roamTransform;
  151. var viewTransform = this._viewTransform;
  152. viewTransform.parent = roamTransform;
  153. roamTransform.updateTransform();
  154. viewTransform.updateTransform();
  155. viewTransform.transform && matrix.copy(this.transform || (this.transform = []), viewTransform.transform);
  156. if (this.transform) {
  157. this.invTransform = this.invTransform || [];
  158. matrix.invert(this.invTransform, this.transform);
  159. } else {
  160. this.invTransform = null;
  161. }
  162. this.decomposeTransform();
  163. },
  164. /**
  165. * @return {module:zrender/core/BoundingRect}
  166. */
  167. getViewRect: function () {
  168. return this._viewRect;
  169. },
  170. /**
  171. * Get view rect after roam transform
  172. * @return {module:zrender/core/BoundingRect}
  173. */
  174. getViewRectAfterRoam: function () {
  175. var rect = this.getBoundingRect().clone();
  176. rect.applyTransform(this.transform);
  177. return rect;
  178. },
  179. /**
  180. * Convert a single (lon, lat) data item to (x, y) point.
  181. * @param {Array.<number>} data
  182. * @return {Array.<number>}
  183. */
  184. dataToPoint: function (data) {
  185. var transform = this.transform;
  186. return transform ? v2ApplyTransform([], data, transform) : [data[0], data[1]];
  187. },
  188. /**
  189. * Convert a (x, y) point to (lon, lat) data
  190. * @param {Array.<number>} point
  191. * @return {Array.<number>}
  192. */
  193. pointToData: function (point) {
  194. var invTransform = this.invTransform;
  195. return invTransform ? v2ApplyTransform([], point, invTransform) : [point[0], point[1]];
  196. },
  197. /**
  198. * @implements
  199. * see {module:echarts/CoodinateSystem}
  200. */
  201. convertToPixel: zrUtil.curry(doConvert, 'dataToPoint'),
  202. /**
  203. * @implements
  204. * see {module:echarts/CoodinateSystem}
  205. */
  206. convertFromPixel: zrUtil.curry(doConvert, 'pointToData'),
  207. /**
  208. * @implements
  209. * see {module:echarts/CoodinateSystem}
  210. */
  211. containPoint: function (point) {
  212. return this.getViewRectAfterRoam().contain(point[0], point[1]);
  213. }
  214. /**
  215. * @return {number}
  216. */
  217. // getScalarScale: function () {
  218. // // Use determinant square root of transform to mutiply scalar
  219. // var m = this.transform;
  220. // var det = Math.sqrt(Math.abs(m[0] * m[3] - m[2] * m[1]));
  221. // return det;
  222. // }
  223. };
  224. zrUtil.mixin(View, Transformable);
  225. function doConvert(methodName, ecModel, finder, value) {
  226. var seriesModel = finder.seriesModel;
  227. var coordSys = seriesModel ? seriesModel.coordinateSystem : null; // e.g., graph.
  228. return coordSys === this ? coordSys[methodName](value) : null;
  229. }
  230. var _default = View;
  231. module.exports = _default;