ant X6高亮

先附上效果图
在这里插入图片描述
// 节点内属性的点击事件:node:port:click
graph.on(‘node:port:click’, ({ node, port }) => {
resetAllHighlights();
highlightPort(node, port, true);
highlightEdgesForPort(port, new Set());
});
// 以下为源码

<template>
  <div id="container"></div>
</template>
<script setup lang="ts">
import {onMounted} from "vue";
import { Graph, Cell, Shape } from '@antv/x6'

const LINE_HEIGHT = 24
const NODE_WIDTH = 150

Graph.registerPortLayout(
    'erPortPosition',
    (portsPositionArgs) => {
      return portsPositionArgs.map((_, index) => {
        return {
          position: {
            x: 0,
            y: (index + 1) * LINE_HEIGHT,
          },
          angle: 0,
        }
      })
    },
    true,
)

Graph.registerNode(
    'er-rect',
    {
      inherit: 'rect',
      markup: [
        {
          tagName: 'rect',
          selector: 'body',
        },
        {
          tagName: 'text',
          selector: 'label',
        },
      ],
      attrs: {
        rect: {
          strokeWidth: 1,
          stroke: '#5F95FF',
          fill: '#5F95FF',
        },
        label: {
          fontWeight: 'bold',
          fill: '#ffffff',
          fontSize: 12,
        },
      },
      ports: {
        groups: {
          list: {
            markup: [
              {
                tagName: 'rect',
                selector: 'portBody',
              },
              {
                tagName: 'text',
                selector: 'portNameLabel',
              },
              {
                tagName: 'text',
                selector: 'portTypeLabel',
              },
            ],
            attrs: {
              portBody: {
                width: NODE_WIDTH,
                height: LINE_HEIGHT,
                strokeWidth: 1,
                stroke: '#5F95FF',
                fill: '#EFF4FF',
                cursor: 'pointer',
              },
              portNameLabel: {
                ref: 'portBody',
                refX: 6,
                refY: 6,
                fontSize: 10,
              },
              portTypeLabel: {
                ref: 'portBody',
                refX: 95,
                refY: 6,
                fontSize: 10,
              },
            },
            position: 'erPortPosition',
          },
        },
      },
    },
    true,
)



