UNPKG

@alicloud/cloud-charts

Version:

![](https://img.shields.io/npm/v/@alicloud/cloud-charts?color=%23ff8200)

332 lines (311 loc) 17.3 kB
import _inheritsLoose from "@babel/runtime/helpers/inheritsLoose"; function _createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } import RawTooltipController from '@antv/g2/esm/chart/controller/tooltip'; import ReactDOM from 'react-dom'; import { FullCrossName, HideTooltipEventName } from '../../constants'; import FreeTooltip from '../component/FreeTooltip'; import { PrefixName } from '../../constants'; import React from 'react'; import { getRawData, customFormatter } from '../../common/common'; import "../component/FreeTooltip/index.css"; // @ts-ignore var WidgetsTooltipController = /*#__PURE__*/function (_RawTooltipController) { _inheritsLoose(WidgetsTooltipController, _RawTooltipController); function WidgetsTooltipController(props) { var _this; _this = _RawTooltipController.call(this, props) || this; _this.parentDom = void 0; _this.tooltipContainer = void 0; // 锁定tooltip时,图表容器的位置信息 _this.startRect = void 0; // 锁定tooltip时,tooltip的起始位置 _this.startPosition = void 0; // 计时器,用于防抖 _this.timer = void 0; // 监听器,用于监听图表是否可见 _this.observer = void 0; // 锁定tooltip时监听滚动事件 _this.handleScroll = function () { if (_this.timer) { clearTimeout(_this.timer); _this.timer = null; } _this.timer = setTimeout(function () { // 图表父元素的当前位置 var currentRect = _this.parentDom.getBoundingClientRect(); var offsetX = currentRect.x - _this.startRect.x; var offsetY = currentRect.y - _this.startRect.y; // this.tooltipContainer.style.left = `${this.startPosition.x + offsetX}px`; // this.tooltipContainer.style.top = `${this.startPosition.y + offsetY}px`; _this.tooltipContainer.style.transform = "translate3d(" + (_this.startPosition.x + offsetX) + "px, " + (_this.startPosition.y + offsetY) + "px, 0px)"; clearTimeout(_this.timer); _this.timer = null; }, 50); }; _this.parentDom = _this.view.getCanvas().get('el').parentNode.parentNode.parentNode; return _this; } var _proto = WidgetsTooltipController.prototype; _proto.showTooltip = function showTooltip(point) { var _items, _this2 = this; var cfg = this.getTooltipCfg(); var items = this.getTooltipItems(point); if (cfg !== null && cfg !== void 0 && cfg.customItems) { items = cfg.customItems(items); } if (!((_items = items) !== null && _items !== void 0 && _items.length)) { return; } // 自定义tooltip if (cfg !== null && cfg !== void 0 && cfg.customTooltip) { var _widgetsCtx$mergeConf, _this$view, _this$view$widgetsCtx, _config$tooltip, _config$tooltip2, _config$tooltip3, _config$tooltip4, _items2; // 创建容器 if (!this.tooltipContainer) { var container = document.createElement('div'); container.className = FullCrossName + " widgets-tooltip"; container.style.cssText = "position: fixed;z-index: 1001; pointer-events: none; top: 0; left: 0;"; document.body.append(container); this.tooltipContainer = container; } this.tooltipContainer.style.visibility = 'visible'; // 图表离开视窗时隐藏tooltip this.observer = new IntersectionObserver(function (entries) { for (var _iterator = _createForOfIteratorHelperLoose(entries), _step; !(_step = _iterator()).done;) { var entry = _step.value; // 元素离开视口 if (!entry.isIntersecting) { _this2.unlockTooltip(); _this2.hideTooltip(); } } }); this.observer.observe(this.parentDom); // 通过事件手动隐藏tooltip window.addEventListener(HideTooltipEventName, function () { _this2.unlockTooltip(); _this2.hideTooltip(); }); // 绘制 var title = ''; if (cfg !== null && cfg !== void 0 && cfg.showTitle) { try { // @ts-ignore title = this.getTitle(items); } catch (e) {} } // 配置项处理 var config = (_widgetsCtx$mergeConf = this === null || this === void 0 ? void 0 : (_this$view = this.view) === null || _this$view === void 0 ? void 0 : (_this$view$widgetsCtx = _this$view.widgetsCtx) === null || _this$view$widgetsCtx === void 0 ? void 0 : _this$view$widgetsCtx.mergeConfig) !== null && _widgetsCtx$mergeConf !== void 0 ? _widgetsCtx$mergeConf : {}; // 进位相关配置项 var formatConfig; // 当tooltip中配置了单位相关信息时,直接使用tooltip的配置项,否则使用y轴配置项 if (typeof (config === null || config === void 0 ? void 0 : config.tooltip) === 'object' && (config !== null && config !== void 0 && (_config$tooltip = config.tooltip) !== null && _config$tooltip !== void 0 && _config$tooltip.valueType || config !== null && config !== void 0 && (_config$tooltip2 = config.tooltip) !== null && _config$tooltip2 !== void 0 && _config$tooltip2.unit || config !== null && config !== void 0 && (_config$tooltip3 = config.tooltip) !== null && _config$tooltip3 !== void 0 && _config$tooltip3.needUnitTransform || config !== null && config !== void 0 && (_config$tooltip4 = config.tooltip) !== null && _config$tooltip4 !== void 0 && _config$tooltip4.unitTransformTo)) { formatConfig = config.tooltip; } else if (Array.isArray(config.yAxis) && config.yAxis.length >= 2) { // 双轴 formatConfig = config.yAxis; } else if (Array.isArray(config.yAxis)) { var _config$yAxis$, _config$yAxis; formatConfig = (_config$yAxis$ = config === null || config === void 0 ? void 0 : (_config$yAxis = config.yAxis) === null || _config$yAxis === void 0 ? void 0 : _config$yAxis[0]) !== null && _config$yAxis$ !== void 0 ? _config$yAxis$ : {}; } else { var _config$yAxis2; formatConfig = (_config$yAxis2 = config === null || config === void 0 ? void 0 : config.yAxis) !== null && _config$yAxis2 !== void 0 ? _config$yAxis2 : {}; } // const customValueFormatter = customFormatter(formatConfig); items.forEach(function (item, index) { var _this2$view, _this2$view$widgetsCt, _config$tooltip5, _config$tooltip7; // @ts-ignore var raw = getRawData(config, _this2 === null || _this2 === void 0 ? void 0 : (_this2$view = _this2.view) === null || _this2$view === void 0 ? void 0 : (_this2$view$widgetsCt = _this2$view.widgetsCtx) === null || _this2$view$widgetsCt === void 0 ? void 0 : _this2$view$widgetsCt.rawData, item); if (config !== null && config !== void 0 && (_config$tooltip5 = config.tooltip) !== null && _config$tooltip5 !== void 0 && _config$tooltip5.valueFormatter) { var _config$tooltip6; item.value = config === null || config === void 0 ? void 0 : (_config$tooltip6 = config.tooltip) === null || _config$tooltip6 === void 0 ? void 0 : _config$tooltip6.valueFormatter(item.value, raw, index, items); } else { var customValueFormatter = null; if (Array.isArray(formatConfig)) { // 双轴 customValueFormatter = 'y1' in (item === null || item === void 0 ? void 0 : item.data) ? customFormatter(formatConfig[1]) : customFormatter(formatConfig[0]); } else { // 单轴 customValueFormatter = customFormatter(formatConfig); } if (customValueFormatter) { item.value = customValueFormatter(item.value); } } if (item.name.startsWith('undefined-name-')) { item.name = ''; } else if (config !== null && config !== void 0 && (_config$tooltip7 = config.tooltip) !== null && _config$tooltip7 !== void 0 && _config$tooltip7.nameFormatter) { var _config$tooltip8; item.name = config === null || config === void 0 ? void 0 : (_config$tooltip8 = config.tooltip) === null || _config$tooltip8 === void 0 ? void 0 : _config$tooltip8.nameFormatter(item.name, raw, index, items); } }); var element = cfg.customTooltip === true ? /*#__PURE__*/React.createElement(FreeTooltip, { title: title, data: items }) : cfg.customTooltip(title, items); ReactDOM.render(element, this.tooltipContainer); // 计算位置和尺寸 var padding = 10; var position = { x: point.x + padding, y: point.y }; var parentRect = this.parentDom.getBoundingClientRect(); var bodyWidth = document.body.clientWidth; var bodyHeight = document.body.clientHeight; position.x += parentRect.left; position.y += parentRect.top; var tooltipRect = this.tooltipContainer.getBoundingClientRect(); // 宽度超过屏幕时 if (position.x + tooltipRect.width > bodyWidth) { // 判断左边和右边哪边区域更大就放哪边 var leftWidth = position.x - padding; var rightWidth = bodyWidth - position.x - padding; if (leftWidth > rightWidth) { // 移至左侧 position.x = Math.max(position.x - tooltipRect.width - padding, 0); } } // 高度超过屏幕时 if (position.y + tooltipRect.height > bodyHeight) { // 判断上边和下边哪边区域更大就放哪边 var topHeight = position.y - padding; var bottomHeight = bodyHeight - position.y - padding; if (topHeight > bottomHeight) { // 移至上方 position.y = Math.max(position.y - tooltipRect.height - padding, 0); } } // 定位 // @ts-ignore this.tooltipContainer.style.transform = "translate3d(" + position.x + "px, " + position.y + "px, 0px)"; if (cfg !== null && cfg !== void 0 && cfg.showMarkers) { // @ts-ignore this.renderTooltipMarkers(items, cfg.marker); } // 显示辅助线 if (cfg !== null && cfg !== void 0 && cfg.showCrosshairs && (_items2 = items) !== null && _items2 !== void 0 && _items2.length) { var _items$, _items$2, _cfg$crosshairs; var dataPoint = { x: (_items$ = items[0]) === null || _items$ === void 0 ? void 0 : _items$.x, y: (_items$2 = items[0]) === null || _items$2 === void 0 ? void 0 : _items$2.y }; // 数据点位置 var isCrosshairsFollowCursor = (cfg === null || cfg === void 0 ? void 0 : (_cfg$crosshairs = cfg.crosshairs) === null || _cfg$crosshairs === void 0 ? void 0 : _cfg$crosshairs.follow) || false; // @ts-ignore _RawTooltipController.prototype.renderCrosshairs.call(this, isCrosshairsFollowCursor ? point : dataPoint, cfg); } } else { _RawTooltipController.prototype.showTooltip.call(this, point); } // 开启锁定时绘制锁定icon if (cfg !== null && cfg !== void 0 && cfg.lockable) { this.drawLockElement(false); } }; _proto.hideTooltip = function hideTooltip() { var cfg = this.getTooltipCfg(); if (cfg !== null && cfg !== void 0 && cfg.customTooltip) { if (this.tooltipContainer) { this.tooltipContainer.style.visibility = 'hidden'; } // @ts-ignore hide the tooltipMarkers var tooltipMarkersGroup = this.tooltipMarkersGroup; if (tooltipMarkersGroup) { tooltipMarkersGroup.hide(); } // hide crosshairs // @ts-ignore var xCrosshair = this.xCrosshair, yCrosshair = this.yCrosshair; if (xCrosshair) { xCrosshair.hide(); } if (yCrosshair) { yCrosshair.hide(); } } else { _RawTooltipController.prototype.hideTooltip.call(this); } }; _proto.destroy = function destroy() { var cfg = this.getTooltipCfg(); if (cfg !== null && cfg !== void 0 && cfg.customTooltip) { if (this.tooltipContainer) { document.body.removeChild(this.tooltipContainer); this.tooltipContainer = null; } // clear crosshairs // @ts-ignore var xCrosshair = this.xCrosshair, yCrosshair = this.yCrosshair; if (xCrosshair) { xCrosshair.clear(); } if (yCrosshair) { yCrosshair.clear(); } } else { _RawTooltipController.prototype.destroy.call(this); } }; _proto.lockTooltip = function lockTooltip() { _RawTooltipController.prototype.lockTooltip.call(this); if (this.tooltipContainer) { this.tooltipContainer.style.pointerEvents = 'auto'; } this.drawLockElement(true); }; _proto.unlockTooltip = function unlockTooltip() { var _this3 = this; _RawTooltipController.prototype.unlockTooltip.call(this); if (this.tooltipContainer) { this.tooltipContainer.style.pointerEvents = 'none'; this.observer.disconnect(); window.removeEventListener(HideTooltipEventName, function () { _this3.unlockTooltip(); _this3.hideTooltip(); }); } this.drawLockElement(false); } // 绘制锁定相关元素 ; _proto.drawLockElement = function drawLockElement(locked) { var curTooltipContainer = this.tooltipContainer || this.parentDom.querySelector('.g2-tooltip'); if (!curTooltipContainer) { return; } var lockIcon = /*#__PURE__*/React.createElement("svg", { viewBox: "0 0 1024 1024", width: "12", height: "12" }, /*#__PURE__*/React.createElement("path", { d: "M921.6 391.68l-288-288c-5.12-5.12-11.52-7.68-17.92-7.68s-13.44 2.56-17.92 7.68L497.28 203.52c-5.12 4.48-7.68 11.52-7.68 17.92s2.56 13.44 7.68 17.92l51.84 51.84-241.28 104.32c-3.2 1.28-5.76 3.2-7.68 5.12L202.88 497.92c-10.24 10.24-10.24 26.24 0 36.48l85.76 85.76-185.6 257.92c-8.96 12.8-7.68 30.08 3.2 40.96 6.4 6.4 14.72 9.6 23.04 9.6 6.4 0 12.8-1.92 18.56-5.76l262.4-181.76 81.28 81.28c10.24 10.24 26.24 10.24 36.48 0l96.64-96.64c1.92-1.92 3.84-4.48 5.12-7.68L737.28 480l48 48c5.12 5.12 11.52 7.68 17.92 7.68s13.44-2.56 17.92-7.68L921.6 427.52c5.12-5.12 7.68-11.52 7.68-17.92s-3.2-13.44-7.68-17.92z" })); var unlockIcon = /*#__PURE__*/React.createElement("svg", { viewBox: "0 0 1024 1024", width: "12", height: "12" }, /*#__PURE__*/React.createElement("path", { d: "M920.32 391.68l-288-288c-4.48-5.12-10.88-7.68-17.92-7.68s-13.44 2.56-17.92 7.68L496 203.52c-5.12 5.12-7.68 11.52-7.68 17.92s2.56 13.44 7.68 17.92l51.84 51.84-241.28 104.32c-3.2 1.28-5.76 3.2-7.68 5.12L202.24 497.92c-10.24 10.24-10.24 26.24 0 36.48L288 620.16l-185.6 257.92c-8.96 12.8-7.68 30.08 3.2 40.96 6.4 6.4 14.72 9.6 23.04 9.6 6.4 0 12.8-1.92 18.56-5.76l262.4-181.76 81.28 81.28c10.24 10.24 26.24 10.24 36.48 0l96.64-96.64c1.92-1.92 3.84-4.48 5.12-7.68L736 480l48 48c5.12 5.12 11.52 7.68 17.92 7.68s13.44-2.56 17.92-7.68l100.48-100.48c5.12-5.12 7.68-11.52 7.68-17.92s-2.56-13.44-7.68-17.92z m-117.12 63.36l-51.84-51.84c-5.76-5.76-13.44-7.68-21.12-6.4-7.68 1.28-14.08 6.4-17.28 13.44l-135.04 270.08L508.8 748.8l-72.96-72.96c-8.32-8.32-21.12-9.6-30.72-2.56l-239.36 183.68 188.16-234.24c7.04-9.6 5.76-22.4-2.56-30.72l-76.8-76.8 68.48-68.48 273.92-131.2c7.04-3.2 12.16-9.6 14.08-17.28 1.28-7.68-1.28-16-6.4-21.12l-55.68-55.68 45.44-45.44L848 409.6l-44.8 45.44z" })); var lockElement = /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", { className: PrefixName + "-free-tooltip-lock-icon-background" }), /*#__PURE__*/React.createElement("div", { className: PrefixName + "-free-tooltip-lock-icon-container" }, locked ? lockIcon : unlockIcon)); var lockContainer = curTooltipContainer === null || curTooltipContainer === void 0 ? void 0 : curTooltipContainer.querySelector("." + PrefixName + "-free-tooltip-lock-container"); if (lockContainer) { ReactDOM.render(lockElement, lockContainer); } else { lockContainer = document.createElement('div'); lockContainer.className = PrefixName + "-free-tooltip-lock-container"; ReactDOM.render(lockElement, lockContainer); curTooltipContainer.appendChild(lockContainer); } }; return WidgetsTooltipController; }(RawTooltipController); export default WidgetsTooltipController;