antv g6 demo2

83 阅读3分钟
<!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;
        }
    </style>
</head>

<body>
    <div id="app">
        <div class="left">
            <div class="left-item" v-for="item in tasklist" @click="addNode(item)">
                {{ item.name }}
            </div>
        </div>
        <div class="right" id="graph-container"></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: 'Start1111111111111111', name: 'Start1111111111111111', color: 'orange' },
                    { id: 'Process2222222222222', name: 'Process2222222222222', color: 'green' },
                    { id: 'End33333333333333333333', name: 'End33333333333333333333', color: 'yellow' },
                    { id: 'Java_144444444444444444444', name: 'Java_144444444444444444444', color: 'blue' },
                    { id: 'Java_255555555555555555555', name: 'Java_255555555555555555555', color: 'blue' },
                ],
                graph: null,
                javaNodeEdges: {}, // 记录 Java_ 节点出边状态
            },
            mounted() {
                this.initGraph();
            },
            methods: {
                initGraph() {
                    this.graph = new G6.Graph({
                        container: 'graph-container',
                        width: 1100,
                        height: 600,
                        modes: {
                            default: [
                                'drag-node', 
                                'drag-canvas', 
                                'zoom-canvas', 
                                {
                                    type: 'create-edge',
                                    key: 'shift',  // 配置创建边的按键为 Shift 键
                                    trigger: 'drag'  // 修改为拖拽触发创建边
                                }
                            ]
                        },
                        defaultNode: {
                            type: 'circle',
                            size: [60],
                            style: {
                                fill: '#9FD7FF',
                                stroke: '#5B8FF9',
                            },
                            labelCfg: {
                                position: 'center',
                                style: {
                                    textAlign: 'center',
                                    textBaseline: 'middle',
                                    fill: '#000',
                                    fontSize: 12
                                }
                            }
                        },
                        defaultEdge: {
                            style: {
                                lineWidth: 2,
                                lineAppendWidth: 5,
                                stroke: '#BDBEBF',
                                endArrow: {
                                    path: G6.Arrow.triangle(5, 5, 5), // 自定义边的箭头样式
                                    fill: '#BDBEBF',
                                },
                            },
                        },
                    });

                    // 监听节点按下事件,判断是否按下 Shift 键来锁定节点
                    this.graph.on('node:mousedown', (evt) => {
                        const mouseEvent = evt.originalEvent;
                        if (mouseEvent.shiftKey) {
                            evt.item.lock(); // 锁定节点
                        }
                    });

                    // 监听节点抬起事件,判断是否按下 Shift 键来解锁节点
                    this.graph.on('node:mouseup', (evt) => {
                        const mouseEvent = evt.originalEvent;
                        if (mouseEvent.shiftKey) {
                            evt.item.unlock(); // 解锁节点
                        }
                    });

                    // 监听边创建完成后的事件回调
                    this.graph.on('aftercreateedge', (evt) => {
                        const edge = evt.edge;
                        const sourceNode = edge.getSource();
                        const sourceLabel = sourceNode.getModel().label;

                        if (sourceLabel.startsWith('Java_')) {
                            const sourceId = sourceNode.get('id');

                            // 初始化 Java_ 节点的出边状态
                            if (!this.javaNodeEdges[sourceId]) {
                                this.javaNodeEdges[sourceId] = { count: 0, lastColor: null };
                            }

                            const edgeData = this.javaNodeEdges[sourceId];
                            if (edgeData.count >= 2) {
                                alert('Java_开头节点只能有两条出边');
                                this.graph.removeItem(edge);
                                return;
                            }

                            // 检查当前是否有剩余连线以及其颜色
                            const remainingEdges = this.graph.getEdges().filter((e) => e.getSource().getID() === sourceId);
                            let edgeColor = 'green'; // 默认绿色
                            if (remainingEdges.some((e) => e.getModel().style.stroke === 'green')) {
                                edgeColor = 'red'; // 如果有绿色边,下一条为红色
                            }

                            this.graph.updateItem(edge, {
                                style: { stroke: edgeColor },
                            });

                            // 更新出边状态
                            edgeData.count += 1;
                            edgeData.lastColor = edgeColor;
                        }
                    });

                    // 监听双击事件删除节点和连线
                    this.graph.on('node:dblclick', (evt) => {
                        const node = evt.item;
                        const nodeId = node.get('id');

                        // 获取所有与此节点相关的连线
                        const relatedEdges = this.graph.findAll('edge', (edge) => edge.getSource().getID() === nodeId || edge.getTarget().getID() === nodeId);

                        relatedEdges.forEach(edge => {
                            const sourceNode = edge.getSource();
                            const sourceId = sourceNode.get('id');

                            if (sourceNode.getModel().label.startsWith('Java_') && this.javaNodeEdges[sourceId]) {
                                this.javaNodeEdges[sourceId].count -= 1;

                                if (this.javaNodeEdges[sourceId].count === 0) {
                                    this.javaNodeEdges[sourceId].lastColor = null;
                                } else {
                                    const remainingEdges = this.graph.getEdges().filter((e) => e.getSource().getID() === sourceId);
                                    if (remainingEdges.some((e) => e.getModel().style.stroke === 'green')) {
                                        this.javaNodeEdges[sourceId].lastColor = 'green';
                                    } else {
                                        this.javaNodeEdges[sourceId].lastColor = 'red';
                                    }
                                }

                                this.graph.removeItem(edge);
                            }
                        });

                        this.graph.removeItem(node);

                        if (this.javaNodeEdges[nodeId]) {
                            delete this.javaNodeEdges[nodeId];
                        }
                    });

                    this.graph.on('edge:dblclick', (evt) => {
                        const edge = evt.item;
                        const sourceNode = edge.getSource();
                        const sourceId = sourceNode.get('id');

                        if (sourceNode.getModel().label.startsWith('Java_') && this.javaNodeEdges[sourceId]) {
                            const edgeColor = edge.getModel().style.stroke;
                            if (edgeColor === 'red') {
                                this.javaNodeEdges[sourceId].lastColor = 'red';
                            } else if (edgeColor === 'green') {
                                this.javaNodeEdges[sourceId].lastColor = 'green';
                            }

                            this.javaNodeEdges[sourceId].count -= 1;

                            const remainingEdges = this.graph.getEdges().filter((e) => e.getSource().getID() === sourceId);
                            if (remainingEdges.some((e) => e.getModel().style.stroke === 'green')) {
                                this.javaNodeEdges[sourceId].lastColor = 'green';
                            } else {
                                this.javaNodeEdges[sourceId].lastColor = 'red';
                            }
                        }

                        this.graph.removeItem(edge);
                    });
                },

                addNode(item) {
                    if (this.graph.findById(item.name)) return;

                    // 处理文本长度,超出部分添加省略号
                    const MAX_LENGTH = 10;
                    const label = item.name.length > MAX_LENGTH ? item.name.substring(0, MAX_LENGTH) + '...' : item.name;

                    // 获取画布的中心坐标
                    const graphWidth = this.graph.get('width');
                    const graphHeight = this.graph.get('height');
                    const centerX = graphWidth / 2;
                    const centerY = graphHeight / 2;

                    // 轻微偏移量,防止节点完全重叠
                    const offset = Math.random() * 50; // 随机生成一个偏移量

                    this.graph.addItem('node', {
                        id: item.name,
                        label: label,
                        color: item.color,
                        x: centerX , // 添加偏移量
                        y: centerY ,
                    });
                },
            }
        });
    </script>
</body>

</html>