antvis/G6

[Bug]: When vue3 is connected, the right-click occasionally reports an error and the click event is invalid #6791

jinpikaFE posted onGitHub

Describe the bug / 问题描述

It is illegal to free an event not managed by this EventBoundary 报错信息;同时该浏览器tab 卡死

Image

<template>
  <div class="relative bg-[#f0f2f5] w-full h-[800px]" @contextmenu.prevent="">
    <div id="container" ref="containerRef" class="w-full h-full" />
    <NodeContextMenu
      :showModal="showConditionMenu"
      :x="conditionMenuPosition.x"
      :y="conditionMenuPosition.y"
      :node-data="targetNodeData"
    />
  </div>
</template>

<script setup lang="ts">
import { Graph, NodeEvent, Size, treeToGraphData } from "@antv/g6";
import { onMounted, onUnmounted, ref } from "vue";
import NodeContextMenu from "./components/NodeContextMenu/index.vue";
import { G6DataType, G6NodeTypeEnum, G6NodeTypeMap } from "./typing";

const data: G6DataType = {
  id: "root",
  type: "circle",
  data: {
    label: "+",
    nodeType: G6NodeTypeEnum.ROOT,
    fill: G6NodeTypeMap[G6NodeTypeEnum.ROOT].fill
  },
  children: [
    {
      id: "and",
      type: "circle",
      data: {
        label: "并且",
        nodeType: G6NodeTypeEnum.AND,
        fill: G6NodeTypeMap[G6NodeTypeEnum.AND].fill
      },
      children: [
        {
          id: "condition",
          type: G6NodeTypeMap[G6NodeTypeEnum.CONDITION].type,
          data: {
            label: "条件条件条件条件条件条件条件条件条件",
            nodeType: G6NodeTypeEnum.CONDITION,
            fill: G6NodeTypeMap[G6NodeTypeEnum.CONDITION].fill
          }
        },
        {
          id: "condition2",
          type: G6NodeTypeMap[G6NodeTypeEnum.CONDITION].type,
          data: {
            label: "条件条件条条件2",
            nodeType: G6NodeTypeEnum.CONDITION,
            fill: G6NodeTypeMap[G6NodeTypeEnum.CONDITION].fill
          }
        },
        {
          id: "condition3",
          type: G6NodeTypeMap[G6NodeTypeEnum.CONDITION].type,
          data: {
            label: "条件条件条件3",
            nodeType: G6NodeTypeEnum.CONDITION,
            fill: G6NodeTypeMap[G6NodeTypeEnum.CONDITION].fill
          }
        },
        {
          id: "and1",
          type: "circle",
          data: {
            label: "并且",
            nodeType: G6NodeTypeEnum.AND,
            fill: G6NodeTypeMap[G6NodeTypeEnum.AND].fill
          },
          children: [
            {
              id: "conditio22n",
              type: G6NodeTypeMap[G6NodeTypeEnum.CONDITION].type,
              data: {
                label: "条件条件条件条件条件条件条件条件条件",
                nodeType: G6NodeTypeEnum.CONDITION,
                fill: G6NodeTypeMap[G6NodeTypeEnum.CONDITION].fill
              }
            },
            {
              id: "condition332",
              type: G6NodeTypeMap[G6NodeTypeEnum.CONDITION].type,
              data: {
                label: "条件条件条条件2",
                nodeType: G6NodeTypeEnum.CONDITION,
                fill: G6NodeTypeMap[G6NodeTypeEnum.CONDITION].fill
              }
            },
            {
              id: "condition344",
              type: G6NodeTypeMap[G6NodeTypeEnum.CONDITION].type,
              data: {
                label: "条件条件条件3",
                nodeType: G6NodeTypeEnum.CONDITION,
                fill: G6NodeTypeMap[G6NodeTypeEnum.CONDITION].fill
              }
            }
          ]
        }
      ]
    }
  ]
};

const containerRef = ref<HTMLDivElement | null>(null);
const graphRef = ref<Graph | null>(null);
const showConditionMenu = ref(false);
const conditionMenuPosition = ref({ x: 0, y: 0 });

const targetNodeData = ref<any>();

