x6实现节点新增编辑删除

本文介绍了如何使用AntVX6库在网页上创建交互式的流程图,包括图形布局、Stencil组件、节点和边的定义,以及键盘快捷键的绑定和事件操作。
摘要由CSDN通过智能技术生成

<template>
  <div class="x6-content">
    <div id="stencil"></div>
    <div id="graph-container"></div>
  </div>
</template>

<script>
import { Graph, Shape, Addon } from "@antv/x6";
export default {
  data() {
    return {
      graph: null,
      // 初始化图形
      ports: {
        groups: {
          top: {
            position: "top",
            attrs: {
              circle: {
                r: 4,
                magnet: true,
                stroke: "#5F95FF",
                strokeWidth: 1,
                fill: "#fff",
                style: {
                  visibility: "hidden",
                },
              },
            },
          },
          right: {
            position: "right",
            attrs: {
              circle: {
                r: 4,
                magnet: true,
                stroke: "#5F95FF",
                strokeWidth: 1,
                fill: "#fff",
                style: {
                  visibility: "hidden",
                },
              },
            },
          },
          bottom: {
            position: "bottom",
            attrs: {
              circle: {
                r: 4,
                magnet: true,
                stroke: "#5F95FF",
                strokeWidth: 1,
                fill: "#fff",
                style: {
                  visibility: "hidden",
                },
              },
            },
          },
          left: {
            position: "left",
            attrs: {
              circle: {
                r: 4,
                magnet: true,
                stroke: "#5F95FF",
                strokeWidth: 1,
                fill: "#fff",
                style: {
                  visibility: "hidden",
                },
              },
            },
          },
        },
        items: [
          {
            group: "top",
          },
          {
            group: "right",
          },
          {
            group: "bottom",
          },
          {
            group: "left",
          },
        ],
      },
    };
  },
  mounted() {
    this.initData();
  },
  methods: {
    initData() {
      // #region 初始化画布
      this.graph = new Graph({
        container: document.getElementById("graph-container"),
        grid: true,
        mousewheel: {
          enabled: true,
          zoomAtMousePosition: true,
          modifiers: "ctrl",
          minScale: 0.5,
          maxScale: 3,
        },
        connecting: {
          router: {
            name: "manhattan",
            args: {
              padding: 1,
            },
          },
          connector: {
            name: "rounded",
            args: {
              radius: 8,
            },
          },
          anchor: "center",
          connectionPoint: "anchor",
          allowBlank: false,
          snap: {
            radius: 20,
          },
          createEdge() {
            return new Shape.Edge({
              attrs: {
                line: {
                  stroke: "#A2B1C3",
                  strokeWidth: 2,
                  targetMarker: {
                    name: "block",
                    width: 12,
                    height: 8,
                  },
                },
              },
              zIndex: 0,
            });
          },
          validateConnection({ targetMagnet }) {
            return !!targetMagnet;
          },
        },
        highlighting: {
          magnetAdsorbed: {
            name: "stroke",
            args: {
              attrs: {
                fill: "#5F95FF",
                stroke: "#5F95FF",
              },
            },
          },
        },
        resizing: true,
        rotating: true,
        selecting: {
          enabled: true,
          rubberband: true,
          showNodeSelectionBox: true,
        },
        snapline: true,
        keyboard: true,
        clipboard: true,
      });
      // #endregion

      // #region 初始化 stencil
      const stencil = new Addon.Stencil({
        title: "流程图",
        target: this.graph,
        stencilGraphWidth: 200,
        stencilGraphHeight: 180,
        collapsable: true,
        groups: [
          {
            title: "基础流程图",
            name: "group1",
          },
        ],
        layoutOptions: {
          columns: 2,
          columnWidth: 80,
          rowHeight: 55,
        },
      });
      document.getElementById("stencil").appendChild(stencil.container);

      // #region 快捷键与事件
      this.shortCutKeyPractice(this.graph);
      // 控制连接桩显示/隐藏
      this.operatePorts(this.graph);

      // #region 初始化图形
      Graph.registerNode(
        "custom-rect",
        {
          inherit: "rect",
          width: 66,
          height: 36,
          attrs: {
            body: {
              strokeWidth: 1,
              stroke: "#5F95FF",
              fill: "#EFF4FF",
            },
            text: {
              fontSize: 12,
              fill: "#262626",
            },
          },
          tools: [
            {
              name: "button-remove",
              arg: { x: -6, y: -8 },
            },
          ],
          ports: { ...this.ports },
        },
        true
      );
      const r1 = this.graph.createNode({
        shape: "custom-rect",
        label: "开始",
        attrs: {
          body: {
            rx: 20,
            ry: 26,
          },
        },
      });
      stencil.load([r1], "group1");
    },
    shortCutKeyPractice(graph) {
      // copy cut paste
      graph.bindKey(["meta+c", "ctrl+c"], () => {
        const cells = graph.getSelectedCells();
        if (cells.length) {
          graph.copy(cells);
        }
        return false;
      });
      graph.bindKey(["meta+x", "ctrl+x"], () => {
        const cells = graph.getSelectedCells();
        if (cells.length) {
          graph.cut(cells);
        }
        return false;
      });
      graph.bindKey(["meta+v", "ctrl+v"], () => {
        if (!graph.isClipboardEmpty()) {
          const cells = graph.paste({ offset: 32 });
          graph.cleanSelection();
          graph.select(cells);
        }
        return false;
      });

      //undo redo
      graph.bindKey(["meta+z", "ctrl+z"], () => {
        if (graph.history.canUndo()) {
          graph.history.undo();
        }
        return false;
      });
      graph.bindKey(["meta+shift+z", "ctrl+shift+z"], () => {
        if (graph.history.canRedo()) {
          graph.history.redo();
        }
        return false;
      });

      // select all
      graph.bindKey(["meta+a", "ctrl+a"], () => {
        const nodes = graph.getNodes();
        if (nodes) {
          graph.select(nodes);
        }
      });
    
      //双击修改内容
      graph.on("cell:dblclick", ({ cell, e }) => {
        const isNode = cell.isNode();
        const name = cell.isNode() ? "node-editor" : "edge-editor";
        cell.removeTool(name);
        cell.addTools({
          name,
          args: {
            event: e,
            attrs: {
              backgroundColor: isNode ? "#EFF4FF" : "#FFF",
            },
          },
        });
      });
    },
    operatePorts(graph) {
      // 控制连接桩显示/隐藏
      const showPorts = (ports, show) => {
        for (let i = 0, len = ports.length; i < len; i = i + 1) {
          ports[i].style.visibility = show ? "visible" : "hidden";
        }
      };
      graph.on("node:mouseenter", () => {
        const container = document.getElementById("graph-container");
        const ports = container.querySelectorAll(".x6-port-body");
        showPorts(ports, true);
      });
      graph.on("node:mouseleave", () => {
        const container = document.getElementById("graph-container");
        const ports = container.querySelectorAll(".x6-port-body");
        showPorts(ports, false);
      });

      graph.on("edge:mouseenter", ({ edge }) => {
        edge.addTools([
          "source-arrowhead",
          "target-arrowhead",
          {
            name: "button-remove",
            args: {
              distance: -30,
            },
          },
        ]);
      });
      graph.on("edge:mouseleave", ({ edge }) => {
        edge.removeTools();
      });
    },
  },
};
</script>
<style lang="less" scoped>
.x6-content {
  display: flex;
  width: 100%;
  height: 100%;
  #stencil {
    width: 200px;
    height: 100%;
  }
  #graph-container {
    width: calc(100% - 200px);
    height: 100%;
  }
}
</style>

ANTV X6 是一款流程图绘制工具,使用 ANT(A Nature Toolkit)作为开发框架,提供了丰富的图形绘制和交互功能。在ANTV X6中,可以通过节点双击来实现文本编辑。 当使用者在绘制流程图时,可以在画布上添加节点节点可以表示各种不同的对象或操作,例如任务、决策、操作等。节点双击是一种常见的交互方式,用于对节点的文本进行编辑。 具体实现上,在ANTV X6中,首先需要为每个节点添加双击事件的监听器。当节点被双击时,监听器会捕捉到该事件,并触发相应的操作。一般情况下,双击事件会将节点的文本框置为可编辑状态,让使用者可以直接在节点上进行文本编辑。 在文本编辑状态下,使用者可以通过键盘输入或者复制粘贴等方式对文本内容进行修改或更新。同时,ANTV X6会提供相应的编辑框界面,用于对文本进行格式化或样式调整。例如,可以修改文本的字体、颜色、大小等属性,以及添加或删除文本的下划线、斜体等效果。 一旦用户完成了节点文本的编辑,可以通过点击画布其他部分或按下回车键等方式,退出文本编辑状态,并将修改后的文本内容保存到节点上。 ANTV X6 提供了便捷的节点双击文本编辑功能,使得用户可以在流程图绘制过程中轻松地编辑节点的文本内容。这样可以提高工作效率,同时也丰富了流程图的表达能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值