【Antv G6】关系图谱鼠标覆盖节点和边 显示tooltip 以及部分节点tooltip不显示问题处理 节点和边常用事件的监听

上示例图

在这里插入图片描述
在这里插入图片描述

一、鼠标覆盖部分节点tooltip不显示问题处理

现象

以下注释掉的这段代码是为节点添加tooltip的方式之一,但会有tooltip隐藏后覆盖节点导致鼠标移动到节点上不出现新的tooltip的现象

modes: {
        default: [
          "drag-node",
          "zoom-canvas",
          "drag-canvas",
          // {
          //   type: 'tooltip',
          //   formatText: function formatText(model) {
          //     // var text = 'description: ' + model.description;
          //     let str = '';
          //     nodeInfo.forEach((it) => {
          //       if (it.id === model.id) {
          //         str = it.description;
          //       }
          //     });
          //     var text = str;
          //     return text;
          //   },

          //   shouldUpdate: function shouldUpdate(e) {
          //     return true;
          //   },
          // },
          {
            type: "edge-tooltip",
            formatText: function formatText(model) {
              let str = "";
              edgesInfo.forEach((it) => {
                let mId = model.start + ":" + model.end;
                if (it.id === mId) {
                  str = it.description;
                }
              });
              var text = str;
              return text;
            },

            shouldUpdate: function shouldUpdate(e) {
              return true;
            },
          },
        ],
      },

解决方式

	const tooltip = new G6.Tooltip({
      // offsetX and offsetY include the padding of the parent container
      offsetX: 20,
      offsetY: 30,
      // the types of items that allow the tooltip show up
      // 允许出现 tooltip 的 item 类型
      itemTypes: ["node"],
      // custom the tooltip's content
      // 自定义 tooltip 内容
      getContent: (e) => {
        const outDiv = document.createElement("div");
        //outDiv.style.padding = '0px 0px 20px 0px';
        const node = e.item.getModel();
        const nodeName = e.item.getModel().tbl_name;
        if (nodeName) {
          let formatedNodeName = `<div>表名:${node.tbl_name}<br/>节点ID:${node.id}<br/>集群ID:${node.clust_name}<br/>表ID:${node.tbl_id}</div>`;
          // console.log('eeeeeeeeeeee', e, nodeName, formatedNodeName);
          outDiv.innerHTML = `${formatedNodeName}`;
          return outDiv;
        }
      },
    });
    const graph = new G6.Graph({
		...
		plugins: [tooltip],
	});

如需要了解如何监听节点以及边的各种鼠标事件例如点击、覆盖、离开等,请查看以下完整代码示例:

二、完整代码

import G6 from "@antv/g6";
import insertCss from "insert-css";
import { useEffect, useState } from "react";
import { connect } from "umi";
// import constants from '../../constants';
// const COLORS = constants.COLORS;