onMounted(() => {
  const graph = new Graph({
    container: document.getElementById('container'),
    interacting: false, // 节点不可拖动
    connecting: {
      router: {
        name: 'er',
        args: {
          offset: 25,
          direction: 'H',
        },
      },
      createEdge() {
        return new Shape.Edge({
          attrs: {
            line: {
              stroke: '#A2B1C3',
              strokeWidth: 2,
            },
          },
        })
      },
    },
  })

  const resetAllHighlights = () => {
    const nodes = graph.getNodes(); // 获取所有nodes
    nodes.forEach((node) => {
      const ports = node.getPorts(); // 获取所有ports
      ports.forEach((port) => {
        node.portProp(port.id, 'attrs/portBody/fill', '#EFF4FF');
        node.portProp(port.id, 'attrs/portNameLabel/fill', '#000000');
        node.portProp(port.id, 'attrs/portTypeLabel/fill', '#000000');
      });
    });

    const edges = graph.getEdges();
    edges.forEach((edge) => {
      edge.attr('line/stroke', '#A2B1C3');
      edge.attr('line/strokeWidth', 2);
    });
  };

  const highlightPort = (node: Cell, portId: string, highlight: boolean) => {
    if (highlight) {
      node.portProp(portId, 'attrs/portBody/fill', 'yellow');
      node.portProp(portId, 'attrs/portNameLabel/fill', 'red');
      node.portProp(portId, 'attrs/portTypeLabel/fill', 'red');
    } else {
      node.portProp(portId, 'attrs/portBody/fill', '#EFF4FF');
      node.portProp(portId, 'attrs/portNameLabel/fill', '#000000');
      node.portProp(portId, 'attrs/portTypeLabel/fill', '#000000');
    }
  };

  const highlightEdgesForPort = (portId: string, visitedPorts: Set<string>) => {
    if (visitedPorts.has(portId)) return;
    visitedPorts.add(portId);

    const edges = graph.getEdges();
    edges.forEach((edge) => {
      const sourcePortId = edge.getSourcePortId();
      const targetPortId = edge.getTargetPortId();
      if (sourcePortId === portId || targetPortId === portId) {
        edge.attr('line/stroke', 'red');
        edge.attr('line/strokeWidth', 2);

        const sourceNode = edge.getSourceNode();
        const targetNode = edge.getTargetNode();
        // 递归
        if (sourcePortId === portId && targetNode) {
          highlightPort(targetNode, targetPortId, true);
          highlightEdgesForPort(targetPortId, visitedPorts); // Recursively highlight connected ports
        } else if (targetPortId === portId && sourceNode) {
          highlightPort(sourceNode, sourcePortId, true);
          highlightEdgesForPort(sourcePortId, visitedPorts); // Recursively highlight connected ports
        }
      }
    });
  };

  graph.on('node:port:click', ({ node, port }) => {
    resetAllHighlights();
    highlightPort(node, port, true);
    highlightEdgesForPort(port, new Set());
  });



  const data = [
    {
      "id": "1",
      "shape": "er-rect",
      "label": "学生",
      "width": 150,
      "height": 24,
      "position": {
        "x": 24,
        "y": 150
      },
      "ports": [
        {
          "id": "1-1",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "ID"
            },
            "portTypeLabel": {
              "text": "STRING"
            }
          }
        },
        {
          "id": "1-2",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "Name"
            },
            "portTypeLabel": {
              "text": "STRING"
            }
          }
        },
        {
          "id": "1-3",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "Class"
            },
            "portTypeLabel": {
              "text": "NUMBER"
            }
          }
        },
        {
          "id": "1-4",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "Gender"
            },
            "portTypeLabel": {
              "text": "BOOLEAN"
            }
          }
        }
      ]
    },
    {
      "id": "2",
      "shape": "er-rect",
      "label": "课程",
      "width": 150,
      "height": 24,
      "position": {
        "x": 250,
        "y": 210
      },
      "ports": [
        {
          "id": "2-1",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "ID"
            },
            "portTypeLabel": {
              "text": "STRING"
            }
          }
        },
        {
          "id": "2-2",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "Name"
            },
            "portTypeLabel": {
              "text": "STRING"
            }
          }
        },
        {
          "id": "2-3",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "StudentID"
            },
            "portTypeLabel": {
              "text": "STRING"
            }
          }
        },
        {
          "id": "2-4",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "TeacherID"
            },
            "portTypeLabel": {
              "text": "STRING"
            }
          }
        },
        {
          "id": "2-5",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "Description"
            },
            "portTypeLabel": {
              "text": "STRING"
            }
          }
        }
      ]
    },
    {
      "id": "3",
      "shape": "er-rect",
      "label": "老师",
      "width": 150,
      "height": 24,
      "position": {
        "x": 480,
        "y": 350
      },
      "ports": [
        {
          "id": "3-1",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "ID"
            },
            "portTypeLabel": {
              "text": "STRING"
            }
          }
        },
        {
          "id": "3-2",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "Name"
            },
            "portTypeLabel": {
              "text": "STRING"
            }
          }
        },
        {
          "id": "3-3",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "Age"
            },
            "portTypeLabel": {
              "text": "NUMBER"
            }
          }
        }
      ]
    },
    {
      "id": "4",
      "shape": "edge",
      "source": {
        "cell": "1",
        "port": "1-1"
      },
      "target": {
        "cell": "2",
        "port": "2-4"
      },
      "attrs": {
        "line": {
          "stroke": "#A2B1C3",
          "strokeWidth": 2
        }
      },
      "zIndex": 0
    },
    {
      "id": "5",
      "shape": "edge",
      "source": {
        "cell": "2",
        "port": "2-4"
      },
      "target": {
        "cell": "3",
        "port": "3-1"
      },
      "attrs": {
        "line": {
          "stroke": "#A2B1C3",
          "strokeWidth": 2
        }
      },
      "zIndex": 0
    },

    {
      "id": "6",
      "shape": "edge",
      "source": {
        "cell": "1",
        "port": "1-2"
      },
      "target": {
        "cell": "2",
        "port": "2-2"
      },
      "attrs": {
        "line": {
          "stroke": "#A2B1C3",
          "strokeWidth": 2
        }
      },
      "zIndex": 0
    },
  ]

  const cells: Cell[] = []
  data.forEach((item: any) => {
    if (item.shape === 'edge') {
      cells.push(graph.createEdge(item))
    } else {
      cells.push(graph.createNode(item))
    }
  })
  graph.resetCells(cells)
  graph.zoomToFit({ padding: 10, maxScale: 1 })


})
</script>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/674983.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Win11下只支持IE浏览器的老网站顺畅运行的方法

