tooltip.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. "use strict";
  2. var Util = require('../util/common');
  3. var Marker = require('./marker');
  4. var Container = require('./list');
  5. var TextBox = require('./text-box');
  6. var GAP = 4;
  7. /**
  8. * TODOList:
  9. * 1. 移除 fixed 参数
  10. */
  11. var Tooltip = /*#__PURE__*/function () {
  12. var _proto = Tooltip.prototype;
  13. _proto.getDefaultCfg = function getDefaultCfg() {
  14. return {
  15. /**
  16. * wether show the crosshairs
  17. * @type {Object}
  18. */
  19. showCrosshairs: false,
  20. /**
  21. * the style for crosshairs
  22. * @type {Object}
  23. */
  24. crosshairsStyle: {
  25. stroke: 'rgba(0, 0, 0, 0.25)',
  26. lineWidth: 1
  27. },
  28. /**
  29. * the type of crosshairs, optional value is 'x', 'y' or 'xy', default is 'y'
  30. */
  31. crosshairsType: 'y',
  32. /**
  33. * show or hide the x axis tip
  34. */
  35. showXTip: false,
  36. /**
  37. * show or hide the y axis tip
  38. */
  39. showYTip: false,
  40. xTip: null,
  41. xTipBackground: {
  42. radius: 1,
  43. fill: 'rgba(0, 0, 0, 0.65)',
  44. padding: [3, 5]
  45. },
  46. yTip: null,
  47. yTipBackground: {
  48. radius: 1,
  49. fill: 'rgba(0, 0, 0, 0.65)',
  50. padding: [3, 5]
  51. },
  52. /**
  53. * the style for tooltip container's background
  54. * @type {Object}
  55. */
  56. background: null,
  57. /**
  58. * layout, can be horizontal or vertical
  59. * @type {String}
  60. */
  61. layout: 'horizontal',
  62. offsetX: 0,
  63. offsetY: 0
  64. };
  65. };
  66. function Tooltip(cfg) {
  67. Util.deepMix(this, this.getDefaultCfg(), cfg);
  68. var frontPlot = this.frontPlot,
  69. custom = this.custom;
  70. if (!custom) {
  71. // custom means user do customize
  72. var container = new Container(Util.mix({
  73. parent: frontPlot,
  74. zIndex: 3
  75. }, cfg));
  76. this.container = container;
  77. var fixed = this.fixed,
  78. background = this.background;
  79. if (!fixed) {
  80. this.tooltipArrow = frontPlot.addShape('Polygon', {
  81. className: 'tooltip-arrow',
  82. visible: false,
  83. zIndex: 2,
  84. attrs: Util.mix({
  85. points: []
  86. }, background)
  87. });
  88. }
  89. }
  90. if (this.showXTip) {
  91. var xTipBackground = this.xTipBackground;
  92. var xTipBox = new TextBox({
  93. className: 'xTip',
  94. background: xTipBackground,
  95. visible: false
  96. });
  97. frontPlot.add(xTipBox.container);
  98. this.xTipBox = xTipBox;
  99. }
  100. if (this.showYTip) {
  101. var yTipBackground = this.yTipBackground;
  102. var yTipBox = new TextBox({
  103. className: 'yTip',
  104. background: yTipBackground,
  105. visible: false
  106. });
  107. frontPlot.add(yTipBox.container);
  108. this.yTipBox = yTipBox;
  109. }
  110. if (this.showCrosshairs) {
  111. this._renderCrosshairs();
  112. }
  113. frontPlot.sort();
  114. }
  115. _proto.setContent = function setContent(title, items) {
  116. this.title = title;
  117. this.items = items;
  118. if (!this.custom) {
  119. var container = this.container;
  120. container.setTitle(title);
  121. container.setItems(items);
  122. }
  123. };
  124. _proto.setYTipContent = function setYTipContent(val) {
  125. var yTip = this.yTip;
  126. if (Util.isFunction(yTip)) {
  127. val = yTip(val);
  128. } else {
  129. val = Util.mix({
  130. text: val
  131. }, yTip);
  132. }
  133. this.yTipBox && this.yTipBox.updateContent(val);
  134. };
  135. _proto.setYTipPosition = function setYTipPosition(pos) {
  136. var plotRange = this.plotRange;
  137. var crosshairsShapeX = this.crosshairsShapeX;
  138. if (this.showYTip) {
  139. var yTipBox = this.yTipBox;
  140. var yTipHeight = yTipBox.getHeight();
  141. var yTipWidth = yTipBox.getWidth();
  142. var posX = plotRange.tl.x - yTipWidth;
  143. var posY = pos - yTipHeight / 2;
  144. if (posY <= plotRange.tl.y) {
  145. posY = plotRange.tl.y;
  146. }
  147. if (posY + yTipHeight >= plotRange.br.y) {
  148. posY = plotRange.br.y - yTipHeight;
  149. }
  150. if (posX < 0) {
  151. posX = plotRange.tl.x;
  152. crosshairsShapeX && crosshairsShapeX.attr('x1', plotRange.tl.x + yTipWidth);
  153. }
  154. yTipBox.updatePosition(posX, posY);
  155. }
  156. };
  157. _proto.setXTipContent = function setXTipContent(val) {
  158. var xTip = this.xTip;
  159. if (Util.isFunction(xTip)) {
  160. val = xTip(val);
  161. } else {
  162. val = Util.mix({
  163. text: val
  164. }, xTip);
  165. }
  166. this.xTipBox && this.xTipBox.updateContent(val);
  167. };
  168. _proto.setXTipPosition = function setXTipPosition(pos) {
  169. var showXTip = this.showXTip,
  170. canvas = this.canvas,
  171. plotRange = this.plotRange,
  172. xTipBox = this.xTipBox,
  173. crosshairsShapeY = this.crosshairsShapeY;
  174. if (showXTip) {
  175. // const el = canvas.get('el');
  176. // const canvasHeight = Util.getHeight(el);
  177. var canvasHeight = canvas.get('height');
  178. var xTipWidth = xTipBox.getWidth();
  179. var xTipHeight = xTipBox.getHeight();
  180. var posX = pos - xTipWidth / 2;
  181. var posY = plotRange.br.y;
  182. if (posX <= plotRange.tl.x) {
  183. posX = plotRange.tl.x;
  184. }
  185. if (posX + xTipWidth >= plotRange.tr.x) {
  186. posX = plotRange.tr.x - xTipWidth;
  187. }
  188. if (canvasHeight - posY < xTipHeight) {
  189. posY -= xTipHeight;
  190. }
  191. xTipBox.updatePosition(posX, posY);
  192. crosshairsShapeY && crosshairsShapeY.attr('y1', posY);
  193. }
  194. };
  195. _proto.setXCrosshairPosition = function setXCrosshairPosition(pos) {
  196. this.crosshairsShapeX && this.crosshairsShapeX.moveTo(0, pos);
  197. };
  198. _proto.setYCrosshairPosition = function setYCrosshairPosition(pos) {
  199. this.crosshairsShapeY && this.crosshairsShapeY.moveTo(pos, 0);
  200. };
  201. _proto.setPosition = function setPosition(items) {
  202. var container = this.container,
  203. plotRange = this.plotRange,
  204. offsetX = this.offsetX,
  205. offsetY = this.offsetY,
  206. fixed = this.fixed,
  207. tooltipArrow = this.tooltipArrow;
  208. if (!container) {
  209. return;
  210. }
  211. var containerBBox = container.container.getBBox();
  212. var minX = containerBBox.minX,
  213. minY = containerBBox.minY,
  214. width = containerBBox.width,
  215. height = containerBBox.height;
  216. var tl = plotRange.tl,
  217. tr = plotRange.tr;
  218. var posX = 0;
  219. var posY = tl.y - height - GAP + offsetY;
  220. if (fixed) {
  221. var x = (tl.x + tr.x) / 2;
  222. posX = x - width / 2 + offsetX;
  223. } else {
  224. var _x;
  225. if (items.length > 1) {
  226. _x = (items[0].x + items[items.length - 1].x) / 2;
  227. } else {
  228. _x = items[0].x;
  229. }
  230. posX = _x - width / 2 + offsetX;
  231. if (posX < tl.x) {
  232. posX = tl.x;
  233. }
  234. if (posX + width > tr.x) {
  235. posX = tr.x - width;
  236. }
  237. if (tooltipArrow) {
  238. tooltipArrow.attr('points', [{
  239. x: _x - 3,
  240. y: tl.y - GAP + offsetY
  241. }, {
  242. x: _x + 3,
  243. y: tl.y - GAP + offsetY
  244. }, {
  245. x: _x,
  246. y: tl.y + offsetY
  247. }]);
  248. var backShape = container.backShape;
  249. var radius = Util.parsePadding(backShape.attr('radius'));
  250. if (_x === tl.x) {
  251. radius[3] = 0;
  252. tooltipArrow.attr('points', [{
  253. x: tl.x,
  254. y: tl.y + offsetY
  255. }, {
  256. x: tl.x,
  257. y: tl.y - GAP + offsetY
  258. }, {
  259. x: tl.x + GAP,
  260. y: tl.y - GAP + offsetY
  261. }]);
  262. } else if (_x === tr.x) {
  263. radius[2] = 0;
  264. tooltipArrow.attr('points', [{
  265. x: tr.x,
  266. y: tl.y + offsetY
  267. }, {
  268. x: tr.x - GAP,
  269. y: tl.y - GAP + offsetY
  270. }, {
  271. x: tr.x,
  272. y: tl.y - GAP + offsetY
  273. }]);
  274. }
  275. backShape.attr('radius', radius);
  276. }
  277. }
  278. container.moveTo(posX - minX, posY - minY);
  279. };
  280. _proto.setMarkers = function setMarkers(cfg) {
  281. if (cfg === void 0) {
  282. cfg = {};
  283. }
  284. var self = this;
  285. var _cfg = cfg,
  286. items = _cfg.items,
  287. style = _cfg.style,
  288. type = _cfg.type;
  289. var markerGroup = self._getMarkerGroup(type);
  290. if (type === 'circle') {
  291. for (var i = 0, length = items.length; i < length; i++) {
  292. var item = items[i];
  293. var marker = new Marker({
  294. className: 'tooltip-circle-marker',
  295. attrs: Util.mix({
  296. x: item.x,
  297. y: item.y,
  298. stroke: item.color
  299. }, style)
  300. });
  301. markerGroup.add(marker);
  302. }
  303. } else {
  304. markerGroup.addShape('rect', {
  305. className: 'tooltip-rect-marker',
  306. attrs: style
  307. });
  308. }
  309. };
  310. _proto.clearMarkers = function clearMarkers() {
  311. var markerGroup = this.markerGroup;
  312. markerGroup && markerGroup.clear();
  313. };
  314. _proto.show = function show() {
  315. var crosshairsShapeX = this.crosshairsShapeX;
  316. var crosshairsShapeY = this.crosshairsShapeY;
  317. var markerGroup = this.markerGroup;
  318. var container = this.container;
  319. var tooltipArrow = this.tooltipArrow;
  320. var xTipBox = this.xTipBox;
  321. var yTipBox = this.yTipBox;
  322. var canvas = this.canvas;
  323. crosshairsShapeX && crosshairsShapeX.show();
  324. crosshairsShapeY && crosshairsShapeY.show();
  325. markerGroup && markerGroup.show();
  326. container && container.show();
  327. tooltipArrow && tooltipArrow.show();
  328. xTipBox && xTipBox.show();
  329. yTipBox && yTipBox.show();
  330. canvas.draw();
  331. };
  332. _proto.hide = function hide() {
  333. var crosshairsShapeX = this.crosshairsShapeX;
  334. var crosshairsShapeY = this.crosshairsShapeY;
  335. var markerGroup = this.markerGroup;
  336. var container = this.container;
  337. var tooltipArrow = this.tooltipArrow;
  338. var xTipBox = this.xTipBox;
  339. var yTipBox = this.yTipBox;
  340. crosshairsShapeX && crosshairsShapeX.hide();
  341. crosshairsShapeY && crosshairsShapeY.hide();
  342. markerGroup && markerGroup.hide();
  343. container && container.hide();
  344. tooltipArrow && tooltipArrow.hide();
  345. xTipBox && xTipBox.hide();
  346. yTipBox && yTipBox.hide();
  347. };
  348. _proto.destroy = function destroy() {
  349. var crosshairsShapeX = this.crosshairsShapeX;
  350. var crosshairsShapeY = this.crosshairsShapeY;
  351. var markerGroup = this.markerGroup;
  352. var container = this.container;
  353. var tooltipArrow = this.tooltipArrow;
  354. var xTipBox = this.xTipBox;
  355. var yTipBox = this.yTipBox;
  356. crosshairsShapeX && crosshairsShapeX.remove(true);
  357. crosshairsShapeY && crosshairsShapeY.remove(true);
  358. markerGroup && markerGroup.remove(true);
  359. tooltipArrow && tooltipArrow.remove(true);
  360. container && container.clear();
  361. xTipBox && xTipBox.clear();
  362. yTipBox && yTipBox.clear();
  363. this.destroyed = true;
  364. };
  365. _proto._getMarkerGroup = function _getMarkerGroup(type) {
  366. var markerGroup = this.markerGroup;
  367. if (!markerGroup) {
  368. if (type === 'circle') {
  369. markerGroup = this.frontPlot.addGroup({
  370. zIndex: 1
  371. });
  372. this.frontPlot.sort();
  373. } else {
  374. markerGroup = this.backPlot.addGroup();
  375. }
  376. this.markerGroup = markerGroup;
  377. } else {
  378. markerGroup.clear();
  379. }
  380. return markerGroup;
  381. };
  382. _proto._renderCrosshairs = function _renderCrosshairs() {
  383. var crosshairsType = this.crosshairsType,
  384. crosshairsStyle = this.crosshairsStyle,
  385. frontPlot = this.frontPlot,
  386. plotRange = this.plotRange;
  387. var tl = plotRange.tl,
  388. br = plotRange.br;
  389. if (Util.directionEnabled(crosshairsType, 'x')) {
  390. this.crosshairsShapeX = frontPlot.addShape('Line', {
  391. className: 'tooltip-crosshairs-x',
  392. zIndex: 0,
  393. visible: false,
  394. attrs: Util.mix({
  395. x1: tl.x,
  396. y1: 0,
  397. x2: br.x,
  398. y2: 0
  399. }, crosshairsStyle)
  400. });
  401. }
  402. if (Util.directionEnabled(crosshairsType, 'y')) {
  403. this.crosshairsShapeY = frontPlot.addShape('Line', {
  404. className: 'tooltip-crosshairs-y',
  405. zIndex: 0,
  406. visible: false,
  407. attrs: Util.mix({
  408. x1: 0,
  409. y1: br.y,
  410. x2: 0,
  411. y2: tl.y
  412. }, crosshairsStyle)
  413. });
  414. }
  415. };
  416. return Tooltip;
  417. }();
  418. module.exports = Tooltip;