Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

X6未来有支持从一条边上直接拖拽出一条边的功能吗 #4590

Open
fireflyshen opened this issue Mar 10, 2025 · 8 comments
Open

Comments

@fireflyshen
Copy link

功能描述

制作电力接线图会遇到大量边链接边的场景

期望解决方案

如图:Image

@x6-bot
Copy link
Contributor

x6-bot bot commented Mar 10, 2025

👋 @fireflyshen

Thanks for opening your first issue here! If you're reporting a 🐞 bug, please make sure you include steps to reproduce it.
To help make it easier for us to investigate your issue, please follow the contributing guidelines.
We get a lot of issues on this repo, so please be patient and we will get back to you as soon as we can.

@cgxdd
Copy link

cgxdd commented Mar 11, 2025

我也是要做电力图,现在折中的方案就是自定义线条的node,当作edge来使用

@fireflyshen
Copy link
Author

我也是要做电力图,现在折中的方案就是自定义线条的node,当作edge来使用

也不是没有办法,就是使用锚点,但是这样实现也不太方便,

Image

用自定义节点的话,拓扑关系又不好建立,头大

@fireflyshen
Copy link
Author

#2027 (comment) 还有一个删除原边添加中间端子的方法,都不太友好

@colonot
Copy link

colonot commented Mar 11, 2025

我也是要做电力图,现在折中的方案就是自定义线条的node,当作edge来使用

也不是没有办法,就是使用锚点,但是这样实现也不太方便,

Image Image

用自定义节点的话,拓扑关系又不好建立,头大
创建电线,拖动鼠标绘制绘制出一条边,这个实现思路是什么

@fireflyshen
Copy link
Author

我也是要做电力图,现在折中的方案就是自定义线条的node,当作edge来使用

