auto-hide.js 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.equidistanceWithReverseBoth = exports.equidistance = exports.reserveBoth = exports.reserveLast = exports.reserveFirst = exports.getDefault = void 0;
  4. var label_1 = require("../../util/label");
  5. var matrix_1 = require("../../util/matrix");
  6. var util_1 = require("../../util/util");
  7. // 文本是否旋转
  8. function isRotate(label) {
  9. var matrix = label.attr('matrix');
  10. return matrix && matrix[0] !== 1; // 仅在这个场景下判定
  11. }
  12. function getRotateAngle(label) {
  13. var angle = isRotate(label) ? matrix_1.getAngleByMatrix(label.attr('matrix')) : 0;
  14. return angle % 360;
  15. }
  16. // autohide 不再考虑超出限制
  17. // function isOutLimit(isVertical: boolean, label: IElement, limitLength: number) {
  18. // if (!limitLength) {
  19. // // 如果没限制 limitLength 则直接返回 false
  20. // return false;
  21. // }
  22. // const canvasBBox = label.getCanvasBBox();
  23. // let isOut = false;
  24. // if (isVertical) {
  25. // isOut = canvasBBox.width > limitLength;
  26. // } else {
  27. // isOut = canvasBBox.height > limitLength;
  28. // }
  29. // return isOut;
  30. // }
  31. // 是否重叠
  32. function isOverlap(isVertical, first, second, minGap) {
  33. var overlap = false;
  34. var angle = getRotateAngle(first);
  35. var distance = isVertical
  36. ? Math.abs(second.attr('y') - first.attr('y'))
  37. : Math.abs(second.attr('x') - first.attr('x'));
  38. var prevBBox = (isVertical
  39. ? second.attr('y') > first.attr('y')
  40. : second.attr('x') > first.attr('x'))
  41. ? first.getBBox()
  42. : second.getBBox();
  43. if (isVertical) {
  44. var ratio = Math.abs(Math.cos(angle));
  45. if (util_1.near(ratio, 0, Math.PI / 180)) {
  46. overlap = prevBBox.width + minGap > distance;
  47. }
  48. else {
  49. overlap = prevBBox.height / ratio + minGap > distance;
  50. }
  51. }
  52. else {
  53. var ratio = Math.abs(Math.sin(angle));
  54. if (util_1.near(ratio, 0, Math.PI / 180)) {
  55. overlap = prevBBox.width + minGap > distance;
  56. }
  57. else {
  58. overlap = prevBBox.height / ratio + minGap > distance;
  59. }
  60. }
  61. return overlap;
  62. }
  63. // 保留第一个或者最后一个
  64. function reserveOne(isVertical, labelsGroup, reversed, autoHideCfg) {
  65. var minGap = (autoHideCfg === null || autoHideCfg === void 0 ? void 0 : autoHideCfg.minGap) || 0;
  66. var labels = labelsGroup
  67. .getChildren()
  68. .slice() // 复制数组
  69. .filter(function (item) { return item.get('visible'); });
  70. if (!labels.length) {
  71. return false;
  72. }
  73. var hasHide = false;
  74. if (reversed) {
  75. // 翻转
  76. labels.reverse();
  77. }
  78. var count = labels.length;
  79. var first = labels[0];
  80. var prev = first;
  81. for (var i = 1; i < count; i++) {
  82. var label = labels[i];
  83. var curBBox = label.getBBox();
  84. // 不再考虑超出限制,而仅仅根据是否重叠进行隐藏 isOutLimit(isVertical, label, limitLength) ||
  85. var isHide = isOverlap(isVertical, prev, label, minGap);
  86. if (isHide) {
  87. label.hide();
  88. hasHide = true;
  89. }
  90. else {
  91. prev = label;
  92. }
  93. }
  94. return hasHide;
  95. }
  96. // 均匀抽样隐藏标签,注意这里假设 label/tick 是均匀的
  97. function parityHide(isVertical, labelsGroup, autoHideCfg) {
  98. var minGap = (autoHideCfg === null || autoHideCfg === void 0 ? void 0 : autoHideCfg.minGap) || 0;
  99. var labels = labelsGroup.getChildren().slice(); // 复制数组
  100. if (labels.length < 2) {
  101. // 如果数量小于 2 则直接返回,等于 2 时可能也会重合
  102. return false;
  103. }
  104. var hasHide = false;
  105. var first = labels[0];
  106. var firstBBox = first.getBBox();
  107. var second = labels[1];
  108. var count = labels.length;
  109. var angle = getRotateAngle(first);
  110. var distance = isVertical
  111. ? Math.abs(second.attr('y') - first.attr('y'))
  112. : Math.abs(second.attr('x') - first.attr('x'));
  113. var interval = 0; // 不重叠的坐标文本间距个数
  114. if (isVertical) {
  115. // 垂直的坐标轴计算垂直方向的间距
  116. var ratio = Math.abs(Math.cos(angle));
  117. if (util_1.near(ratio, 0, Math.PI / 180)) {
  118. var maxWidth = label_1.getMaxLabelWidth(labels);
  119. interval = (maxWidth + minGap) / distance;
  120. }
  121. else {
  122. interval = (firstBBox.height / ratio + minGap) / distance;
  123. }
  124. }
  125. else {
  126. // 水平坐标轴
  127. var ratio = Math.abs(Math.sin(angle));
  128. if (util_1.near(ratio, 0, Math.PI / 180)) {
  129. var maxWidth = label_1.getMaxLabelWidth(labels);
  130. interval = (maxWidth + minGap) / distance;
  131. }
  132. else {
  133. interval = (firstBBox.height / ratio + minGap) / distance;
  134. }
  135. }
  136. // interval > 1 时需要对 label 进行隐藏
  137. if (interval > 1) {
  138. interval = Math.ceil(interval);
  139. for (var i = 0; i < count; i++) {
  140. if (i % interval !== 0) {
  141. // 仅保留被整除的 label
  142. labels[i].hide();
  143. hasHide = true;
  144. }
  145. }
  146. }
  147. return hasHide;
  148. }
  149. function getDefault() {
  150. return equidistance;
  151. }
  152. exports.getDefault = getDefault;
  153. /**
  154. * 保证首个 label 可见,即使超过 limitLength 也不隐藏
  155. * @param {boolean} isVertical 是否垂直
  156. * @param {IGroup} labelsGroup label 的分组
  157. * @param {number} limitLength 另一个方向的长度限制,autoHide 不关心
  158. * @param {AxisLabelAutoHideCfg} autoHideCfg autoHide overlap 的可选配置参数
  159. */
  160. function reserveFirst(isVertical, labelsGroup, limitLength, autoHideCfg) {
  161. return reserveOne(isVertical, labelsGroup, false, autoHideCfg);
  162. }
  163. exports.reserveFirst = reserveFirst;
  164. /**
  165. * 保证最后一个 label 可见,即使超过 limitLength 也不隐藏
  166. * @param {boolean} isVertical 是否垂直
  167. * @param {IGroup} labelsGroup label 的分组
  168. * @param {number} limitLength 另一个方向的长度限制,autoHide 不关心
  169. * @param {AxisLabelAutoHideCfg} autoHideCfg autoHide overlap 的可选配置参数
  170. */
  171. function reserveLast(isVertical, labelsGroup, limitLength, autoHideCfg) {
  172. return reserveOne(isVertical, labelsGroup, true, autoHideCfg);
  173. }
  174. exports.reserveLast = reserveLast;
  175. /**
  176. * 保证第一个最后一个 label 可见,即使超过 limitLength 也不隐藏
  177. * @param {boolean} isVertical 是否垂直
  178. * @param {IGroup} labelsGroup label 的分组
  179. * @param {number} limitLength 另一个方向的长度限制,autoHide 不关心
  180. * @param {AxisLabelAutoHideCfg} autoHideCfg autoHide overlap 的可选配置参数
  181. */
  182. function reserveBoth(isVertical, labelsGroup, limitLength, autoHideCfg) {
  183. var minGap = (autoHideCfg === null || autoHideCfg === void 0 ? void 0 : autoHideCfg.minGap) || 0;
  184. var labels = labelsGroup.getChildren().slice(); // 复制数组
  185. if (labels.length <= 2) {
  186. // 如果数量小于或等于 2 则直接返回
  187. return false;
  188. }
  189. var hasHide = false;
  190. var count = labels.length;
  191. var first = labels[0];
  192. var last = labels[count - 1];
  193. var preLabel = first;
  194. // 按照先保存第一个的逻辑循环一遍,最后一个不参与循环
  195. for (var i = 1; i < count - 1; i++) {
  196. var label = labels[i];
  197. var curBBox = label.getBBox();
  198. // 废弃 isOutLimit(isVertical, label, limitLength) ||
  199. var isHide = isOverlap(isVertical, preLabel, label, minGap);
  200. if (isHide) {
  201. label.hide();
  202. hasHide = true;
  203. }
  204. else {
  205. preLabel = label;
  206. }
  207. }
  208. var overlap = isOverlap(isVertical, preLabel, last, minGap);
  209. if (overlap) {
  210. // 发生冲突,则隐藏前一个保留后一个
  211. preLabel.hide();
  212. hasHide = true;
  213. }
  214. return hasHide;
  215. }
  216. exports.reserveBoth = reserveBoth;
  217. /**
  218. * 保证 label 均匀显示 和 不出现重叠,主要解决文本层叠的问题,对于 limitLength 不处理
  219. * @param {boolean} isVertical 是否垂直
  220. * @param {IGroup} labelsGroup label 的分组
  221. * @param {number} limitLength 另一个方向的长度限制,autoHide 不关心
  222. * @param {AxisLabelAutoHideCfg} autoHideCfg autoHide overlap 的可选配置参数
  223. */
  224. function equidistance(isVertical, labelsGroup, limitLength, autoHideCfg) {
  225. var hasHide = parityHide(isVertical, labelsGroup, autoHideCfg);
  226. // 处理 timeCat 类型的 tick,在均匀的基础上,再次检查出现重叠的进行隐藏
  227. if (reserveOne(isVertical, labelsGroup, false)) {
  228. hasHide = true;
  229. }
  230. return hasHide;
  231. }
  232. exports.equidistance = equidistance;
  233. /**
  234. * 同 equidistance, 首先会保证 labels 均匀显示,然后会保留首尾
  235. * @param isVertical
  236. * @param labelsGroup
  237. * @param {number} limitLength 另一个方向的长度限制,autoHide 不关心
  238. * @param {AxisLabelAutoHideCfg} autoHideCfg autoHide overlap 的可选配置参数
  239. */
  240. function equidistanceWithReverseBoth(isVertical, labelsGroup, limitLength, autoHideCfg) {
  241. var labels = labelsGroup.getChildren().slice(); // 复制数组
  242. var hasHide = parityHide(isVertical, labelsGroup, autoHideCfg);
  243. if (labels.length > 2) {
  244. var first = labels[0];
  245. var last = labels[labels.length - 1];
  246. // 如果第一个被隐藏了
  247. if (!first.get('visible')) {
  248. first.show();
  249. if (reserveOne(isVertical, labelsGroup, false, autoHideCfg)) {
  250. hasHide = true;
  251. }
  252. }
  253. // 如果最后一个被隐藏了
  254. if (!last.get('visible')) {
  255. last.show();
  256. if (reserveOne(isVertical, labelsGroup, true, autoHideCfg)) {
  257. hasHide = true;
  258. }
  259. }
  260. }
  261. return hasHide;
  262. }
  263. exports.equidistanceWithReverseBoth = equidistanceWithReverseBoth;
  264. //# sourceMappingURL=auto-hide.js.map