html.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. var tslib_1 = require("tslib");
  4. var color_util_1 = require("@antv/color-util");
  5. var dom_util_1 = require("@antv/dom-util");
  6. var util_1 = require("@antv/util");
  7. var html_component_1 = require("../abstract/html-component");
  8. var util_2 = require("../util/util");
  9. var CssConst = require("./css-const");
  10. var html_theme_1 = require("./html-theme");
  11. var align_1 = require("../util/align");
  12. function hasOneKey(obj, keys) {
  13. var result = false;
  14. util_1.each(keys, function (key) {
  15. if (util_1.hasKey(obj, key)) {
  16. result = true;
  17. return false;
  18. }
  19. });
  20. return result;
  21. }
  22. var Tooltip = /** @class */ (function (_super) {
  23. tslib_1.__extends(Tooltip, _super);
  24. function Tooltip() {
  25. return _super !== null && _super.apply(this, arguments) || this;
  26. }
  27. Tooltip.prototype.getDefaultCfg = function () {
  28. var cfg = _super.prototype.getDefaultCfg.call(this);
  29. return tslib_1.__assign(tslib_1.__assign({}, cfg), { name: 'tooltip', type: 'html', x: 0, y: 0, items: [], customContent: null, containerTpl: "<div class=\"" + CssConst.CONTAINER_CLASS + "\"><div class=\"" + CssConst.TITLE_CLASS + "\"></div><ul class=\"" + CssConst.LIST_CLASS + "\"></ul></div>", itemTpl: "<li class=\"" + CssConst.LIST_ITEM_CLASS + "\" data-index={index}>\n <span class=\"" + CssConst.MARKER_CLASS + "\" style=\"background:{color}\"></span>\n <span class=\"" + CssConst.NAME_CLASS + "\">{name}</span>:\n <span class=\"" + CssConst.VALUE_CLASS + "\">{value}</span>\n </li>", xCrosshairTpl: "<div class=\"" + CssConst.CROSSHAIR_X + "\"></div>", yCrosshairTpl: "<div class=\"" + CssConst.CROSSHAIR_Y + "\"></div>", title: null, showTitle: true,
  30. /**
  31. * tooltip 限制的区域
  32. * @type {Region}
  33. */
  34. region: null,
  35. // crosshair 的限制区域
  36. crosshairsRegion: null, containerClassName: CssConst.CONTAINER_CLASS,
  37. // x, y, xy
  38. crosshairs: null, offset: 10, position: 'right', domStyles: null, defaultStyles: html_theme_1.default });
  39. };
  40. // tooltip 渲染时,渲染 title,items 和 corosshairs
  41. Tooltip.prototype.render = function () {
  42. if (this.get('customContent')) {
  43. this.renderCustomContent();
  44. }
  45. else {
  46. this.resetTitle();
  47. this.renderItems();
  48. }
  49. // 绘制完成后,再定位
  50. this.resetPosition();
  51. };
  52. // 复写清空函数,因为有模板的存在,所以默认的写法不合适
  53. Tooltip.prototype.clear = function () {
  54. // 由于 crosshair 没有在 container 内,所以需要单独清理
  55. this.clearCrosshairs();
  56. this.setTitle(''); // 清空标题
  57. this.clearItemDoms();
  58. };
  59. Tooltip.prototype.show = function () {
  60. var container = this.getContainer();
  61. if (!container || this.destroyed) {
  62. // 防止容器不存在或者被销毁时报错
  63. return;
  64. }
  65. this.set('visible', true);
  66. dom_util_1.modifyCSS(container, {
  67. visibility: 'visible',
  68. });
  69. this.setCrossHairsVisible(true);
  70. };
  71. Tooltip.prototype.hide = function () {
  72. var container = this.getContainer();
  73. // relative: https://github.com/antvis/g2/issues/1221
  74. if (!container || this.destroyed) {
  75. return;
  76. }
  77. this.set('visible', false);
  78. dom_util_1.modifyCSS(container, {
  79. visibility: 'hidden',
  80. });
  81. this.setCrossHairsVisible(false);
  82. };
  83. // 实现 IPointLocation 的接口
  84. Tooltip.prototype.getLocation = function () {
  85. return { x: this.get('x'), y: this.get('y') };
  86. };
  87. // 实现 IPointLocation 的接口
  88. Tooltip.prototype.setLocation = function (point) {
  89. this.set('x', point.x);
  90. this.set('y', point.y);
  91. this.resetPosition();
  92. };
  93. Tooltip.prototype.setCrossHairsVisible = function (visible) {
  94. var display = visible ? '' : 'none';
  95. var xCrosshairDom = this.get('xCrosshairDom');
  96. var yCrosshairDom = this.get('yCrosshairDom');
  97. xCrosshairDom &&
  98. dom_util_1.modifyCSS(xCrosshairDom, {
  99. display: display,
  100. });
  101. yCrosshairDom &&
  102. dom_util_1.modifyCSS(yCrosshairDom, {
  103. display: display,
  104. });
  105. };
  106. // 如有 customContent 则根据 customContent 设置 container
  107. Tooltip.prototype.initContainer = function () {
  108. _super.prototype.initContainer.call(this);
  109. if (this.get('customContent')) {
  110. if (this.get('container')) {
  111. this.get('container').remove();
  112. }
  113. var container = this.getHtmlContentNode();
  114. this.get('parent').appendChild(container);
  115. this.set('container', container);
  116. this.resetStyles();
  117. this.applyStyles();
  118. }
  119. };
  120. // 更新属性的同时,可能会引起 DOM 的变化,这里对可能引起 DOM 变化的场景做了处理
  121. Tooltip.prototype.updateInner = function (cfg) {
  122. if (this.get('customContent')) {
  123. this.renderCustomContent();
  124. }
  125. else {
  126. // 更新标题
  127. if (hasOneKey(cfg, ['title', 'showTitle'])) {
  128. this.resetTitle();
  129. }
  130. // 更新内容
  131. if (util_1.hasKey(cfg, 'items')) {
  132. this.renderItems();
  133. }
  134. }
  135. _super.prototype.updateInner.call(this, cfg);
  136. };
  137. Tooltip.prototype.initDom = function () {
  138. this.cacheDoms();
  139. };
  140. // 清理 DOM
  141. Tooltip.prototype.removeDom = function () {
  142. _super.prototype.removeDom.call(this);
  143. this.clearCrosshairs();
  144. };
  145. // 调整位置
  146. Tooltip.prototype.resetPosition = function () {
  147. var x = this.get('x');
  148. var y = this.get('y');
  149. var offset = this.get('offset');
  150. var _a = this.getOffset(), offsetX = _a.offsetX, offsetY = _a.offsetY;
  151. var position = this.get('position');
  152. var region = this.get('region');
  153. var container = this.getContainer();
  154. var bbox = this.getBBox();
  155. var width = bbox.width, height = bbox.height;
  156. var limitBox;
  157. if (region) {
  158. // 不限制位置
  159. limitBox = util_2.regionToBBox(region);
  160. }
  161. var point = align_1.getAlignPoint(x, y, offset, width, height, position, limitBox);
  162. dom_util_1.modifyCSS(container, {
  163. left: util_2.toPx(point.x + offsetX),
  164. top: util_2.toPx(point.y + offsetY),
  165. });
  166. this.resetCrosshairs();
  167. };
  168. // 根据 customContent 渲染
  169. Tooltip.prototype.renderCustomContent = function () {
  170. var node = this.getHtmlContentNode();
  171. var parent = this.get('parent');
  172. var curContainer = this.get('container');
  173. if (curContainer && curContainer.parentNode === parent) {
  174. parent.replaceChild(node, curContainer);
  175. }
  176. else {
  177. parent.appendChild(node);
  178. }
  179. this.set('container', node);
  180. this.resetStyles();
  181. this.applyStyles();
  182. };
  183. Tooltip.prototype.getHtmlContentNode = function () {
  184. var node;
  185. var customContent = this.get('customContent');
  186. if (customContent) {
  187. var elem = customContent(this.get('title'), this.get('items'));
  188. if (util_1.isElement(elem)) {
  189. node = elem;
  190. }
  191. else {
  192. node = dom_util_1.createDom(elem);
  193. }
  194. }
  195. return node;
  196. };
  197. // 缓存模板设置的各种 DOM
  198. Tooltip.prototype.cacheDoms = function () {
  199. var container = this.getContainer();
  200. var titleDom = container.getElementsByClassName(CssConst.TITLE_CLASS)[0];
  201. var listDom = container.getElementsByClassName(CssConst.LIST_CLASS)[0];
  202. this.set('titleDom', titleDom);
  203. this.set('listDom', listDom);
  204. };
  205. // 重置 title
  206. Tooltip.prototype.resetTitle = function () {
  207. var title = this.get('title');
  208. var showTitle = this.get('showTitle');
  209. if (showTitle && title) {
  210. this.setTitle(title);
  211. }
  212. else {
  213. this.setTitle('');
  214. }
  215. };
  216. // 设置 title 文本
  217. Tooltip.prototype.setTitle = function (text) {
  218. var titleDom = this.get('titleDom');
  219. if (titleDom) {
  220. titleDom.innerText = text;
  221. }
  222. };
  223. // 终止 crosshair
  224. Tooltip.prototype.resetCrosshairs = function () {
  225. var crosshairsRegion = this.get('crosshairsRegion');
  226. var crosshairs = this.get('crosshairs');
  227. if (!crosshairsRegion || !crosshairs) {
  228. // 不显示 crosshair,都移除,没有设定 region 也都移除掉
  229. this.clearCrosshairs();
  230. }
  231. else {
  232. var crosshairBox = util_2.regionToBBox(crosshairsRegion);
  233. var xCrosshairDom = this.get('xCrosshairDom');
  234. var yCrosshairDom = this.get('yCrosshairDom');
  235. if (crosshairs === 'x') {
  236. this.resetCrosshair('x', crosshairBox);
  237. // 仅显示 x 的 crosshair,y 移除
  238. if (yCrosshairDom) {
  239. yCrosshairDom.remove();
  240. this.set('yCrosshairDom', null);
  241. }
  242. }
  243. else if (crosshairs === 'y') {
  244. this.resetCrosshair('y', crosshairBox);
  245. // 仅显示 y 的 crosshair,x 移除
  246. if (xCrosshairDom) {
  247. xCrosshairDom.remove();
  248. this.set('xCrosshairDom', null);
  249. }
  250. }
  251. else {
  252. this.resetCrosshair('x', crosshairBox);
  253. this.resetCrosshair('y', crosshairBox);
  254. }
  255. this.setCrossHairsVisible(this.get('visible'));
  256. }
  257. };
  258. // 设定 crosshair 的位置,需要区分 x,y
  259. Tooltip.prototype.resetCrosshair = function (name, bbox) {
  260. var croshairDom = this.checkCrosshair(name);
  261. var value = this.get(name);
  262. if (name === 'x') {
  263. dom_util_1.modifyCSS(croshairDom, {
  264. left: util_2.toPx(value),
  265. top: util_2.toPx(bbox.y),
  266. height: util_2.toPx(bbox.height),
  267. });
  268. }
  269. else {
  270. dom_util_1.modifyCSS(croshairDom, {
  271. top: util_2.toPx(value),
  272. left: util_2.toPx(bbox.x),
  273. width: util_2.toPx(bbox.width),
  274. });
  275. }
  276. };
  277. // 如果 crosshair 对应的 dom 不存在,则创建
  278. Tooltip.prototype.checkCrosshair = function (name) {
  279. var domName = name + "CrosshairDom";
  280. var tplName = name + "CrosshairTpl";
  281. var constName = "CROSSHAIR_" + name.toUpperCase();
  282. var styleName = CssConst[constName];
  283. var croshairDom = this.get(domName);
  284. var parent = this.get('parent');
  285. if (!croshairDom) {
  286. croshairDom = dom_util_1.createDom(this.get(tplName)); // 创建
  287. this.applyStyle(styleName, croshairDom); // 设置初始样式
  288. parent.appendChild(croshairDom); // 添加到跟 tooltip 同级的目录下
  289. this.set(domName, croshairDom);
  290. }
  291. return croshairDom;
  292. };
  293. Tooltip.prototype.renderItems = function () {
  294. this.clearItemDoms();
  295. var items = this.get('items');
  296. var itemTpl = this.get('itemTpl');
  297. var listDom = this.get('listDom');
  298. if (listDom) {
  299. util_1.each(items, function (item) {
  300. var color = color_util_1.default.toCSSGradient(item.color);
  301. var substituteObj = tslib_1.__assign(tslib_1.__assign({}, item), { color: color });
  302. var domStr = util_1.substitute(itemTpl, substituteObj);
  303. var itemDom = dom_util_1.createDom(domStr);
  304. listDom.appendChild(itemDom);
  305. });
  306. this.applyChildrenStyles(listDom, this.get('domStyles'));
  307. }
  308. };
  309. Tooltip.prototype.clearItemDoms = function () {
  310. if (this.get('listDom')) {
  311. util_2.clearDom(this.get('listDom'));
  312. }
  313. };
  314. Tooltip.prototype.clearCrosshairs = function () {
  315. var xCrosshairDom = this.get('xCrosshairDom');
  316. var yCrosshairDom = this.get('yCrosshairDom');
  317. xCrosshairDom && xCrosshairDom.remove();
  318. yCrosshairDom && yCrosshairDom.remove();
  319. this.set('xCrosshairDom', null);
  320. this.set('yCrosshairDom', null);
  321. };
  322. return Tooltip;
  323. }(html_component_1.default));
  324. exports.default = Tooltip;
  325. //# sourceMappingURL=html.js.map