const getNodeSize = (d: any): Size => {
  const label = d.data.label;

  const fontSize = 24;
  const maxWidth = 20 * fontSize + 40;
  const width = Math.min(label.length * fontSize + 40, maxWidth);
  return [width, 80];
};

const countNodes = (node: G6DataType): number => {
  let count = 1; // 当前节点
  if (node.children) {
    count += node.children.reduce((sum, child) => sum + countNodes(child), 0);
  }
  return count;
};

const totalNodes = countNodes(data);

onMounted(() => {
  if (!containerRef.value) return;
  if (!graphRef.value) {
    graphRef.value = new Graph({
      container: containerRef.value,
      autoFit: totalNodes > 3 ? "view" : "center",
      padding: 60,
      data: treeToGraphData(data),
      edge: {
        type: "cubic-horizontal"
      },
      node: {
        style: {
          size: getNodeSize,
          labelText: d => (d.data.label as string) || "",
          labelFill: "#fff",
          labelFontWeight: "bold",
          labelFontSize: 24,
          labelPlacement: "center",
          labelLineHeight: 24,
          labelMaxWidth: "95%",
          labelWordWrap: true,
          fill: d => (d.data.fill as string) || "#65cec5",
          stroke: d => (d.data.fill as string) || "#65cec5"
        },
        state: {
          focus: {
            lineWidth: 3,
            stroke: "orange"
          }
        }
      },
      layout: {
        type: "compact-box",
        direction: "LR",

        getVGap: d => {
          return d?.data?.label?.length * 2 + 40;
        },
        getHGap: d => {
          return d?.data?.label?.length * 100 + 40;
        }
      },
      plugins: [
        {
          type: "minimap",
          width: 150,
          height: 150,
          position: "bottom-left"
        },

        {
          type: "tooltip",
          getContent: (e, items) => {
            let result = ``;
            items.forEach(item => {
              if (item.data?.nodeType === G6NodeTypeEnum.CONDITION) {
                result += `<p>${item.data.label}</p>`;
              }
            });
            return result;
          }
        }
      ],
      behaviors: ["drag-canvas", "zoom-canvas", "hover-activate"],
      autoResize: true
    });

    graphRef.value.render();
    // graphRef.value.on(NodeEvent.CLICK, (event: any) => {
    //   console.log(event);
    //   const target = event?.target;
    //   const nodeData = graphRef.value?.getElementData(target?.id);
    //   if (nodeData?.data?.nodeType === G6NodeTypeEnum.ROOT) {
    //     return;
    //   }
    //   targetNodeData.value = nodeData;
    //   showConditionMenu.value = true;
    //   conditionMenuPosition.value = {
    //     x: target?.style?.x,
    //     y: target?.style?.y
    //   };
    //   console.log(nodeData);
    // });
  }
});

onUnmounted(() => {
  // graphRef.value?.off();
  // graphRef.value?.destroy();
});
</script>

No response

Steps to Reproduce the Bug or Issue / 重现步骤

No response

Version / 版本

🆕 5.x

OS / 操作系统

  • macOS
  • Windows
  • Linux
  • Others / 其他

Browser / 浏览器

  • Chrome
  • Edge
  • Firefox
  • Safari (Limited support / 有限支持)
  • IE (Nonsupport / 不支持)
  • Others / 其他

https://g6.antv.antgroup.com/manual/getting-started/integration/vue 在vue中避免响应式数据,不要使用ref,可以改为let graphRef = (null);

posted by luck3yl 2 months ago

⚠️ This issue has been automatically closed due to inactivity.

  • If the issue is still relevant and important to you, feel free to:
    1. Reopen with additional information
    2. Create a new issue with updated context
    3. Reference any related issues or discussions

We close inactive issues to keep our backlog manageable and focused on active issues.

Your contribution makes our project better! 🌟


⚠️ 由于长期无活动,此 issue 已被自动关闭。

  • 如果这个问题对您来说仍然重要,您可以:
    1. 重新打开并提供补充信息
    2. 创建一个新的 issue 并更新相关背景
    3. 关联相关的 issue 或讨论

为了更好地维护项目,我们需要定期清理不活跃的问题。

感谢您为开源添砖加瓦!🌟

posted by github-actions[bot] about 2 months ago

Fund this Issue

$0.00
Funded

Pull requests