React Antd Pro + antv/X6实现ER图

采用React FunctionComponent 方法返回
路由导入该路径
使用官方例子

import React, { useEffect, useRef } from 'react';
import { Cell, Graph, Shape } from '@antv/x6';

const LINE_HEIGHT = 24;
const NODE_WIDTH = 150;

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-3"
        },
        "attrs": {
            "line": {
                "stroke": "#A2B1C3",
                "strokeWidth": 2
            }
        },
        "zIndex": 0
    },
    {
        "id": "5",
        "shape": "edge",
        "source": {
            "cell": "3",
            "port": "3-1"
        },
        "target": {
            "cell": "2",
            "port": "2-4"
        },
        "attrs": {
            "line": {
                "stroke": "#A2B1C3",
                "strokeWidth": 2
            }
        },
        "zIndex": 0
    }
]

const ERRenderer: React.FC = () => {
    const containerRef = useRef<HTMLDivElement>(null);

    useEffect(() => {
        if (containerRef.current) {

            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',
                                        magnet: true,
                                    },
                                    portNameLabel: {
                                        ref: 'portBody',
                                        refX: 6,
                                        refY: 6,
                                        fontSize: 10,
                                    },
                                    portTypeLabel: {
                                        ref: 'portBody',
                                        refX: 95,
                                        refY: 6,
                                        fontSize: 10,
                                    },
                                },
                                position: 'erPortPosition',
                            },
                        },
                    },
                },
                true,
            );
            const graph = new Graph({
                container: containerRef.current!,
                connecting: {
                    router: {
                        name: 'er',
                        args: {
                            offset: 25,
                            direction: 'H',
                        },
                    },
                    createEdge() {
                        return new Shape.Edge({
                            attrs: {
                                line: {
                                    stroke: '#A2B1C3',
                                    strokeWidth: 2,
                                },
                            },
                        });
                    },
                },
            });
            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 });
        }
    }, []);

    return <div ref={containerRef} style={{ width: '100%', height: '100%', border: '1px solid #ccc' }} />;
};

export default ERRenderer;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值