在Windows 11操作系统中&#xff0c;由于Internet Explorer&#xff08;IE&#xff09;浏览器的逐步淘汰&#xff0c;微软官方已不再直接支持IE浏览器。然而&#xff0c;当您遇到必须访问仅支持IE的老旧网站时&#xff0c;Windows 11仍然提供了一些实用的替代方案来应对这一挑战…

GA/T 1400视频汇聚平台EasyCVR级联后,平台显示无通道是什么原因?

国标GB28181安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台部署轻快&#xff0c;可支持的主流标准协议有GA/T 1400、国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。 有用户反馈&#xff…

【python】OpenCV—Bitplane

学习来自&#xff1a; 位平面分割&#xff08;Bit-Plane Slicing&#xff09;使用OpenCVPython进行图像处理的初学者指南 位平面 位平面&#xff08;bitplane&#xff09;是一个在计算机科学中用于描述图像数据的概念&#xff0c;具体定义如下&#xff1a; 【定义】&#x…

22、matlab锯齿波、三角波、方波:rectpuls()函数/sawtooth()函数/square()函数

1、采样的非周期性矩形 语法 语法1&#xff1a;y rectpuls(t) 返回一个以数组 t 中指示的采样时间采样的连续非周期性单位高度矩形脉冲&#xff0c;该矩形脉冲以 t 0 为中心。 语法2&#xff1a;y rectpuls(t,w) 生成一个宽度为 w 的矩形 参数 t:采样时间 w:矩形宽度…

网络编程(五)

网络编程&#xff08;五&#xff09; 网络服务器超时检测使用select进行超时检测套接字属性**getsockopt:获取socket软通道的某项属性值**setsockopt:设置socket软通道的某项属性值**&#xff08;socket建立之后就可使用&#xff09; 信号**signal()&#xff1a;信号处理函数se…

34. 【Java教程】反射

本小节我们来学习一个 Java 语言中较为深入的概念 —— 反射&#xff08;reflection&#xff09;&#xff0c;很多小伙伴即便参与了工作&#xff0c;可能也极少用到 Java 反射机制&#xff0c;但是如果你想要开发一个 web 框架&#xff0c;反射是不可或缺的知识点。本小节我们将…

天诚学校物联网锁、公租房智能门锁亮相2024永康门博会

5月26-28日&#xff0c;全场景AIoT解决方案服务商——江苏新巢天诚智能技术有限公司&#xff08;以下简称“天诚”&#xff09;盛装出席第14届中国&#xff08;永康&#xff09;国际门业博览会&#xff08;以下简称“门博会”&#xff09;。 门博会亮点十足 作为享誉海内外的…

产品评测:Coolmuster Android Eraser - 安全彻底删除Android数据的利器

产品概述 在数字化时代&#xff0c;智能手机成为了个人敏感信息的集中地。当涉及到数据隐私和安全时&#xff0c;简单的删除操作并不能满足我们对数据彻底清除的需求。Coolmuster Android Eraser正是为了解决这一问题而生&#xff0c;它是一款专为Android设备设计的第三方软件&…

VUE封装-自定义权限控制指令

在实际开发中&#xff0c;会遇到很多的权限控制、资源位的场景&#xff0c;其实就是用来控制某个组件的展示与否&#xff0c;可以是一个按钮、一个报表、一个TAB页面等 例如下图&#xff0c;我想通过当前登录的用户控制谷歌的这个logo显示与否 因为设计到的权限、资源位控制比…

图片中线段和圆圈检测(python opencv)

前言 本文实现将一个图片中的线段和圆圈检测出来&#xff0c;效果就像这样 开始之前请先自行安装 opencv 另外还用到了一个用来检测直线&#xff1a; http://olena.pages.lre.epita.fr/pylena/index.html pip install pylena直线检测 先用 opencv 来检测直线, 因为下面代码…

