import React, { useEffect, useMemo, useRef } from "react"; import { register } from "@antv/x6-react-shape"; import { Edge, Graph, Node } from "@antv/x6"; import type { ColumnItem, TableItemType } from "@/type"; import { DATA_TYPE_OPTIONS } from "@/constants"; import { uuid } from "@/utils"; function TableNode({ node, graph }: { node: Node; graph: Graph }) { const { table, tableColumnList } = node.getData(); const containerRef = useRef(null); useEffect(() => { const container = containerRef.current; if (container?.clientHeight) { node.setSize(container.clientWidth, container.clientHeight); } }, [tableColumnList.length]); const hasListener = useRef(false); const relationSource = useRef(); useEffect(() => { if (!hasListener.current) { hasListener.current = true; // 参考线添加完成 graph.on("edge:added", (args) => { if (args.edge.data?.type === "refer") { relationSource.current = args.edge.source; } }); // 参考线移除 graph.on("edge:removed", (args) => { if (args.edge.data?.type === "refer") { relationSource.current = undefined; } }); graph.on("edge:connected", (args) => { // 连接完成后删除refer类型的连线 if (args.edge.data?.type === "refer") { graph.removeEdge(args.edge); const target: any = args.edge.target; const source: any = args.edge.source; if (target?.cell === node.id && target?.port?.includes("port1")) { node.prop("add:relation", { source: { tableId: source?.cell, columnId: source?.port?.slice( 0, source?.port?.indexOf("_port") ), }, target: { tableId: node.id, columnId: target.port.slice(0, target.port.indexOf("_port")), }, }); } } }); } }, []); // 连接桩,1用于开始连接拖拽,2用于关系连线连接 useEffect(() => { const ports = node.getPorts(); ports?.forEach((item) => { if (!tableColumnList.find((column) => item.id?.includes(column.id))) { node.removePort(item); } }); tableColumnList.forEach((item, index) => { if (!ports.find((port) => port.id?.includes(item.id))) { node.addPort({ id: item.id + "_port1", group: "columnPort", args: { y: 42 + 16 + index * 27, }, attrs: { circle: { r: 4, magnet: true, stroke: "#31d0c6", strokeWidth: 2, fill: "#fff", }, }, zIndex: 5, }); node.addPort({ id: item.id + "_port2", group: "columnPort", args: { x: 0, y: 42 + index * 27, }, attrs: { rect: { magnet: true, fill: "rgba(255,255,255,0)", strokeWidth: 0, width: node.size().width, height: 27, }, }, zIndex: 0, }); } }); }, [tableColumnList]); // 触发添加关系操作 // 字段位置鼠标抬起,判断有没有开始连线操作 const handleColumnMouseUp = (record: ColumnItem) => { if (relationSource.current) { node.prop("add:relation", { source: { tableId: relationSource.current?.cell, columnId: relationSource.current?.port.slice( 0, relationSource.current.port.indexOf("_port") ), }, target: { tableId: node.id, columnId: record.id, }, }); } }; const ColumnItem = ({ record }: { record: ColumnItem }) => { const type = DATA_TYPE_OPTIONS.find((item) => item.value === record.type); return (
handleColumnMouseUp(record)} > {record.schemaName} {record.cn_name ? `(${record.cn_name})` : ""} {record.isUnique ? ( P F ) : ( )} {type?.label}
); }; return (
{table.schemaName}({table.cn_name})
{tableColumnList.map((item) => { return ; })}
); } register({ shape: "table-node", component: TableNode, width: 300, height: 220, effect: ["data"], });