index.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.Tooltip = void 0;
  4. var tslib_1 = require("tslib");
  5. var dom_util_1 = require("@antv/dom-util");
  6. var util_1 = require("@antv/util");
  7. var core_1 = require("../../core");
  8. var util_2 = require("../../util");
  9. var constant_1 = require("./constant");
  10. var Tooltip = /** @class */ (function (_super) {
  11. tslib_1.__extends(Tooltip, _super);
  12. function Tooltip(options) {
  13. var _this = this;
  14. var _a, _b;
  15. var prefixCls = (_b = (_a = options.style) === null || _a === void 0 ? void 0 : _a.template) === null || _b === void 0 ? void 0 : _b.prefixCls;
  16. var CLASS_NAME = (0, constant_1.getClassNames)(prefixCls);
  17. _this = _super.call(this, options, {
  18. data: [],
  19. x: 0,
  20. y: 0,
  21. visibility: 'visible',
  22. title: '',
  23. position: 'bottom-right',
  24. offset: [5, 5],
  25. enterable: false,
  26. container: {
  27. x: 0,
  28. y: 0,
  29. },
  30. bounding: null,
  31. template: {
  32. prefixCls: '',
  33. container: "<div class=\"".concat(CLASS_NAME.CONTAINER, "\"></div>"),
  34. title: "<div class=\"".concat(CLASS_NAME.TITLE, "\"></div>"),
  35. item: "<li class=\"".concat(CLASS_NAME.LIST_ITEM, "\" data-index={index}>\n <span class=\"").concat(CLASS_NAME.NAME, "\">\n <span class=\"").concat(CLASS_NAME.MARKER, "\" style=\"background:{color}\"></span>\n <span class=\"").concat(CLASS_NAME.NAME_LABEL, "\" title=\"{name}\">{name}</span>\n </span>\n <span class=\"").concat(CLASS_NAME.VALUE, "\" title=\"{value}\">{value}</span>\n </li>"),
  36. },
  37. style: (0, constant_1.getDefaultTooltipStyle)(prefixCls),
  38. }) || this;
  39. _this.prevCustomContentKey = _this.attributes.contentKey;
  40. _this.initShape();
  41. _this.render(_this.attributes, _this);
  42. return _this;
  43. }
  44. Object.defineProperty(Tooltip.prototype, "HTMLTooltipElement", {
  45. get: function () {
  46. return this.element;
  47. },
  48. enumerable: false,
  49. configurable: true
  50. });
  51. Tooltip.prototype.getContainer = function () {
  52. return this.element;
  53. };
  54. Object.defineProperty(Tooltip.prototype, "position", {
  55. set: function (_a) {
  56. var _b = tslib_1.__read(_a, 2), x = _b[0], y = _b[1];
  57. this.attributes.x = x;
  58. this.attributes.y = y;
  59. this.updatePosition();
  60. },
  61. enumerable: false,
  62. configurable: true
  63. });
  64. Object.defineProperty(Tooltip.prototype, "elementSize", {
  65. get: function () {
  66. var width = this.element.offsetWidth;
  67. var height = this.element.offsetHeight;
  68. return { width: width, height: height };
  69. },
  70. enumerable: false,
  71. configurable: true
  72. });
  73. Object.defineProperty(Tooltip.prototype, "HTMLTooltipItemsElements", {
  74. get: function () {
  75. var _a = this.attributes, data = _a.data, template = _a.template;
  76. return data.map(function (_a, idx) {
  77. var _b = _a.name, name = _b === void 0 ? '' : _b, _c = _a.color, color = _c === void 0 ? 'black' : _c, index = _a.index, rest = tslib_1.__rest(_a, ["name", "color", "index"]);
  78. var datum = tslib_1.__assign({ name: name, color: color, index: index !== null && index !== void 0 ? index : idx }, rest);
  79. return (0, dom_util_1.createDom)((0, util_1.substitute)(template.item, datum));
  80. });
  81. },
  82. enumerable: false,
  83. configurable: true
  84. });
  85. Tooltip.prototype.render = function (attributes, container) {
  86. this.renderHTMLTooltipElement();
  87. this.updatePosition();
  88. };
  89. Tooltip.prototype.destroy = function () {
  90. var _a;
  91. (_a = this.element) === null || _a === void 0 ? void 0 : _a.remove();
  92. _super.prototype.destroy.call(this);
  93. };
  94. /**
  95. * 如果设置了坐标值,显示过程中会立即更新位置并关闭过渡动画
  96. */
  97. Tooltip.prototype.show = function (x, y) {
  98. var _this = this;
  99. var disableTransition = x !== undefined && y !== undefined;
  100. if (disableTransition) {
  101. var transition_1 = this.element.style.transition;
  102. this.element.style.transition = 'none';
  103. this.position = [x !== null && x !== void 0 ? x : +this.attributes.x, y !== null && y !== void 0 ? y : +this.attributes.y];
  104. setTimeout(function () {
  105. _this.element.style.transition = transition_1;
  106. }, 10);
  107. }
  108. this.element.style.visibility = 'visible';
  109. };
  110. Tooltip.prototype.hide = function () {
  111. this.element.style.visibility = 'hidden';
  112. };
  113. /**
  114. * 初始化容器
  115. */
  116. Tooltip.prototype.initShape = function () {
  117. var template = this.attributes.template;
  118. this.element = (0, dom_util_1.createDom)(template.container);
  119. if (this.id)
  120. this.element.setAttribute('id', this.id);
  121. };
  122. Tooltip.prototype.renderCustomContent = function () {
  123. if (this.prevCustomContentKey !== undefined && this.prevCustomContentKey === this.attributes.contentKey)
  124. return;
  125. this.prevCustomContentKey = this.attributes.contentKey;
  126. var content = this.attributes.content;
  127. if (!content)
  128. return;
  129. if (typeof content === 'string')
  130. this.element.innerHTML = content;
  131. else
  132. this.element.replaceChildren(content);
  133. };
  134. /**
  135. * 更新 HTML 上的内容
  136. */
  137. Tooltip.prototype.renderHTMLTooltipElement = function () {
  138. var _a, _b;
  139. var _c = this.attributes, template = _c.template, title = _c.title, enterable = _c.enterable, style = _c.style, content = _c.content;
  140. var CLASS_NAME = (0, constant_1.getClassNames)(template.prefixCls);
  141. var container = this.element;
  142. this.element.style.pointerEvents = enterable ? 'auto' : 'none';
  143. if (content)
  144. this.renderCustomContent();
  145. else {
  146. if (title) {
  147. container.innerHTML = template.title;
  148. container.getElementsByClassName(CLASS_NAME.TITLE)[0].innerHTML = title;
  149. }
  150. else
  151. (_b = (_a = container.getElementsByClassName(CLASS_NAME.TITLE)) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.remove();
  152. var itemsElements = this.HTMLTooltipItemsElements;
  153. var ul = document.createElement('ul');
  154. ul.className = CLASS_NAME.LIST;
  155. ul.replaceChildren.apply(ul, tslib_1.__spreadArray([], tslib_1.__read(itemsElements), false));
  156. var list = this.element.querySelector(".".concat(CLASS_NAME.LIST));
  157. if (list)
  158. list.replaceWith(ul);
  159. else
  160. container.appendChild(ul);
  161. }
  162. (0, util_2.applyStyleSheet)(container, style);
  163. };
  164. /**
  165. * 根据 position 和指针位置,计算出 tooltip 相对于指针的偏移量
  166. * @param assignPosition {TooltipPosition} tooltip相对于指针的位置,不指定时使用默认参数
  167. */
  168. Tooltip.prototype.getRelativeOffsetFromCursor = function (assignPosition) {
  169. var _a = this.attributes, position = _a.position, offset = _a.offset;
  170. var interPosition = assignPosition || position;
  171. var finalPosition = interPosition.split('-');
  172. var positionScore = { left: [-1, 0], right: [1, 0], top: [0, -1], bottom: [0, 1] };
  173. var _b = this.elementSize, width = _b.width, height = _b.height;
  174. var absolutelyOffset = [-width / 2, -height / 2];
  175. finalPosition.forEach(function (pos) {
  176. var _a = tslib_1.__read(absolutelyOffset, 2), abs1 = _a[0], abs2 = _a[1];
  177. var _b = tslib_1.__read(positionScore[pos], 2), pos1 = _b[0], pos2 = _b[1];
  178. absolutelyOffset = [abs1 + (width / 2 + offset[0]) * pos1, abs2 + (height / 2 + offset[1]) * pos2];
  179. });
  180. return absolutelyOffset;
  181. };
  182. /**
  183. * 将相对于指针的偏移量生效到dom元素上
  184. */
  185. Tooltip.prototype.setOffsetPosition = function (_a) {
  186. var _b = tslib_1.__read(_a, 2), offsetX = _b[0], offsetY = _b[1];
  187. var _c = this.attributes, _d = _c.x, x = _d === void 0 ? 0 : _d, _e = _c.y, y = _e === void 0 ? 0 : _e, _f = _c.container, cx = _f.x, cy = _f.y;
  188. this.element.style.left = "".concat(+x + cx + offsetX, "px");
  189. this.element.style.top = "".concat(+y + cy + offsetY, "px");
  190. };
  191. /**
  192. * 更新tooltip的位置
  193. */
  194. Tooltip.prototype.updatePosition = function () {
  195. // 尝试当前的位置使用默认position能否放下
  196. // 如果不能,则改变取溢出边的反向position
  197. /**
  198. * 默认位置
  199. * ⬇️
  200. * 计算自动调整位置
  201. * ⬇️
  202. * 实际摆放位置
  203. */
  204. this.setOffsetPosition(this.autoPosition(this.getRelativeOffsetFromCursor()));
  205. };
  206. /**
  207. * 计算自动调整位置后的相对位置
  208. * @param offsetX 根据position计算的横向偏移量
  209. * @param offsetY 根据position计算的纵向偏移量
  210. */
  211. Tooltip.prototype.autoPosition = function (_a) {
  212. var _b = tslib_1.__read(_a, 2), offsetX = _b[0], offsetY = _b[1];
  213. var _c = this.attributes, cursorX = _c.x, cursorY = _c.y, bounding = _c.bounding, position = _c.position;
  214. // 如果没有设置 bounds,那么意思就是不限制空间
  215. if (!bounding)
  216. return [offsetX, offsetY];
  217. // 更新前的位置和宽度
  218. var _d = this.element, offsetWidth = _d.offsetWidth, offsetHeight = _d.offsetHeight;
  219. // 预期放置的位置
  220. var _e = tslib_1.__read([+cursorX + offsetX, +cursorY + offsetY], 2), expectLeft = _e[0], expectTop = _e[1];
  221. // 反方向
  222. var inversion = {
  223. left: 'right',
  224. right: 'left',
  225. top: 'bottom',
  226. bottom: 'top',
  227. };
  228. // 各个边界是否超出容器边界
  229. var boundingX = bounding.x, boundingY = bounding.y, boundingWidth = bounding.width, boundingHeight = bounding.height;
  230. var edgeCompare = {
  231. left: expectLeft < boundingX,
  232. right: expectLeft + offsetWidth > boundingX + boundingWidth,
  233. top: expectTop < boundingY,
  234. bottom: expectTop + offsetHeight > boundingY + boundingHeight,
  235. };
  236. // 修正的位置
  237. var correctivePosition = [];
  238. // 判断是否超出边界
  239. position.split('-').forEach(function (pos) {
  240. // 如果在当前方向超出边界,则设置其反方向
  241. if (edgeCompare[pos])
  242. correctivePosition.push(inversion[pos]);
  243. else
  244. correctivePosition.push(pos);
  245. });
  246. var correctedPositionString = correctivePosition.join('-');
  247. return this.getRelativeOffsetFromCursor(correctedPositionString);
  248. };
  249. Tooltip.tag = 'tooltip';
  250. tslib_1.__decorate([
  251. (0, util_2.throttle)(100, true)
  252. ], Tooltip.prototype, "updatePosition", null);
  253. return Tooltip;
  254. }(core_1.GUI));
  255. exports.Tooltip = Tooltip;
  256. //# sourceMappingURL=index.js.map