function SwdtShowHidden(props) {
  const { dispatch, relaData = {}, id, nodeInfo = [], edgesInfo = [] } = props;

  const globalFontSize = 12;
  let nodeSize = 80;

  useEffect(() => {
    // const data = {
    //   nodes: [
    //     {
    //       id: '0',
    //       label: '0',
    //     },
    //     {
    //       id: '1',
    //       label: '1',
    //     },
    //     {
    //       id: '2',
    //       label: '2',
    //     },
    //     {
    //       id: '3',
    //       label: '3',
    //     },
    //     {
    //       id: '4',
    //       label: '4',
    //     },
    //     {
    //       id: '5',
    //       label: '5',
    //     },
    //     {
    //       id: '6',
    //       label: '6',
    //     },
    //     {
    //       id: '7',
    //       label: '7',
    //     },
    //     {
    //       id: '8',
    //       label: '8',
    //     },
    //     {
    //       id: '9',
    //       label: '9',
    //     },
    //   ],
    //   edges: [
    //     {
    //       source: '0',
    //       target: '1',
    //     },
    //     {
    //       source: '0',
    //       target: '2',
    //     },
    //     {
    //       source: '0',
    //       target: '3',
    //     },
    //     {
    //       source: '0',
    //       target: '4',
    //     },
    //     {
    //       source: '0',
    //       target: '5',
    //     },
    //     {
    //       source: '0',
    //       target: '7',
    //     },
    //     {
    //       source: '0',
    //       target: '8',
    //     },
    //     {
    //       source: '0',
    //       target: '9',
    //     },
    //     {
    //       source: '2',
    //       target: '3',
    //     },
    //     {
    //       source: '4',
    //       target: '5',
    //     },
    //     {
    //       source: '4',
    //       target: '6',
    //     },
    //     {
    //       source: '5',
    //       target: '6',
    //     },
    //   ],
    // };
    const container = document.getElementById(`container${id}`);
    const width = container.scrollWidth;
    const height = container.scrollHeight || 500;

    insertCss(`
      .g6-component-tooltip {
        background-color: rgba(0,0,0, 0.65);
        padding: 10px;
        box-shadow: rgb(174, 174, 174) 0px 0px 10px;
        width: fit-content;
        color: #fff;

        border-radius = 4px;
      }
      .g6-tooltip {
        border: 1px solid #e2e2e2;

        border-radius: 4px;
        font-size: 12px;
        color: #545454;

        background-color: rgba(255, 255, 255, 0.9);
        padding: 10px 8px;
        box-shadow: rgb(174, 174, 174) 0px 0px 10px;
      }
    `);
    const tooltip = new G6.Tooltip({
      // offsetX and offsetY include the padding of the parent container
      offsetX: 20,
      offsetY: 30,
      // the types of items that allow the tooltip show up
      // 允许出现 tooltip 的 item 类型
      itemTypes: ["node"],
      // custom the tooltip's content
      // 自定义 tooltip 内容
      getContent: (e) => {
        const outDiv = document.createElement("div");
        //outDiv.style.padding = '0px 0px 20px 0px';
        const node = e.item.getModel();
        const nodeName = e.item.getModel().tbl_name;
        if (nodeName) {
          let formatedNodeName = `<div>表名:${node.tbl_name}<br/>节点ID:${node.id}<br/>集群ID:${node.clust_name}<br/>表ID:${node.tbl_id}</div>`;
          // console.log('eeeeeeeeeeee', e, nodeName, formatedNodeName);
          outDiv.innerHTML = `${formatedNodeName}`;
          return outDiv;
        }
      },
    });
    const graph = new G6.Graph({
      container: `container${id}`,
      width,
      height,
      plugins: [tooltip],
      layout: {
        type: "force",
        preventOverlap: true,
        nodeSize: nodeSize + 50,
      },
      fitCenter: true,
      modes: {
        default: [
          "drag-node",
          "zoom-canvas",
          "drag-canvas",
          // {
          //   type: 'tooltip',
          //   formatText: function formatText(model) {
          //     // var text = 'description: ' + model.description;
          //     let str = '';
          //     nodeInfo.forEach((it) => {
          //       if (it.id === model.id) {
          //         str = it.description;
          //       }
          //     });
          //     var text = str;
          //     return text;
          //   },

          //   shouldUpdate: function shouldUpdate(e) {
          //     return true;
          //   },
          // },
          {
            type: "edge-tooltip",
            formatText: function formatText(model) {
              let str = "";
              edgesInfo.forEach((it) => {
                let mId = model.start + ":" + model.end;
                if (it.id === mId) {
                  str = it.description;
                }
              });
              var text = str;
              return text;
            },

            shouldUpdate: function shouldUpdate(e) {
              return true;
            },
          },
        ],
      },
      defaultNode: {
        // type: 'rect',
        size: [nodeSize, 40],
        labelCfg: {
          style: {
            fontSize: globalFontSize,
          },
        },
      },
      defaultEdge: {
        type: "cubic-horizontal",
        style: {
          stroke: "#CED4D9",
          endArrow: true,
          // endArrow: {
          //   path: G6.Arrow.vee(10, 20, 10),
          //   d: 10,
          // },
        },
      },
    });
    /**
     * format the string
     * @param {string} str The origin string
     * @param {number} maxWidth max width
     * @param {number} fontSize font size
     * @return {string} the processed result
     */
    const fittingString = (str, maxWidth, fontSize) => {
      const ellipsis = "...";
      const ellipsisLength = G6.Util.getTextSize(ellipsis, fontSize)[0];
      let currentWidth = 0;
      let res = str;
      const pattern = new RegExp("[\u4E00-\u9FA5]+"); // distinguish the Chinese charactors and letters
      if (str) {
        str.split("").forEach((letter, i) => {
          if (currentWidth > maxWidth - ellipsisLength) return;
          if (pattern.test(letter)) {
            // Chinese charactors
            currentWidth += fontSize;
          } else {
            // get the width of single letter according to the fontSize
            currentWidth += G6.Util.getLetterWidth(letter, fontSize);
          }
          if (currentWidth > maxWidth - ellipsisLength) {
            res = `${str.substr(0, i)}${ellipsis}`;
          }
        });
      }
      return res;
    };
    // Modify the label in the data
    relaData.nodes &&
      relaData.nodes.forEach(function (node) {
        node.label = fittingString(node.label, nodeSize, globalFontSize);
      });
    // relaData.edges.forEach(function (edge) {
    //   console.log('当前边', edge);
    //   edge.label = fittingString(edge.label, 120, globalFontSize);
    // });
    graph.data(relaData);
    graph.render();

    function refreshDragedNodePosition(e) {
      const model = e.item.get("model");
      model.fx = e.x;
      model.fy = e.y;
    }
    graph.on("node:dragstart", (e) => {
      graph.layout();
      refreshDragedNodePosition(e);
    });
    graph.on("node:drag", (e) => {
      refreshDragedNodePosition(e);
    });

    // 清除节点+边高亮
    function clearAllStats() {
      graph.setAutoPaint(false);
      graph.getNodes().forEach(function (node) {
        graph.clearItemStates(node);
      });
      graph.getEdges().forEach(function (edge) {
        graph.clearItemStates(edge);
      });
      graph.paint();
      graph.setAutoPaint(true);
    }

    // graph.on('edge:click', (e) => {
    //   console.log('eeeeeeeeee', e);
    // });

    graph.on("node:mouseenter", function (e) {
      var item = e.item;
      graph.setAutoPaint(false);
      graph.getNodes().forEach(function (node) {
        graph.clearItemStates(node);
        graph.setItemState(node, "dark", true);
      });
      graph.setItemState(item, "dark", false);
      graph.setItemState(item, "highlight", true);
      graph.getEdges().forEach(function (edge) {
        if (edge.getSource() === item) {
          graph.setItemState(edge.getTarget(), "dark", false);
          graph.setItemState(edge.getTarget(), "highlight", true);
          graph.setItemState(edge, "highlight", true);
          edge.toFront();
        } else if (edge.getTarget() === item) {
          graph.setItemState(edge.getSource(), "dark", false);
          graph.setItemState(edge.getSource(), "highlight", true);
          graph.setItemState(edge, "highlight", true);
          edge.toFront();
        } else {
          graph.setItemState(edge, "highlight", false);
        }
      });
      graph.paint();
      graph.setAutoPaint(true);
    });
    graph.on("node:mouseleave", clearAllStats);

    graph.on("edge:mouseenter", function (e) {
      var item = e.item;
      // console.log('移动到边上了', e, item);
      graph.setAutoPaint(false);
      graph.setItemState(item, "dark", false);
      graph.setItemState(item, "highlight", true);
      graph.paint();
      graph.setAutoPaint(true);
    });

    graph.on("edge:mouseleave", clearAllStats);

    graph.on("canvas:click", clearAllStats);

    if (typeof window !== "undefined")
      window.onresize = () => {
        if (!graph || graph.get("destroyed")) return;
        if (!container || !container.scrollWidth || !container.scrollHeight)
          return;
        graph.changeSize(container.scrollWidth, container.scrollHeight);
      };
  }, [relaData, id, nodeInfo, edgesInfo]);

  return <div id={`container${id}`} style={{ height: "100%" }}></div>;
}

export default connect((store) => {
  return {};
})(SwdtShowHidden);

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hzxOnlineOk

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值