天融信 2023 的年终奖。。

天融信 过去几天&#xff0c;最大的瓜&#xff0c;是天融信 2023 的年终奖脚踝砍。 "天融信"是国内首家网络安全企业&#xff0c;同时也是一家上市公司。 就在前些天&#xff0c;有网友爆料出&#xff0c;天融信年终奖到账只有几百元&#xff0c;甚至只有几十元&…

铝包木门窗性能优异 国内产量及需求量总体呈增长态势

铝包木门窗性能优异 国内产量及需求量总体呈增长态势 铝包木门窗是在保留纯实木门窗特性和功能的前提下&#xff0c;将隔热断桥铝合金型材和实木通过机械方法复合而成的框体。铝包木门窗具有良好的密封性、保温性、抗腐蚀性、隔音性等&#xff0c;能够满足市场对门窗质量要求不…

【Linux-阻塞,非阻塞,异步】

Linux-阻塞&#xff0c;非阻塞&#xff0c;异步 ■ Linux-阻塞-非阻塞 IO-异步■ Linux-阻塞IO■ 阻塞IO简介■ open■ 等待队列■ 示例一&#xff1a;APP阻塞IO读取进入睡眠后-等待队列唤醒进程■■ ■ Linux-非阻塞IO■ 非阻塞IO简介■ open■ 轮询■ 1、select 函数■ 2、po…

【轻触按键】开关机电路--填坑1

接上文&#xff0c;挖的坑 一、翻转电路 二、真值表 按键按下去&#xff0c;1G17会拉低&#xff0c;A端脚会掉电&#xff0c;下降沿&#xff1b;终到逻辑“0” 松开按键&#xff0c;1G17会拉高&#xff0c;A端脚充电&#xff0c;上升沿&#xff1b;终到逻辑“1”&#xff1b; …

[补题记录]LeetCode 6.Z字形变换

传送门&#xff1a;Z字形变换 转自&#xff1a;Z字形变换 Thought/思路 关键点在于&#xff0c;最后的答案是一行行连接起来的。 这样我们就会发现&#xff0c;这个 Z 字&#xff0c;实际上会让行数 不断加 1&#xff0c;然后又 不断减 1。每次按顺序选择 S 中的一个字符即…

visual studio打包qt算子时,只生成dll没有生成lib等文件

问题&#xff1a;在visual studio配置了qt项目&#xff0c;并打包成dll&#xff0c;原则上会生成一堆文件&#xff0c;包括dll,lib等文件。 解决办法&#xff1a; 挨个右击源代码的所有头文件-》属性-》项类型。改成qt头文件形式&#xff0c;如下。

961题库 北航计算机 计算机网络 附答案 简答题形式

有题目和答案&#xff0c;没有解析&#xff0c;不懂的题问大模型即可&#xff0c;无偿分享。 第1组 习题 某网络拓扑如题下图所示&#xff0c;其中 R 为路由器&#xff0c;主机 H1&#xff5e;H4 的 IP 地址配置以及 R 的各接口 IP 地址配置如图中所示。现有若干以太网交换机…

C#中使用Mapster

Mapster是一个开源的.NET对象映射库&#xff0c;它提供了一种简单而强大的方式来处理对象之间的映射。 多个映射框架的性能对比&#xff1a; 第一步安装Mapster 使用方法 public class Test {public string name { get; set; }public string sex { get; set; }public string…

光伏并网逆变器UL 1741:2021标准解析

光伏并网逆变器UL 1741:2021标准解析 不同国家的安规认证可以说是光伏逆变器走向国际市场的一张通行证&#xff0c;由于全球各国家的电网制式及并网政策的不同差异&#xff0c;这对逆变器测试顺利的通过安规测试认证 还是有一定的技术难度&#xff0c;也是中国光伏制造企业迫切…

在Linux中tomcat占用内存过高可以通过导出hprof日志来解决

自动导出hprof日志 第一种方法&#xff1a; Tomcat的hprof日志是一种用于分析Java堆内存使用情况的工具&#xff0c;它可以帮助开发人员找到内存泄漏的原因。 hprof日志可以在特定的时间点对Java堆内存进行快照&#xff0c;并生成详细的分析报告。 启用hprof日志导出的具体…