也不是没有办法,就是使用锚点,但是这样实现也不太方便,
Image

    [
      
    
        ![Image](https://github.com/user-attachments/assets/1a74af21-979d-4863-afd8-b211cddaa50a)
      ](https://private-user-images.githubusercontent.com/59105078/421150741-1a74af21-979d-4863-afd8-b211cddaa50a.gif?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NDE2NzUwNTcsIm5iZiI6MTc0MTY3NDc1NywicGF0aCI6Ii81OTEwNTA3OC80MjExNTA3NDEtMWE3NGFmMjEtOTc5ZC00ODYzLWFmZDgtYjIxMWNkZGFhNTBhLmdpZj9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAzMTElMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMzExVDA2MzIzN1omWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWEyZTlmYTliNDlhNTIxNzUzMjljNmQyMGRjZGQ4YjU5MmIzYzQ1M2M5ZDcyODFmNzg2MjkyZWJmODQ4NmU0OWImWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.uaoa1IssYWPQt1NawxzoBkfBb6NMwjo2p7kWI-mttZ0)
    
    
      
        
          
        
        
          
          
        
      
      [
        
          
        
      ](https://private-user-images.githubusercontent.com/59105078/421150741-1a74af21-979d-4863-afd8-b211cddaa50a.gif?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NDE2NzUwNTcsIm5iZiI6MTc0MTY3NDc1NywicGF0aCI6Ii81OTEwNTA3OC80MjExNTA3NDEtMWE3NGFmMjEtOTc5ZC00ODYzLWFmZDgtYjIxMWNkZGFhNTBhLmdpZj9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAzMTElMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMzExVDA2MzIzN1omWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWEyZTlmYTliNDlhNTIxNzUzMjljNmQyMGRjZGQ4YjU5MmIzYzQ1M2M5ZDcyODFmNzg2MjkyZWJmODQ4NmU0OWImWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.uaoa1IssYWPQt1NawxzoBkfBb6NMwjo2p7kWI-mttZ0)
    
   [ ![Image](https://github.com/user-attachments/assets/1a74af21-979d-4863-afd8-b211cddaa50a) ](https://private-user-images.githubusercontent.com/59105078/421150741-1a74af21-979d-4863-afd8-b211cddaa50a.gif?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NDE2NjY1NDksIm5iZiI6MTc0MTY2NjI0OSwicGF0aCI6Ii81OTEwNTA3OC80MjExNTA3NDEtMWE3NGFmMjEtOTc5ZC00ODYzLWFmZDgtYjIxMWNkZGFhNTBhLmdpZj9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAzMTElMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMzExVDA0MTA0OVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWQyNDYzOGVkZTc1YTQ4MGM3M2MxOGRjZGM4ZmNjNjVmZTJhOTVkZDVhMGMwZjRjOTRlZWYxNjAxYmI5MDkzZDUmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.AlKLN0Dg3PWweW0qAkHLWb3lzzjdakY57MgQ9mxzFXI)
  
    [
      
    
        ![Image](https://github.com/user-attachments/assets/1a74af21-979d-4863-afd8-b211cddaa50a)
      ](https://private-user-images.githubusercontent.com/59105078/421150741-1a74af21-979d-4863-afd8-b211cddaa50a.gif?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NDE2NjY1NDksIm5iZiI6MTc0MTY2NjI0OSwicGF0aCI6Ii81OTEwNTA3OC80MjExNTA3NDEtMWE3NGFmMjEtOTc5ZC00ODYzLWFmZDgtYjIxMWNkZGFhNTBhLmdpZj9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAzMTElMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMzExVDA0MTA0OVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWQyNDYzOGVkZTc1YTQ4MGM3M2MxOGRjZGM4ZmNjNjVmZTJhOTVkZDVhMGMwZjRjOTRlZWYxNjAxYmI5MDkzZDUmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.AlKLN0Dg3PWweW0qAkHLWb3lzzjdakY57MgQ9mxzFXI)
    
    
      
        
          
        
        
          
          
        
      
      [
        
          
        
      ](https://private-user-images.githubusercontent.com/59105078/421150741-1a74af21-979d-4863-afd8-b211cddaa50a.gif?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NDE2NjY1NDksIm5iZiI6MTc0MTY2NjI0OSwicGF0aCI6Ii81OTEwNTA3OC80MjExNTA3NDEtMWE3NGFmMjEtOTc5ZC00ODYzLWFmZDgtYjIxMWNkZGFhNTBhLmdpZj9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAzMTElMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMzExVDA0MTA0OVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWQyNDYzOGVkZTc1YTQ4MGM3M2MxOGRjZGM4ZmNjNjVmZTJhOTVkZDVhMGMwZjRjOTRlZWYxNjAxYmI5MDkzZDUmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.AlKLN0Dg3PWweW0qAkHLWb3lzzjdakY57MgQ9mxzFXI)
    
   [ ](https://private-user-images.githubusercontent.com/59105078/421150741-1a74af21-979d-4863-afd8-b211cddaa50a.gif?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NDE2NjY1NDksIm5iZiI6MTc0MTY2NjI0OSwicGF0aCI6Ii81OTEwNTA3OC80MjExNTA3NDEtMWE3NGFmMjEtOTc5ZC00ODYzLWFmZDgtYjIxMWNkZGFhNTBhLmdpZj9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAzMTElMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMzExVDA0MTA0OVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWQyNDYzOGVkZTc1YTQ4MGM3M2MxOGRjZGM4ZmNjNjVmZTJhOTVkZDVhMGMwZjRjOTRlZWYxNjAxYmI5MDkzZDUmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.AlKLN0Dg3PWweW0qAkHLWb3lzzjdakY57MgQ9mxzFXI)

用自定义节点的话,拓扑关系又不好建立,头大
创建电线,拖动鼠标绘制绘制出一条边,这个实现思路是什么

点击画布空白处创建一个临时边,你可监听鼠标在画布空白处移动的事件,或者监听鼠标在浏览器上移动的事件,前者X6原生事件有缺陷,就是你必须按下鼠标移动才能触发,然后不断通过setTarget这个函数更新坐标就行了,再次点击屏幕空白把这个点定住就行。需要固定连接桩就要用到边工具,还有一个问题就是边外部是有一个包围盒的,你的鼠标要离创建出来的边有一定的距离,或者通过一些手段把那个包围盒去掉,大概是如下

document.addEventListener("mousemove", (e) => {
// 获取鼠标当前位置(客户端坐标)
const mouseClientX = e.clientX;
const mouseClientY = e.clientY;

    // 将鼠标位置转换为图形本地坐标
    const localPosition = this.graph.clientToLocal({
      x: mouseClientX,
      y: mouseClientY,
    });

    this.mousePosition = localPosition;

    if (this.graph.tempEdge) {
      // 尝试直接获取边的源点
      let sourcePoint;

      // 获取源信息
      const source = this.graph.tempEdge.getSource();

      // 如果源是节点和端口组合
      if (source && source.cell) {
        const sourceCell = this.graph.getCellById(source.cell);

        if (sourceCell && source.port) {
          // 尝试获取端口位置
          try {
            // 不同版本的X6可能有不同的获取端口位置的方法
            sourcePoint = sourceCell.getPortProp(source.port, "position");

            // 如果position是相对坐标,需要转换为绝对坐标
            if (
              sourcePoint &&
              typeof sourcePoint.x === "number" &&
              typeof sourcePoint.y === "number"
            ) {
              const bbox = sourceCell.getBBox();
              sourcePoint = {
                x: bbox.x + sourcePoint.x * bbox.width,
                y: bbox.y + sourcePoint.y * bbox.height,
              };
            }
          } catch (err) {
            console.warn("无法获取端口位置", err);
          }
        }

        // 如果没有获取到端口位置,就使用节点中心
        if (!sourcePoint) {
          const bbox = sourceCell.getBBox();
          sourcePoint = {
            x: bbox.x + bbox.width / 2,
            y: bbox.y + bbox.height / 2,
          };
        }
      } else if (
        typeof source === "object" &&
        "x" in source &&
        "y" in source
      ) {
        // 如果源点是坐标对象
        sourcePoint = source;
      }

      // 如果没有获取到源点,使用边的第一个点
      if (!sourcePoint) {
        try {
          const points = this.graph.tempEdge.getVertices();
          if (points && points.length > 0) {
            sourcePoint = points[0];
          }
        } catch (err) {
          console.warn("无法获取边的顶点", err);
        }
      }

      // 最后尝试使用边的位置
      if (!sourcePoint) {
        const edgeBBox = this.graph.tempEdge.getBBox();
        sourcePoint = {
          x: edgeBBox.x,
          y: edgeBBox.y,
        };
      }

      if (!sourcePoint || isNaN(sourcePoint.x) || isNaN(sourcePoint.y)) {
        console.error("无法获取有效的源点坐标");
        return;
      }

      // 全部使用本地坐标系计算角度
      const angle = Math.atan2(
        localPosition.y - sourcePoint.y,
        localPosition.x - sourcePoint.x
      );

      // 设置偏移距离
      const offset = 2;

      // 在本地坐标系中计算偏移目标位置
      const targetX = localPosition.x - Math.cos(angle) * offset;
      const targetY = localPosition.y - Math.sin(angle) * offset;

      // 设置边的终点
      this.graph.tempEdge.setTarget({
        x: targetX,
        y: targetY,
      });
    }
  });

@fireflyshen
Copy link
Author

我也是要做电力图,现在折中的方案就是自定义线条的node,当作edge来使用

也不是没有办法,就是使用锚点,但是这样实现也不太方便,
Image

    [
      
    
        ![Image](https://github.com/user-attachments/assets/1a74af21-979d-4863-afd8-b211cddaa50a)
      ](https://private-user-images.githubusercontent.com/59105078/421150741-1a74af21-979d-4863-afd8-b211cddaa50a.gif?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NDE2NzU1MjQsIm5iZiI6MTc0MTY3NTIyNCwicGF0aCI6Ii81OTEwNTA3OC80MjExNTA3NDEtMWE3NGFmMjEtOTc5ZC00ODYzLWFmZDgtYjIxMWNkZGFhNTBhLmdpZj9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAzMTElMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMzExVDA2NDAyNFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTYzZDhjZjRmNTJkYzJjYWM3ZTljZmIwNTllNDRmNjkzOGExYjg4ZTRlZjQyOTNhYWU0MTk1NWViNjQ4M2U5NjImWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.0g5JAwijU33Vdjiujpy5I3f8iNXtMJTcdOpSg3kxgAY)
    
    
      
        
          
        
        
          
          
        
      
      [
        
          
        
      ](https://private-user-images.githubusercontent.com/59105078/421150741-1a74af21-979d-4863-afd8-b211cddaa50a.gif?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NDE2NzU1MjQsIm5iZiI6MTc0MTY3NTIyNCwicGF0aCI6Ii81OTEwNTA3OC80MjExNTA3NDEtMWE3NGFmMjEtOTc5ZC00ODYzLWFmZDgtYjIxMWNkZGFhNTBhLmdpZj9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAzMTElMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMzExVDA2NDAyNFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTYzZDhjZjRmNTJkYzJjYWM3ZTljZmIwNTllNDRmNjkzOGExYjg4ZTRlZjQyOTNhYWU0MTk1NWViNjQ4M2U5NjImWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.0g5JAwijU33Vdjiujpy5I3f8iNXtMJTcdOpSg3kxgAY)
    [
      
    
        ![Image](https://github.com/user-attachments/assets/1a74af21-979d-4863-afd8-b211cddaa50a)
      ](https://private-user-images.githubusercontent.com/59105078/421150741-1a74af21-979d-4863-afd8-b211cddaa50a.gif?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NDE2NzUwNTcsIm5iZiI6MTc0MTY3NDc1NywicGF0aCI6Ii81OTEwNTA3OC80MjExNTA3NDEtMWE3NGFmMjEtOTc5ZC00ODYzLWFmZDgtYjIxMWNkZGFhNTBhLmdpZj9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAzMTElMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMzExVDA2MzIzN1omWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWEyZTlmYTliNDlhNTIxNzUzMjljNmQyMGRjZGQ4YjU5MmIzYzQ1M2M5ZDcyODFmNzg2MjkyZWJmODQ4NmU0OWImWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.uaoa1IssYWPQt1NawxzoBkfBb6NMwjo2p7kWI-mttZ0)
    
    
      
        
          
        
        
          
          
        
      
      [
        
          
        
      ](https://private-user-images.githubusercontent.com/59105078/421150741-1a74af21-979d-4863-afd8-b211cddaa50a.gif?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NDE2NzUwNTcsIm5iZiI6MTc0MTY3NDc1NywicGF0aCI6Ii81OTEwNTA3OC80MjExNTA3NDEtMWE3NGFmMjEtOTc5ZC00ODYzLWFmZDgtYjIxMWNkZGFhNTBhLmdpZj9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAzMTElMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMzExVDA2MzIzN1omWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWEyZTlmYTliNDlhNTIxNzUzMjljNmQyMGRjZGQ4YjU5MmIzYzQ1M2M5ZDcyODFmNzg2MjkyZWJmODQ4NmU0OWImWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.uaoa1IssYWPQt1NawxzoBkfBb6NMwjo2p7kWI-mttZ0)
    
   [ ![Image](https://github.com/user-attachments/assets/1a74af21-979d-4863-afd8-b211cddaa50a) ](https://private-user-images.githubusercontent.com/59105078/421150741-1a74af21-979d-4863-afd8-b211cddaa50a.gif?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NDE2NjY1NDksIm5iZiI6MTc0MTY2NjI0OSwicGF0aCI6Ii81OTEwNTA3OC80MjExNTA3NDEtMWE3NGFmMjEtOTc5ZC00ODYzLWFmZDgtYjIxMWNkZGFhNTBhLmdpZj9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAzMTElMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMzExVDA0MTA0OVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWQyNDYzOGVkZTc1YTQ4MGM3M2MxOGRjZGM4ZmNjNjVmZTJhOTVkZDVhMGMwZjRjOTRlZWYxNjAxYmI5MDkzZDUmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.AlKLN0Dg3PWweW0qAkHLWb3lzzjdakY57MgQ9mxzFXI)
  
    [
      
    
        ![Image](https://github.com/user-attachments/assets/1a74af21-979d-4863-afd8-b211cddaa50a)
      ](https://private-user-images.githubusercontent.com/59105078/421150741-1a74af21-979d-4863-afd8-b211cddaa50a.gif?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NDE2NjY1NDksIm5iZiI6MTc0MTY2NjI0OSwicGF0aCI6Ii81OTEwNTA3OC80MjExNTA3NDEtMWE3NGFmMjEtOTc5ZC00ODYzLWFmZDgtYjIxMWNkZGFhNTBhLmdpZj9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAzMTElMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMzExVDA0MTA0OVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWQyNDYzOGVkZTc1YTQ4MGM3M2MxOGRjZGM4ZmNjNjVmZTJhOTVkZDVhMGMwZjRjOTRlZWYxNjAxYmI5MDkzZDUmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.AlKLN0Dg3PWweW0qAkHLWb3lzzjdakY57MgQ9mxzFXI)
    
    
      
        
          
        
        
          
          
        
      
      [
        
          
        
      ](https://private-user-images.githubusercontent.com/59105078/421150741-1a74af21-979d-4863-afd8-b211cddaa50a.gif?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NDE2NjY1NDksIm5iZiI6MTc0MTY2NjI0OSwicGF0aCI6Ii81OTEwNTA3OC80MjExNTA3NDEtMWE3NGFmMjEtOTc5ZC00ODYzLWFmZDgtYjIxMWNkZGFhNTBhLmdpZj9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAzMTElMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMzExVDA0MTA0OVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWQyNDYzOGVkZTc1YTQ4MGM3M2MxOGRjZGM4ZmNjNjVmZTJhOTVkZDVhMGMwZjRjOTRlZWYxNjAxYmI5MDkzZDUmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.AlKLN0Dg3PWweW0qAkHLWb3lzzjdakY57MgQ9mxzFXI)
    
   [ ](https://private-user-images.githubusercontent.com/59105078/421150741-1a74af21-979d-4863-afd8-b211cddaa50a.gif?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NDE2NjY1NDksIm5iZiI6MTc0MTY2NjI0OSwicGF0aCI6Ii81OTEwNTA3OC80MjExNTA3NDEtMWE3NGFmMjEtOTc5ZC00ODYzLWFmZDgtYjIxMWNkZGFhNTBhLmdpZj9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAzMTElMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMzExVDA0MTA0OVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWQyNDYzOGVkZTc1YTQ4MGM3M2MxOGRjZGM4ZmNjNjVmZTJhOTVkZDVhMGMwZjRjOTRlZWYxNjAxYmI5MDkzZDUmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.AlKLN0Dg3PWweW0qAkHLWb3lzzjdakY57MgQ9mxzFXI)

用自定义节点的话,拓扑关系又不好建立,头大
创建电线,拖动鼠标绘制绘制出一条边,这个实现思路是什么

点击画布空白处创建一个临时边,你可监听鼠标在画布空白处移动的事件,或者监听鼠标在浏览器上移动的事件,前者X6原生事件有缺陷,就是你必须按下鼠标移动才能触发,然后不断通过setTarget这个函数更新坐标就行了,再次点击屏幕空白把这个点定住就行。需要固定连接桩就要用到边工具,还有一个问题就是边外部是有一个包围盒的,你的鼠标要离创建出来的边有一定的距离,或者通过一些手段把那个包围盒去掉,大概是如下

document.addEventListener("mousemove", (e) => { // 获取鼠标当前位置(客户端坐标) const mouseClientX = e.clientX; const mouseClientY = e.clientY;

    // 将鼠标位置转换为图形本地坐标
    const localPosition = this.graph.clientToLocal({
      x: mouseClientX,
      y: mouseClientY,
    });

    this.mousePosition = localPosition;

    if (this.graph.tempEdge) {
      // 尝试直接获取边的源点
      let sourcePoint;

      // 获取源信息
      const source = this.graph.tempEdge.getSource();

      // 如果源是节点和端口组合
      if (source && source.cell) {
        const sourceCell = this.graph.getCellById(source.cell);

        if (sourceCell && source.port) {
          // 尝试获取端口位置
          try {
            // 不同版本的X6可能有不同的获取端口位置的方法
            sourcePoint = sourceCell.getPortProp(source.port, "position");

            // 如果position是相对坐标,需要转换为绝对坐标
            if (
              sourcePoint &&
              typeof sourcePoint.x === "number" &&
              typeof sourcePoint.y === "number"
            ) {
              const bbox = sourceCell.getBBox();
              sourcePoint = {
                x: bbox.x + sourcePoint.x * bbox.width,
                y: bbox.y + sourcePoint.y * bbox.height,
              };
            }
          } catch (err) {
            console.warn("无法获取端口位置", err);
          }
        }

        // 如果没有获取到端口位置,就使用节点中心
        if (!sourcePoint) {
          const bbox = sourceCell.getBBox();
          sourcePoint = {
            x: bbox.x + bbox.width / 2,
            y: bbox.y + bbox.height / 2,
          };
        }
      } else if (
        typeof source === "object" &&
        "x" in source &&
        "y" in source
      ) {
        // 如果源点是坐标对象
        sourcePoint = source;
      }

      // 如果没有获取到源点,使用边的第一个点
      if (!sourcePoint) {
        try {
          const points = this.graph.tempEdge.getVertices();
          if (points && points.length > 0) {
            sourcePoint = points[0];
          }
        } catch (err) {
          console.warn("无法获取边的顶点", err);
        }
      }

      // 最后尝试使用边的位置
      if (!sourcePoint) {
        const edgeBBox = this.graph.tempEdge.getBBox();
        sourcePoint = {
          x: edgeBBox.x,
          y: edgeBBox.y,
        };
      }

      if (!sourcePoint || isNaN(sourcePoint.x) || isNaN(sourcePoint.y)) {
        console.error("无法获取有效的源点坐标");
        return;
      }

      // 全部使用本地坐标系计算角度
      const angle = Math.atan2(
        localPosition.y - sourcePoint.y,
        localPosition.x - sourcePoint.x
      );

      // 设置偏移距离
      const offset = 2;

      // 在本地坐标系中计算偏移目标位置
      const targetX = localPosition.x - Math.cos(angle) * offset;
      const targetY = localPosition.y - Math.sin(angle) * offset;

      // 设置边的终点
      this.graph.tempEdge.setTarget({
        x: targetX,
        y: targetY,
      });
    }
  });

这东西X6不支持的,或是不符合图编辑设计理念,怎么整都有缺陷

@colonot
Copy link

colonot commented Mar 11, 2025

我也是要做电力图,现在折中的方案就是自定义线条的node,当作edge来使用

也不是没有办法,就是使用锚点,但是这样实现也不太方便,
Image

    [
      
    
        ![Image](https://github.com/user-attachments/assets/1a74af21-979d-4863-afd8-b211cddaa50a)
      ](https://private-user-images.githubusercontent.com/59105078/421150741-1a74af21-979d-4863-afd8-b211cddaa50a.gif?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NDE2NzU1OTEsIm5iZiI6MTc0MTY3NTI5MSwicGF0aCI6Ii81OTEwNTA3OC80MjExNTA3NDEtMWE3NGFmMjEtOTc5ZC00ODYzLWFmZDgtYjIxMWNkZGFhNTBhLmdpZj9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAzMTElMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMzExVDA2NDEzMVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWRjZDI0N2M4YzM5MDI2YTIxZjk4MDNlNjk3NjFjYzA1ZDljYjAwNTA2Nzc5Nzg1NGJhMjYwYTAzNTIxOTA0MzAmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.lQN_cWrWX4-94nbAToQAJkY6consiPKpf2VA2Z7o2OI)
    
    
      
        
          
        
        
          
          
        
      
      [
        
          
        
      ](https://private-user-images.githubusercontent.com/59105078/421150741-1a74af21-979d-4863-afd8-b211cddaa50a.gif?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NDE2NzU1OTEsIm5iZiI6MTc0MTY3NTI5MSwicGF0aCI6Ii81OTEwNTA3OC80MjExNTA3NDEtMWE3NGFmMjEtOTc5ZC00ODYzLWFmZDgtYjIxMWNkZGFhNTBhLmdpZj9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAzMTElMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMzExVDA2NDEzMVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWRjZDI0N2M4YzM5MDI2YTIxZjk4MDNlNjk3NjFjYzA1ZDljYjAwNTA2Nzc5Nzg1NGJhMjYwYTAzNTIxOTA0MzAmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.lQN_cWrWX4-94nbAToQAJkY6consiPKpf2VA2Z7o2OI)
    [
      
    
        ![Image](https://github.com/user-attachments/assets/1a74af21-979d-4863-afd8-b211cddaa50a)
      ](https://private-user-images.githubusercontent.com/59105078/421150741-1a74af21-979d-4863-afd8-b211cddaa50a.gif?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NDE2NzU1MjQsIm5iZiI6MTc0MTY3NTIyNCwicGF0aCI6Ii81OTEwNTA3OC80MjExNTA3NDEtMWE3NGFmMjEtOTc5ZC00ODYzLWFmZDgtYjIxMWNkZGFhNTBhLmdpZj9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAzMTElMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMzExVDA2NDAyNFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTYzZDhjZjRmNTJkYzJjYWM3ZTljZmIwNTllNDRmNjkzOGExYjg4ZTRlZjQyOTNhYWU0MTk1NWViNjQ4M2U5NjImWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.0g5JAwijU33Vdjiujpy5I3f8iNXtMJTcdOpSg3kxgAY)
    
    
      
        
          
        
        
          
          
        
      
      [
        
          
        
      ](https://private-user-images.githubusercontent.com/59105078/421150741-1a74af21-979d-4863-afd8-b211cddaa50a.gif?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NDE2NzU1MjQsIm5iZiI6MTc0MTY3NTIyNCwicGF0aCI6Ii81OTEwNTA3OC80MjExNTA3NDEtMWE3NGFmMjEtOTc5ZC00ODYzLWFmZDgtYjIxMWNkZGFhNTBhLmdpZj9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAzMTElMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMzExVDA2NDAyNFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTYzZDhjZjRmNTJkYzJjYWM3ZTljZmIwNTllNDRmNjkzOGExYjg4ZTRlZjQyOTNhYWU0MTk1NWViNjQ4M2U5NjImWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.0g5JAwijU33Vdjiujpy5I3f8iNXtMJTcdOpSg3kxgAY)
    [
      
    
        ![Image](https://github.com/user-attachments/assets/1a74af21-979d-4863-afd8-b211cddaa50a)
      ](https://private-user-images.githubusercontent.com/59105078/421150741-1a74af21-979d-4863-afd8-b211cddaa50a.gif?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NDE2NzUwNTcsIm5iZiI6MTc0MTY3NDc1NywicGF0aCI6Ii81OTEwNTA3OC80MjExNTA3NDEtMWE3NGFmMjEtOTc5ZC00ODYzLWFmZDgtYjIxMWNkZGFhNTBhLmdpZj9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAzMTElMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMzExVDA2MzIzN1omWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWEyZTlmYTliNDlhNTIxNzUzMjljNmQyMGRjZGQ4YjU5MmIzYzQ1M2M5ZDcyODFmNzg2MjkyZWJmODQ4NmU0OWImWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.uaoa1IssYWPQt1NawxzoBkfBb6NMwjo2p7kWI-mttZ0)
    
    
      
        
          
        
        
          
          
        
      
      [
        
          
        
      ](https://private-user-images.githubusercontent.com/59105078/421150741-1a74af21-979d-4863-afd8-b211cddaa50a.gif?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NDE2NzUwNTcsIm5iZiI6MTc0MTY3NDc1NywicGF0aCI6Ii81OTEwNTA3OC80MjExNTA3NDEtMWE3NGFmMjEtOTc5ZC00ODYzLWFmZDgtYjIxMWNkZGFhNTBhLmdpZj9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAzMTElMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMzExVDA2MzIzN1omWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWEyZTlmYTliNDlhNTIxNzUzMjljNmQyMGRjZGQ4YjU5MmIzYzQ1M2M5ZDcyODFmNzg2MjkyZWJmODQ4NmU0OWImWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.uaoa1IssYWPQt1NawxzoBkfBb6NMwjo2p7kWI-mttZ0)
    
   [ ![Image](https://github.com/user-attachments/assets/1a74af21-979d-4863-afd8-b211cddaa50a) ](https://private-user-images.githubusercontent.com/59105078/421150741-1a74af21-979d-4863-afd8-b211cddaa50a.gif?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NDE2NjY1NDksIm5iZiI6MTc0MTY2NjI0OSwicGF0aCI6Ii81OTEwNTA3OC80MjExNTA3NDEtMWE3NGFmMjEtOTc5ZC00ODYzLWFmZDgtYjIxMWNkZGFhNTBhLmdpZj9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAzMTElMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMzExVDA0MTA0OVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWQyNDYzOGVkZTc1YTQ4MGM3M2MxOGRjZGM4ZmNjNjVmZTJhOTVkZDVhMGMwZjRjOTRlZWYxNjAxYmI5MDkzZDUmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.AlKLN0Dg3PWweW0qAkHLWb3lzzjdakY57MgQ9mxzFXI)
  
    [
      
    
        ![Image](https://github.com/user-attachments/assets/1a74af21-979d-4863-afd8-b211cddaa50a)
      ](https://private-user-images.githubusercontent.com/59105078/421150741-1a74af21-979d-4863-afd8-b211cddaa50a.gif?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NDE2NjY1NDksIm5iZiI6MTc0MTY2NjI0OSwicGF0aCI6Ii81OTEwNTA3OC80MjExNTA3NDEtMWE3NGFmMjEtOTc5ZC00ODYzLWFmZDgtYjIxMWNkZGFhNTBhLmdpZj9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAzMTElMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMzExVDA0MTA0OVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWQyNDYzOGVkZTc1YTQ4MGM3M2MxOGRjZGM4ZmNjNjVmZTJhOTVkZDVhMGMwZjRjOTRlZWYxNjAxYmI5MDkzZDUmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.AlKLN0Dg3PWweW0qAkHLWb3lzzjdakY57MgQ9mxzFXI)
    
    
      
        
          
        
        
          
          
        
      
      [
        
          
        
      ](https://private-user-images.githubusercontent.com/59105078/421150741-1a74af21-979d-4863-afd8-b211cddaa50a.gif?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NDE2NjY1NDksIm5iZiI6MTc0MTY2NjI0OSwicGF0aCI6Ii81OTEwNTA3OC80MjExNTA3NDEtMWE3NGFmMjEtOTc5ZC00ODYzLWFmZDgtYjIxMWNkZGFhNTBhLmdpZj9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAzMTElMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMzExVDA0MTA0OVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWQyNDYzOGVkZTc1YTQ4MGM3M2MxOGRjZGM4ZmNjNjVmZTJhOTVkZDVhMGMwZjRjOTRlZWYxNjAxYmI5MDkzZDUmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.AlKLN0Dg3PWweW0qAkHLWb3lzzjdakY57MgQ9mxzFXI)
    
   [ ](https://private-user-images.githubusercontent.com/59105078/421150741-1a74af21-979d-4863-afd8-b211cddaa50a.gif?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NDE2NjY1NDksIm5iZiI6MTc0MTY2NjI0OSwicGF0aCI6Ii81OTEwNTA3OC80MjExNTA3NDEtMWE3NGFmMjEtOTc5ZC00ODYzLWFmZDgtYjIxMWNkZGFhNTBhLmdpZj9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAzMTElMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMzExVDA0MTA0OVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWQyNDYzOGVkZTc1YTQ4MGM3M2MxOGRjZGM4ZmNjNjVmZTJhOTVkZDVhMGMwZjRjOTRlZWYxNjAxYmI5MDkzZDUmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.AlKLN0Dg3PWweW0qAkHLWb3lzzjdakY57MgQ9mxzFXI)

用自定义节点的话,拓扑关系又不好建立,头大
创建电线,拖动鼠标绘制绘制出一条边,这个实现思路是什么

点击画布空白处创建一个临时边,你可监听鼠标在画布空白处移动的事件,或者监听鼠标在浏览器上移动的事件,前者X6原生事件有缺陷,就是你必须按下鼠标移动才能触发,然后不断通过setTarget这个函数更新坐标就行了,再次点击屏幕空白把这个点定住就行。需要固定连接桩就要用到边工具,还有一个问题就是边外部是有一个包围盒的,你的鼠标要离创建出来的边有一定的距离,或者通过一些手段把那个包围盒去掉,大概是如下
document.addEventListener("mousemove", (e) => { // 获取鼠标当前位置(客户端坐标) const mouseClientX = e.clientX; const mouseClientY = e.clientY;

    // 将鼠标位置转换为图形本地坐标
    const localPosition = this.graph.clientToLocal({
      x: mouseClientX,
      y: mouseClientY,
    });

    this.mousePosition = localPosition;

    if (this.graph.tempEdge) {
      // 尝试直接获取边的源点
      let sourcePoint;

      // 获取源信息
      const source = this.graph.tempEdge.getSource();

      // 如果源是节点和端口组合
      if (source && source.cell) {
        const sourceCell = this.graph.getCellById(source.cell);

        if (sourceCell && source.port) {
          // 尝试获取端口位置
          try {
            // 不同版本的X6可能有不同的获取端口位置的方法
            sourcePoint = sourceCell.getPortProp(source.port, "position");

            // 如果position是相对坐标,需要转换为绝对坐标
            if (
              sourcePoint &&
              typeof sourcePoint.x === "number" &&
              typeof sourcePoint.y === "number"
            ) {
              const bbox = sourceCell.getBBox();
              sourcePoint = {
                x: bbox.x + sourcePoint.x * bbox.width,
                y: bbox.y + sourcePoint.y * bbox.height,
              };
            }
          } catch (err) {
            console.warn("无法获取端口位置", err);
          }
        }

        // 如果没有获取到端口位置,就使用节点中心
        if (!sourcePoint) {
          const bbox = sourceCell.getBBox();
          sourcePoint = {
            x: bbox.x + bbox.width / 2,
            y: bbox.y + bbox.height / 2,
          };
        }
      } else if (
        typeof source === "object" &&
        "x" in source &&
        "y" in source
      ) {
        // 如果源点是坐标对象
        sourcePoint = source;
      }

      // 如果没有获取到源点,使用边的第一个点
      if (!sourcePoint) {
        try {
          const points = this.graph.tempEdge.getVertices();
          if (points && points.length > 0) {
            sourcePoint = points[0];
          }
        } catch (err) {
          console.warn("无法获取边的顶点", err);
        }
      }

      // 最后尝试使用边的位置
      if (!sourcePoint) {
        const edgeBBox = this.graph.tempEdge.getBBox();
        sourcePoint = {
          x: edgeBBox.x,
          y: edgeBBox.y,
        };
      }

      if (!sourcePoint || isNaN(sourcePoint.x) || isNaN(sourcePoint.y)) {
        console.error("无法获取有效的源点坐标");
        return;
      }

      // 全部使用本地坐标系计算角度
      const angle = Math.atan2(
        localPosition.y - sourcePoint.y,
        localPosition.x - sourcePoint.x
      );

      // 设置偏移距离
      const offset = 2;

      // 在本地坐标系中计算偏移目标位置
      const targetX = localPosition.x - Math.cos(angle) * offset;
      const targetY = localPosition.y - Math.sin(angle) * offset;

      // 设置边的终点
      this.graph.tempEdge.setTarget({
        x: targetX,
        y: targetY,
      });
    }
  });

这东西X6不支持的,或是不符合图编辑设计理念,怎么整都有缺陷

感谢提供思路

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants