antv/g6之交互模式mode

什么是mode

在 AntV G6 中,"mode" 是用于配置图表交互模式的一种属性。通过设置 "mode",可以控制图表的行为,以满足不同的交互需求。可能在不同的场景需要展现的交互行为不一样。比如查看模式下点击一个点就选中的状态,在编辑的情况下点击点可以出现编辑框,在创建边的情况下点击点就是创建一个边的起点。mode正是管理这些behavior的一种机制,一个图上可以存在多种交互模式,每个交互模式的behavior不一样。

配置 mode

在 AntV G6 中配置不同的 "mode" 可以通过在图表实例的配置中指定 "modes" 参数来实现。以下是一个示例,演示如何配置不同的 "mode":

javascript 复制代码
const graph = new G6.Graph({
  container: 'your-container', // 指定容器
  width: 800, // 指定宽度
  height: 600, // 指定高度
  modes: {
    default: ['drag-node', 'zoom-canvas', 'drag-canvas'], // 默认模式下启用的交互模式
    addEdge: ['create-edge', 'zoom-canvas', 'drag-canvas'], // 建模式
    edit: ['click-select'], // 编辑模式
  },
  // 其他配置...
});

在上述示例中,创建了一个名为 "graph" 的 G6 图表实例,并在 "modes" 参数中配置了不同的模式。可以根据需要在不同的模式下启用或禁用不同的交互操作。每个模式的值是一个包含可用的交互模式的数组。

如何切换

  1. 使用 graph.setMode(modeName) 方法 :可以通过调用 setMode 方法来切换图表的模式。传递模式的名称作为参数,这将启用相应的交互模式。例如:
javascript 复制代码
// 切换到默认模式
graph.setMode('default');

// 切换到编辑模式
graph.setMode('edit');

// 切换到建边模式
graph.setMode('addEdge');

可以根据用户的需求和操作来动态切换不同的模式,以提供不同的图表交互体验。

编辑已有的mode

g6也提供了removeBehaviors、addBehaviors、updateBehavior api来编辑mode,可以删除、添加、或修改某个mode中的交互行为。

javascript 复制代码
// 向 default 模式中添加名为 drag-canvas 的行为,并使用行为的默认配置
graph.addBehaviors('drag-canvas', 'default');

// 从 default 模式中移除名为 drag-canvas 的行为
graph.removeBehaviors('drag-canvas', 'default');

// 向 edit 模式中添加名为 drag-canvas 的行为,并定义个性化配置
graph.addBehaviors(
  {
    type: 'drag-canvas',
    direction: 'x',
  },
  'edit',
);

// 更新 'edit' 模式下的 behavior 'click-select'
graph.updateBehavior('click-select', { trigger: 'ctrl' }, 'edit');

示例

定义了三个模式,然后根据按钮点击切换不同的模式

  1. 默认模式下,可以拖拽图、拖拽点、缩放图。
  2. 编辑模式下就有个点击选中的效果。
  3. 创建边的模式,点击两个点创建新边。

代码如下:

javascript 复制代码
import React, { useEffect, useRef } from "react";
import G6 from "@antv/g6";
import { Button } from "antd";


const TestModes: React.FC<any> = (props: any) => {
    const containerRef = useRef<HTMLDivElement>(null);
    const graphRef = useRef<any>();

    useEffect(() => {
        initDraw();
    }, []);

    const initDraw = () => {
        graphRef.current = new G6.Graph({
            linkCenter: true,
            container: containerRef.current || "",
            height: 800,
            width: 800,
            modes: {
                default: ['drag-node', 'zoom-canvas', 'drag-canvas'], // 默认模式下启用的交互模式
                addEdge: ['create-edge', 'zoom-canvas', 'drag-canvas'], // 建模式
                edit: ['click-select'], // 编辑模式
            },
            defaultNode: {
                size: 20,
                style: {
                    fill: "#C6E5FF",
                    stroke: "#5B8FF9",
                    lineWidth: 0.3,
                },
                labelCfg: {
                    style: {
                        fontSize: 12,
                    },
                    position: "bottom",
                    offset: 1,
                },
            },
            defaultEdge: {
                style: {
                    lineWidth: 2,
                    color: "#000",
                    labelCfg: {
                        autoRotate: true,
                        refY: 5,
                        style: {
                            fill: "#000",
                        },
                    },
                    endArrow: {
                        fill: "#000",
                        path: G6.Arrow.triangle(10, 12, 25),
                        d: 25,
                    },
                },
            },
            nodeStateStyles: {
                // The node styles in selected state
                selected: {
                    stroke: '#666',
                    lineWidth: 2,
                    fill: 'steelblue',
                },
            }
        });

        const data = {
            nodes: [
                { id: "node1", x: 100, y: 100, label: "Node 1" },
                { id: "node2", x: 300, y: 100, label: "Node 2" },
                { id: "node3", x: 200, y: 200, label: "Node 3" },
            ],
            edges: [{ source: "node1", target: "node2", label: "Edge 1" }],
        };

        // 渲染图表
        graphRef.current.data(data);
        graphRef.current.render();

        graphRef.current.on('nodeselectchange', (e: any) => {
            // 当前操作的 item
            console.log(e.target);
            // 当前操作后,所有被选中的 items 集合
            console.log(e.selectedItems);
            // 当前操作时选中(true)还是取消选中(false)
            console.log(e.select);
        });
    };

    return (
        <>
            <div>
                <Button onClick={() => { graphRef.current.setMode('default') }}>默认模式</Button>
                <Button onClick={() => { graphRef.current.setMode('edit') }}>编辑模式</Button>
                <Button onClick={() => { graphRef.current.setMode('addEdge') }}>创建边</Button>
            </div>
            <div
                className="ModalgraphContainer"
                ref={containerRef}
                id="graphContainer"
            />
        </>
    );
};
export default TestModes;

效果如下:

相关推荐
mldong2 小时前
你的 Vue3 项目也能有钉钉同款审批流设计器:npm 装包,10 分钟画出第一条审批流
前端·vue.js
2分钟速写快排3 小时前
什么是 RAG?如何用 RAG 实现一个用户记忆?
前端·后端·ai编程
passerby60613 小时前
如何自己造一个时间处理库
前端·javascript·github
走到天涯海角4 小时前
react里面的长列表渲染优化
前端·react.js·前端框架
小羊没烦恼!4 小时前
Hello Web API系列教程——Web API与国际化
java·服务器·前端·javascript·php
北岛贰5 小时前
迷茫焦虑期,我做了一个带支付带官网的 AI 聊天虚拟恋人 App
前端·人工智能·后端
mayaairi6 小时前
Vue2 组件通讯(三):全局事件总线、PubSub、插槽与组件实例属性
前端·javascript·vue.js
kyriewen7 小时前
面试官问我:AI 都能写代码了,前端凭什么还值 25K
前端·javascript·人工智能
风骏时光牛马8 小时前
AI源码分析:拆解模型底层实现逻辑
前端
IT_陈寒8 小时前
React子组件莫名其妙重渲染?你可能漏了这个Hook
前端·人工智能·后端