import { RelationLineType, RelationType } from "@/enum"; import { ColumnRelation, ProjectInfo, RemarkInfo, TableItemType, TopicAreaInfo } from "@/type"; import { Graph } from "@antv/x6"; const dasharrayMap = { // [RelationLineType.Dashdot]: "5 5,1 5", [RelationLineType.Dash]: "5,5", [RelationLineType.Solid]: "0", [RelationLineType.Dotted]: "1,5", } export const render = (graph: Graph, project: ProjectInfo) => { const { tables, relations, topicAreas, remarkInfos } = project; // 渲染表格 const renderTable = (tableItem: TableItemType) => { graph.addNode({ shape: "table-node", x: tableItem.table.style?.x || 100, y: tableItem.table.style?.y || 100, width: project.setting.tableWidth, height: 69, id: tableItem.table.id, data: tableItem, zIndex: 3, ports: { groups: { // 字段名前连接桩 columnPort: { markup: [ { tagName: "rect", selector: "rect", }, { tagName: "circle", selector: "circle", }, ], position: { name: "absolute", args: { x: 12, y: 42, }, }, }, }, }, }); }; // 渲染主题区域 const renderTopicArea = (topicArea: TopicAreaInfo) => { graph.addNode({ shape: "topic-node", x: topicArea.style?.x || 100, y: topicArea.style?.y || 100, width: 200, height: 200, id: topicArea.id, data: topicArea, zIndex: 0, }); }; // 渲染备注 const renderRemark = (remark: RemarkInfo) => { graph?.addNode({ shape: "notice-node", x: remark.style?.x || 100, y: remark.style?.y || 100, width: 200, height: 200, id: remark.id, data: remark, zIndex: 1, }); }; // 渲染关系 const renderRelationEdge = (relation: ColumnRelation) => { // 添加关系连线 const relationEdge = graph?.addEdge({ id: relation.id, router: { name: "er", args: { offset: "center", direction: "H", }, }, connector: { name: "rounded" }, attrs: { line: { stroke: relation.style?.color || "#333", strokeWidth: relation.style?.width || 1, targetMarker: null, strokeDasharray: dasharrayMap[relation.style?.lineType as RelationLineType || RelationLineType.Solid] }, }, source: { cell: relation.primaryTable, port: relation.primaryKey + "_port2", anchor: "left", }, target: { cell: relation.foreignTable, port: relation.foreignKey + "_port2", anchor: "left", }, data: { type: "relation", }, defaultLabel: { markup: [ { tagName: "circle", selector: "bg", }, { tagName: "text", selector: "txt", }, ], attrs: { txt: { fill: "#fff", textAnchor: "middle", textVerticalAnchor: "middle", }, bg: { ref: "txt", fill: "#333", r: 10, strokeWidth: 0, }, }, }, }); if (project.setting.showRelation) { relationEdge?.appendLabel({ attrs: { txt: { text: relation.relationType === RelationType.OneToOne || relation.relationType === RelationType.OneToMany ? "1" : "n", }, bg: { fill: relation.style?.color || "#333", } }, position: { distance: 25, }, }); relationEdge?.appendLabel({ attrs: { txt: { text: relation.relationType === RelationType.OneToMany ? "n" : "1", }, bg: { fill: relation.style?.color || "#333", } }, position: { distance: -25, }, }); } }; const cells = graph.getCells(); const allIds = [ ...tables.map((table) => table.table.id), ...topicAreas.map((topicArea) => topicArea.id), ...remarkInfos.map((remark) => remark.id), ...relations.map((relation) => relation.id), ]; // 移除空数据节点 cells.forEach((cell) => { if (!allIds.includes(cell.id)) { cell.remove(); } }); tables.forEach((tableItem) => { if (!graph.getCellById(tableItem.table.id)) { renderTable(tableItem); } else { const cell = graph.getCellById(tableItem.table.id); if (cell?.isNode()) { cell.setSize(project.setting.tableWidth, cell.size().height); cell.setPosition(tableItem.table.style?.x, tableItem.table.style?.y); cell.setData(tableItem); } } }); topicAreas.forEach((topicArea) => { if (!graph.getCellById(topicArea.id)) { renderTopicArea(topicArea); } else { const cell = graph.getCellById(topicArea.id); if (cell?.isNode()) { cell.setData(topicArea); cell.setPosition(topicArea.style?.x, topicArea.style?.y); } } }); remarkInfos.forEach((remark) => { if (!graph.getCellById(remark.id)) { renderRemark(remark); } else { const cell = graph.getCellById(remark.id); if (cell?.isNode()) { cell.setData(remark); cell.setPosition(remark.style?.x, remark.style?.y); } } }); relations.forEach((relation) => { if (!graph.getCellById(relation.id)) { renderRelationEdge(relation); } else { const relationEdge = graph.getCellById(relation.id); if (relationEdge.isEdge()) { if (project.setting.showRelation) { // 更新标签 relationEdge.setLabelAt(0, { attrs: { txt: { text: relation.relationType === RelationType.OneToOne || relation.relationType === RelationType.OneToMany ? "1" : "n", }, bg: { fill: relation.style?.color || "#333", } }, position: { distance: 25, }, }); relationEdge.setLabelAt(1, { attrs: { txt: { text: relation.relationType === RelationType.OneToMany ? "n" : "1", }, bg: { fill: relation.style?.color || "#333", } }, position: { distance: -25, }, }); } else { relationEdge.setLabels([]); } relationEdge.setAttrs({ line: { stroke: relation.style?.color || "#333", strokeWidth: relation.style?.width || 1, strokeDasharray: dasharrayMap[relation.style?.lineType as RelationLineType || RelationLineType.Solid] }, }); } } }); };