antv g6 demo

72 阅读2分钟
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Flowchart Editor</title>
    <style>
        #app {
            display: flex;
            width: 100%;
            height: 100%;
        }

        .left {
            flex: 1;
            border: 1px solid #ddd;
            padding: 10px;
        }

        .left-item {
            cursor: pointer;
            padding: 5px;
            border: 1px solid #ddd;
            margin-bottom: 5px;
        }

        .right {
            flex: 3;
            border: 1px solid #ddd;
        }

        /* 添加模态框的样式 */
        .modal {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-color: rgba(0, 0, 0, 0.5);
            display: flex;
            justify-content: center;
            align-items: center;
            z-index: 1000;
        }

    </style>
</head>

<body>
    <div id="app">
        <div class="left">
            <div class="left-item" v-for="item in tasklist" 
                @click="addNode(item)"
                @mouseover="handleMouseOver"
                
            >
                {{ item.name }}
            </div>
        </div>
        <div class="right" id="graph-container"></div>
        <!-- 在 #app 内部添加模态框的 HTML 结构 -->
        <div v-if="showModal" class="modal" @click="showModal = false">
            <p>模态框内容</p>
            <button @click.stop="goToOtherPage">前往其他页面</button>
        </div>

    </div>
    

    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    <script src="https://gw.alipayobjects.com/os/lib/antv/g6/4.3.7/dist/g6.min.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
                tasklist: [
                    { id: 1, name: 'Start', color: 'orange' },
                    { id: 2, name: 'Process', color: 'green' },
                    { id: 3, name: 'End', color: 'yellow' }
                ],
                graph: null,
                selectedNode: null,
                nodeArr: [],
                nodeRelation: [],

                showModal: false,
                modalTimeout: null,
            },
            mounted() {
                this.initGraph();
            },
            methods: {
                handleMouseOver() {
                    // 在两秒后显示模态框
                    this.modalTimeout = setTimeout(() => {
                        this.showModal = true;
                    }, 2000);
                },
                goToOtherPage() {
                    location.href = '/paint3'; // 替换为目标页面的 URL
                },
                initGraph() {
                    this.graph = new G6.Graph({
                        container: 'graph-container',
                        width: 1100,
                        height: 600,
                        modes: {
                            default: ['drag-node', 'drag-canvas']
                        },
                        defaultNode: {
                            type: 'rect', // 设置节点类型为长方形
                            style: {
                                lineWidth: 2,
                                stroke: '#5B8FF9',
                                fill: '#C6E5FF'
                            }
                        },
                        defaultEdge: {
                            style: {
                                endArrow: {
                                    path: G6.Arrow.triangle(10, 20, 0), 
                                    fill: 'green',
                                    offset: -1 // 将箭头向后移动一点,使其更靠近节点
                                },
                                lineWidth: 3, // 设置边的宽度
                                stroke: 'green'
                            }
                        },
                    });
                    this.graph.on('node:click', evt => {
                        const clickedNode = evt.item;
                        if (this.selectedNode && this.selectedNode !== clickedNode) {
                            const sourceId = this.selectedNode.get('id');
                            const targetId = clickedNode.get('id');
                            const sourceLabel = this.selectedNode.getModel().label;
                            const targetLabel = clickedNode.getModel().label;
                            // 检查新边是否会形成闭环
                            if (!this.doesEdgeCreateLoop(sourceId, targetId)) {
                                this.graph.addItem('edge', {
                                    source: sourceId,
                                    target: targetId,
                                    style: {
                                        endArrow: {
                                            path: G6.Arrow.triangle(10, 20, 5),
                                            fill: 'green'
                                        }
                                    }
                                });
                                // 添加边关系到 nodeRelation
                                this.nodeRelation.push(`${sourceLabel}>>${targetLabel}`); 
                                console.log(this.nodeRelation,'this.nodeRelation--add')
                                // 添加node到 nodeArr
                                if (!this.nodeArr.includes(sourceLabel)) {
                                    this.nodeArr.push(sourceLabel);
                                }
                                if (!this.nodeArr.includes(targetLabel)) {
                                    this.nodeArr.push(targetLabel);
                                }
                                console.log(this.nodeArr,'this.nodeArr--add')
                            }
                            this.selectedNode = null;
                        } else {
                            this.selectedNode = clickedNode;
                        }
                    });
                    this.graph.on('edge:click', (evt) => {
                        const edge = evt.item;
                        const sourceLabel = edge.getSource().getModel().label;
                        const targetLabel = edge.getTarget().getModel().label;

                        // 从 nodeRelation 中删除边
                        const edgeIndex = this.nodeRelation.indexOf(`${sourceLabel}>>${targetLabel}`);
                        if (edgeIndex > -1) {
                            this.nodeRelation.splice(edgeIndex, 1);
                        }

                        // 从 nodeArr 中删除不再参与连线的节点
                        [sourceLabel, targetLabel].forEach(label => {
                            if (!this.nodeRelation.some(rel => rel.includes(label))) {
                                const nodeIndex = this.nodeArr.indexOf(label);
                                if (nodeIndex > -1) {
                                    this.nodeArr.splice(nodeIndex, 1);
                                }
                            }
                        });
                        console.log(this.nodeRelation,'this.nodeRelation--del')
                        console.log(this.nodeArr,'this.nodeArr---del')

                        // 删除边
                        this.graph.removeItem(edge);
                    });

                },
                
                addNode(item) {
                    if (this.graph.findById(`node-${item.id}`)) return;
                    console.log(item.id,'node-id-------')
                    const model = {
                        id: `node-${item.id}`,
                        label: item.name,
                        x: Math.random() * 800,
                        y: Math.random() * 600,
                        style: {
                            fill: item.color, // 设置节点颜色与左侧被点击的节点颜色一致
                            stroke: item.color
                        }
                    };
                    this.graph.addItem('node', model);
                },
                doesEdgeCreateLoop(sourceId, targetId) {
                    const visited = new Set();
                    let hasLoop = false;

                    const dfs = (nodeId) => {
                        if (nodeId === sourceId) {
                            hasLoop = true;
                            return;
                        }
                        if (visited.has(nodeId)) {
                            return;
                        }
                        visited.add(nodeId);

                        const edges = this.graph.getEdges();
                        edges.forEach(edge => {
                            if (edge.getSource().getID() === nodeId) {
                                const nextNodeId = edge.getTarget().getID();
                                if (!visited.has(nextNodeId)) {
                                    dfs(nextNodeId);
                                }
                            }
                        });
                    };

                    dfs(targetId);
                    return hasLoop;
                }

            }
        });
    </script>
</body>

</html>