public showTooltip()

in src/aop/controller/tooltip.tsx [35:208]


  public showTooltip(point: Point) {
    const cfg = this.getTooltipCfg();
    const items = this.getTooltipItems(point);

    if (!items?.length) {
      return;
    }

    // 自定义tooltip
    if (cfg?.customTooltip) {
      // 创建容器
      if (!this.tooltipContainer) {
        const 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((entries: any[]) => {
        for (const entry of entries) {
          // 元素离开视口
          if (!entry.isIntersecting) {
            this.unlockTooltip();
            this.hideTooltip();
          }
        }
      });

      this.observer.observe(this.parentDom);

      // 通过事件手动隐藏tooltip
      window.addEventListener(HideTooltipEventName, () => {
        this.unlockTooltip();
        this.hideTooltip();
      });

      // 绘制

      let title = '';
      if (cfg?.showTitle) {
        try {
          // @ts-ignore
          title = this.getTitle(items);
        } catch (e) {}
      }

      // 配置项处理
      const config = (this?.view as any)?.widgetsCtx?.mergeConfig ?? {};

      // 进位相关配置项
      let formatConfig: any;
      // 当tooltip中配置了单位相关信息时,直接使用tooltip的配置项,否则使用y轴配置项
      if (
        typeof config?.tooltip === 'object' &&
        (config?.tooltip?.valueType ||
          config?.tooltip?.unit ||
          config?.tooltip?.needUnitTransform ||
          config?.tooltip?.unitTransformTo)
      ) {
        formatConfig = config.tooltip;
      } else if (Array.isArray(config.yAxis) && config.yAxis.length >= 2) {
        // 双轴
        formatConfig = config.yAxis;
      } else if (Array.isArray(config.yAxis)) {
        formatConfig = config?.yAxis?.[0] ?? {};
      } else {
        formatConfig = config?.yAxis ?? {};
      }

      // const customValueFormatter = customFormatter(formatConfig);

      items.forEach((item: any, index: number) => {
        // @ts-ignore
        const raw = getRawData(config, this?.view?.widgetsCtx?.rawData, item);

        if (config?.tooltip?.valueFormatter) {
          item.value = config?.tooltip?.valueFormatter(item.value, raw, index, items);
        } else {
          let customValueFormatter = null;
          if (Array.isArray(formatConfig)) {
            // 双轴
            customValueFormatter =
              'y1' in 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?.tooltip?.nameFormatter) {
          item.name = config?.tooltip?.nameFormatter(item.name, raw, index, items);
        }
      });

      const element =
        cfg.customTooltip === true ? (
          <FreeTooltip title={title} data={items} />
        ) : (
          cfg.customTooltip(title, items)
        );
      ReactDOM.render(element, this.tooltipContainer);

      // 计算位置
      const padding = 10;
      const position = {
        x: point.x + padding,
        y: point.y,
      };
      const parentRect = this.parentDom.getBoundingClientRect();
      position.x += parentRect.left;
      position.y += parentRect.top;

      const tooltipRect = this.tooltipContainer.getBoundingClientRect();
      const bodyWidth = document.body.clientWidth;
      const bodyHeight = document.body.clientHeight;
      if (
        position.x + tooltipRect.width > bodyWidth &&
        position.x - tooltipRect.width - padding * 2 >= 0
      ) {
        // 超过屏幕时移至左边
        position.x = position.x - tooltipRect.width - padding * 2;
      }
      if (
        position.y + tooltipRect.height > bodyHeight &&
        position.y - tooltipRect.height - padding >= 0
      ) {
        // 超过屏幕时移至上方
        position.y = position.y - tooltipRect.height - padding;
      }

      // 定位
      // @ts-ignore
      this.tooltipContainer.style.transform = `translate3d(${position.x}px, ${position.y}px, 0px)`;
      // this.tooltipContainer.style.top = `${position.y}px`;
      // @ts-ignore
      // this.tooltipContainer.style.left = `${position.x}px`;

      if (cfg?.showMarkers) {
        // @ts-ignore
        this.renderTooltipMarkers(items, cfg.marker);
      }

      // 显示辅助线
      if (cfg?.showCrosshairs && items?.length) {
        const dataPoint = {
          x: items[0]?.x,
          y: items[0]?.y,
        }; // 数据点位置
        const isCrosshairsFollowCursor = cfg?.crosshairs?.follow || false;
        // @ts-ignore
        super.renderCrosshairs(isCrosshairsFollowCursor ? point : dataPoint, cfg);
      }
    } else {
      super.showTooltip(point);
    }

    // 开启锁定时绘制锁定icon
    if (cfg?.lockable) {
      this.drawLockElement(false);
    }
  }