Region.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. var BoundingRect = require("zrender/lib/core/BoundingRect");
  2. var bbox = require("zrender/lib/core/bbox");
  3. var vec2 = require("zrender/lib/core/vector");
  4. var polygonContain = require("zrender/lib/contain/polygon");
  5. /**
  6. * @module echarts/coord/geo/Region
  7. */
  8. /**
  9. * @param {string} name
  10. * @param {Array} geometries
  11. * @param {Array.<number>} cp
  12. */
  13. function Region(name, geometries, cp) {
  14. /**
  15. * @type {string}
  16. * @readOnly
  17. */
  18. this.name = name;
  19. /**
  20. * @type {Array.<Array>}
  21. * @readOnly
  22. */
  23. this.geometries = geometries;
  24. if (!cp) {
  25. var rect = this.getBoundingRect();
  26. cp = [rect.x + rect.width / 2, rect.y + rect.height / 2];
  27. } else {
  28. cp = [cp[0], cp[1]];
  29. }
  30. /**
  31. * @type {Array.<number>}
  32. */
  33. this.center = cp;
  34. }
  35. Region.prototype = {
  36. constructor: Region,
  37. properties: null,
  38. /**
  39. * @return {module:zrender/core/BoundingRect}
  40. */
  41. getBoundingRect: function () {
  42. var rect = this._rect;
  43. if (rect) {
  44. return rect;
  45. }
  46. var MAX_NUMBER = Number.MAX_VALUE;
  47. var min = [MAX_NUMBER, MAX_NUMBER];
  48. var max = [-MAX_NUMBER, -MAX_NUMBER];
  49. var min2 = [];
  50. var max2 = [];
  51. var geometries = this.geometries;
  52. for (var i = 0; i < geometries.length; i++) {
  53. // Only support polygon
  54. if (geometries[i].type !== 'polygon') {
  55. continue;
  56. } // Doesn't consider hole
  57. var exterior = geometries[i].exterior;
  58. bbox.fromPoints(exterior, min2, max2);
  59. vec2.min(min, min, min2);
  60. vec2.max(max, max, max2);
  61. } // No data
  62. if (i === 0) {
  63. min[0] = min[1] = max[0] = max[1] = 0;
  64. }
  65. return this._rect = new BoundingRect(min[0], min[1], max[0] - min[0], max[1] - min[1]);
  66. },
  67. /**
  68. * @param {<Array.<number>} coord
  69. * @return {boolean}
  70. */
  71. contain: function (coord) {
  72. var rect = this.getBoundingRect();
  73. var geometries = this.geometries;
  74. if (!rect.contain(coord[0], coord[1])) {
  75. return false;
  76. }
  77. loopGeo: for (var i = 0, len = geometries.length; i < len; i++) {
  78. // Only support polygon.
  79. if (geometries[i].type !== 'polygon') {
  80. continue;
  81. }
  82. var exterior = geometries[i].exterior;
  83. var interiors = geometries[i].interiors;
  84. if (polygonContain.contain(exterior, coord[0], coord[1])) {
  85. // Not in the region if point is in the hole.
  86. for (var k = 0; k < (interiors ? interiors.length : 0); k++) {
  87. if (polygonContain.contain(interiors[k])) {
  88. continue loopGeo;
  89. }
  90. }
  91. return true;
  92. }
  93. }
  94. return false;
  95. },
  96. transformTo: function (x, y, width, height) {
  97. var rect = this.getBoundingRect();
  98. var aspect = rect.width / rect.height;
  99. if (!width) {
  100. width = aspect * height;
  101. } else if (!height) {
  102. height = width / aspect;
  103. }
  104. var target = new BoundingRect(x, y, width, height);
  105. var transform = rect.calculateTransform(target);
  106. var geometries = this.geometries;
  107. for (var i = 0; i < geometries.length; i++) {
  108. // Only support polygon.
  109. if (geometries[i].type !== 'polygon') {
  110. continue;
  111. }
  112. var exterior = geometries[i].exterior;
  113. var interiors = geometries[i].interiors;
  114. for (var p = 0; p < exterior.length; p++) {
  115. vec2.applyTransform(exterior[p], exterior[p], transform);
  116. }
  117. for (var h = 0; h < (interiors ? interiors.length : 0); h++) {
  118. for (var p = 0; p < interiors[h].length; p++) {
  119. vec2.applyTransform(interiors[h][p], interiors[h][p], transform);
  120. }
  121. }
  122. }
  123. rect = this._rect;
  124. rect.copy(target); // Update center
  125. this.center = [rect.x + rect.width / 2, rect.y + rect.height / 2];
  126. }
  127. };
  128. var _default = Region;
  129. module.exports = _default;