Antv/X6图编辑器的应用——流程图实现

Posted forguo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Antv/X6图编辑器的应用——流程图实现相关的知识,希望对你有一定的参考价值。

效果展示

在线预览
源码

SVG介绍

阮一峰SVG图像入门
SVGtutorial

因为antv/x6是基于SVG的图编辑器,所以SVG的知识有必要了解下的

简介

  • 可缩放矢量图形【基于图形】

全称:Scalable Vector Graphics

  • 定义基于矢量的图形
  • 基于XML语法
  • 放大缩小不会失真
  • 属于万维网标准
  • 可以插入DOM,通过javascript和CSS来操作

语法

<svg width=“200” height=“200” viewBox=“-100 -100 200 200”>            	
  	<polygon points="0,0 80,120 -80,120" fill="#234236" />
    <polygon points="0,-40 60,60 -60,60" fill="#0C5C4C" /> 
    <polygon points="0,-80 40,0 -40,0" fill="#38755B" />
    <rect x="-20" y="120" width="40" height="30" fill="brown" />
</svg>
<!– viewBox:视口开始位置 -->

<svg>width属性和height属性,指定了 SVG 图像在 html 元素中所占据的宽度和高度。
<viewBox>属性的值有四个数字,分别是左上角的横坐标和纵坐标、视口的宽度和高度。

形状标签

常用的基本形状,也是我们常用的标签

  • 矩形
  • 圆形
  • 椭圆
  • 线
  • 折线
  • 多边形
  • 路径

属性

通过属性可以去修改SVG的一些样式

.red 
  fill: red;


.fancy 
  fill: none;
  stroke: black;
  stroke-width: 3px;

SVGCSS 属性与网页元素有所不同,主要的属性如下:

fill:填充色
stroke:描边色
stroke-width:边框宽度

Antv/X6介绍

https://x6.antv.vision/zh/

Antv:蚂蚁集团数据可视化团队

简介

X6:基于 HTMLSVG的图编辑引擎,X6AntV旗下的图编辑引擎,提供了一系列开箱即用的交互组件和简单易用的节点定制能力,方便我们快速搭建 DAG 图、ER 图、流程图等应用。
图编辑核心能力:节点、连线与画布

使用

Step 1 创建容器

在页面中创建一个用于容纳 X6 绘图的容器,可以是一个 div 标签。

<div id="container"></div>

Step 2 准备数据

X6 支持 JSON 格式数据,该对象中需要有节点 nodes 和边 edges 字段,分别用数组表示:

const data = 
  // 节点
  nodes: [
    
      id: 'node1', // String,可选,节点的唯一标识
      x: 40,       // Number,必选,节点位置的 x 值
      y: 40,       // Number,必选,节点位置的 y 值
      width: 80,   // Number,可选,节点大小的 width 值
      height: 40,  // Number,可选,节点大小的 height 值
      label: 'hello', // String,节点标签
    ,
    
      id: 'node2', // String,节点的唯一标识
      x: 160,      // Number,必选,节点位置的 x 值
      y: 180,      // Number,必选,节点位置的 y 值
      width: 80,   // Number,可选,节点大小的 width 值
      height: 40,  // Number,可选,节点大小的 height 值
      label: 'world', // String,节点标签
    ,
  ],
  // 边
  edges: [
    
      source: 'node1', // String,必须,起始节点 id
      target: 'node2', // String,必须,目标节点 id
    ,
  ],
;

Step 3 渲染画布

首先,我们需要创建一个 Graph 对象,并为其指定一个页面上的绘图容器,通常也会指定画布的大小。

import  Graph  from '@antv/x6';

const graph = new Graph(
  container: document.getElementById('container'),
  width: 800,
  height: 600,
);

// 读取数据
graph.fromJSON(data)

画布 Graph

https://x6.antv.vision/zh/docs/tutorial/basic/graph

图的载体,包含了所有元素、渲染及交互。

新建画布

let graph = new Graph(graphOptions())

基类 Cell

https://x6.antv.vision/zh/docs/tutorial/basic/cell

图形共同的基类 ,定义了节点和的边共同属性和方法

                                 ┌──────────────────┐
                             ┌──▶│ Shape.Rect       │
                             │   └──────────────────┘
                             │   ┌──────────────────┐
                             ├──▶│ Shape.Circle     │
                 ┌────────┐  │   └──────────────────┘
              ┌─▶│  Node  │──┤   ┌──────────────────┐
              │  └────────┘  ├──▶│ Shape.Ellipse    │
              │              │   └──────────────────┘
              │              │   ┌──────────────────┐
              │              └──▶│ Shape.Xxx...     │
  ┌────────┐  │                  └──────────────────┘
  │  Cell  │──┤                                      
  └────────┘  │                  ┌──────────────────┐
              │              ┌──▶│ Shape.Edge       │
              │              │   └──────────────────┘
              │  ┌────────┐  │   ┌──────────────────┐
              └─▶│  Edge  │──┼──▶│ Shape.DoubleEdge │
                 └────────┘  │   └──────────────────┘
                             │   ┌──────────────────┐
                             └──▶│ Shape.ShadowEdge │
                                 └──────────────────┘

节点 Node

https://x6.antv.vision/zh/docs/tutorial/basic/node

根据不同的SVG元素来渲染节点和边,x6提供了内置节点和自定义节点

节点属性

节点都有共同的基类 Cell,除了Cell继承的选项外,还支持以下选项。

属性名类型默认值描述
xNumber0节点位置 x 坐标,单位为 ‘px’。
yNumber0节点位置 y 坐标,单位为 ‘px’。
widthNumber1节点宽度,单位为 ‘px’。
heightNumber1节点高度,单位为 ‘px’。
angleNumber0节点旋转角度。

添加节点

const rect = graph.addNode(
  shape: 'rect', // 指定使用何种图形,默认值为 'rect'
  x: 100,
  y: 200,
  width: 80,
  height: 40,
  angle: 30,
  attrs: 
    body: 
      fill: 'blue',
    ,
    label: 
      text: 'Hello',
      fill: 'white',
    ,
  ,
)

内置节点

https://x6.antv.vision/zh/examples/gallery/#category-%E5%86%85%E7%BD%AE%E8%8A%82%E7%82%B9

内置节点与svg标签

构造函数shape 名称svg 标签描述
Shape.Rectrectrect矩形
Shape.Circlecirclecircle圆形
Shape.Ellipseellipseellipse椭圆
Shape.Polygonpolygonpolygon多边形
Shape.Pathpathpath路径
Shape.Imageimageimage图片
Shape.HTMLhtmlHTML 节点,使用 foreignObject 渲染 HTML 片段
Shape…

自定义节点

https://x6.antv.vision/zh/docs/tutorial/intermediate/custom-node/#gatsby-focus-wrapper
我们可以通过 markup 和 attrs 来定制节点的形状和样式,
markup 可以类比 HTMLattrs 类比 CSS

1、注册

// 自定义节点的名称
export const GAS_SHAPE_NAME = 'gas-shape'

// 对象节点
Graph.registerNode(
    GAS_SHAPE_NAME,
    
        ...customNodeOptions,
    ,
    true // 重名时是否覆盖
)

配置解析

// 自定义对象节点的配置,需要展示更多的节点内容在这里去添加,并更新数据
// https://x6.antv.vision/zh/docs/tutorial/intermediate/custom-node
export const customNodeOptions = 
    // 来指定继承的基类
    inherit: 'rect',
    width: 64,
    height: 105,
    // 标签及选择器
    markup: [
        
            tagName: 'rect',
            selector: 'body',
        ,
        
            tagName: 'image',
            selector: 'image',
        ,
        
            tagName: 'text', // 标签名称
            selector: 'diagramName', // 选择器
        ,
    ],
    // 属性设置
    attrs: 
        body: 
            stroke: 'transparent',
            fill: 'transparent',
        ,
        image: 
            width: 64,
            height: 64,
            refX: 0,
            y: 10, // 向下偏移 10px
        ,
        diagramName: 
            width: 64,
            refX: 32,
            refY: '100%', // 右下角
            textAnchor: 'middle',
            textVerticalAnchor: 'bottom',
            fontSize: 14,
            fill: '#009CFF',
        ,
    ,
    // 链接桩配置
    ports:  ...ports ,

标签结构

2、使用
const newNode = graph.createNode(
    shape: GAS_SHAPE_NAME,
   	attrs: ,
    data: ,
)

修改节点

  • node.attr(path, value),详细使用见 attr
// 修改节点属性
node.attr('selector/attr', value)
// 修改携带数据
node.setData( ...data )
// 获取携带数据
node.getData()

边Edge

https://x6.antv.antgroup.com/tutorial/basic/edge
内置节点节点和边都有共同的基类 Cell, 并继承Cell 的属性

边的属性

属性名类型默认值描述
sourceTerminalData-源节点或起始点。
targetTerminalData-目标节点或目标点。
verticesPoint.PointLike[]-路径点。
routerRouterData-路由。
connectorConnectorData-连接器。
labelsLabel[]-标签。
defaultLabelLabel默认标签默认标签。

箭头marker样式

节点间连线

链接桩

https://x6.antv.vision/zh/docs/tutorial/basic/port/
负责连线的输入与输出

添加
graph.addNode(
    x: 60,
    y: 60,
    width: 160,
    height: 80,
    label: 'Rect With Ports',
    ports: [
         id: 'port1' ,
         id: 'port2' ,
         id: 'port3' ,
    ],
)

// 分组添加
graph.addNode(
    x: 60,
    y: 60,
    width: 160,
    height: 80,
    label: 'Rect With Ports',
    groups: 
        top: 
            // 定义连接柱的位置,如果不配置,将显示为默认样式
            position: 'top',
            // 定义连接柱的样式
            attrs: 
                circle: 
                    ...portStyle,
                ,
            ,
        ,
    , 
  	// 链接桩组定义
    items: [
        
            group: 'top',
        ,
        
            group: 'right',
        ,
        
            group: 'bottom',
        ,
        
            group: 'left',
        ,
    ],  // 链接桩
)
动态添加链接桩

通过鼠标位置,以及当前节点位置,计算链接桩位置

1、计算链接桩位置

// 双击添加链接桩
graph.on('node:dblclick', e => 
    const  e: event, node  = e
    // 当前选中元素
    const $select = document.querySelector('.x6-node-selected > rect')
    if (!$select) 
        return
    
    // 用于获得页面中某个元素的左,上,右和下分别相对浏览器视窗的位置
    const position = $select.getBoundingClientRect && $select.getBoundingClientRect()
    if (!position) 
        return
    

    // 鼠标位置
    const pageX = event.pageX
    const pageY = event.pageY
    // graph.zoom() 缩放层级
    const zoom = graph.zoom()
    // 相对节点左上角的位置/鼠标的位置-元素的位置就是相对位置
    const x = (pageX - position.x) / zoom
    const y = (pageY - position.y) / zoom
    node.addPort(
        group: 'absolute',
        args: 
            // 传递给自定义连接算法的参数
            // 通过鼠标位置,以及当前节点位置,计算链接桩位置
            x: Math.round(x),
            y: Math.round(y),
        ,
        silent: false, // 为 true 时不触发 'change:ports' 事件和画布重绘。
    )
)

2、添加链接桩

// 鼠标位置 - 元素位置 = 鼠标相对于节点的位置
node.addPort(
    group: 'absolute',
    args: 
        // 传递给自定义连接算法的参数
        // 通过鼠标位置,以及当前节点位置,计算链接桩位置
        x: Math.round(x),
        y: Math.round(y),
    ,
    silent: false, // 为 true 时不触发 'change:ports' 事件和画布重绘。
)

连线规则

https://x6.antv.vision/zh/docs/tutorial/basic/interacting/#%E8%BF%9E%E7%BA%BF%E8%A7%84%E5%88%99

定制节点和边的交互行为

interacting

// 定制节点和边的交互行为 ==> boolean 节点或边是否可交互
interacting: check
? 
      nodeMovable: false,
      edgeMovable: false,
      magnetConnectable: false, // 是否触发连线交互
      vertexDeletable: false, // 边的路径点是否可以被删除
  
: true

对连线过程进行控制

connecting

 // 连线规则

    connecting: 
        // 路由类型
        router: 
            // 连线类型在此修改
            // 曼哈顿路由 'manhattan' 路由是正交路由 'orth' 的智能版本,该路由由水平或垂直的正交线段组成,并自动避开路径上的其他节点(障碍)。
            name: 'manhattan',
                args: 
                padding: 1,
            ,
        ,
        // 圆角连接器,将起点、路由点、终点通过直线按顺序连接,并在线段连接处通过圆弧连接(倒圆角)。
        connector: 
            name: 'rounded',
                args: 
                radius: 8,
            ,
        ,
        anchor: 'center',
        connectionPoint: 'anchor',
        // 是否允许连接到画布空白位置的点,默认为 true。
        allowBlank: false,
        // 距离节点或者连接桩 50px 时会触发自动吸附
        snap: 
            radius: 20,
        ,
        // 拽出新的边
        createEdge() 
            return new Shape.Edge(
                markup: [
                    
                        tagName: 'path',
                        selector: 'stroke',
                    ,
                    
                        tagName: 'path',
                        selector: 'fill',
                    ,
                ],
                connector:  name: 'rounded' ,
                attrs: 
                    fill: 
                        class: 'pipe-ant-line',
                        fill: 'none',
                        connection: true,
                        strokeDasharray: 25,
                        strokeWidth: 3,
                        strokeLinecap: 'round',
                        style: 
                            animation: 

前端实现可拖拽流程的js框架

1 AntV

X6 是 AntV 旗下的图编辑引擎,提供了一系列开箱即用的交互组件和简单易用的节点定制能力,方便我们快速搭建 DAG 图、ER 图、流程图等应用。

XFlow是基于 X6 图编辑引擎、面向 React 技术栈用户的专业图编辑应用级解决方案, 帮助您轻松开发复杂的图编辑应用。目前已经在蚂蚁大数据/人工智能场景中深度打磨验证

# AntV首页,关注 X6 | XFlow
https://antv.vision/zh

# 样例
https://x6.antv.vision/apps/dag/

# X6
https://x6.antv.vision/zh


# XFlow
https://xflow.antv.vision/zh-CN/

2 jsplumb

有收费版和社区版(开源)两个版本。

大神中文地址:https://wdd.js.org/jsplumb-chinese-tutorial/#/

大神中文GitHub地址:https://github.com/wangduanduan/jsplumb-chinese-tutorial

社区版官方社区文档(2.X):https://docs.jsplumbtoolkit.com/community-2.x/current/

项目Github地址: https://github.com/jsplumb/jsplumb

3 flowchart.js

从图表的文本表示中绘制简单的SVG流程图

# 参考网址
http://flowchart.js.org/

4 bpmn-js

bpmn-js是一个BPMN 2.0渲染工具,前端可以利用这个流程设计器,设计流程。

# 网站
https://bpmn.io/toolkit/bpmn-js/

5 LogicFlow

LogicFlow 是一款流程图编辑框架,提供了一系列流程图交互、编辑所必需的功能和灵活的节点自定义、插件等拓展机制。LogicFlow支持前端研发自定义开发各种逻辑编排场景,如流程图、ER图、BPMN流程等。

# 参考网址
http://logic-flow.org/

6 flow-eda

flow-eda 项目是一种基于事件驱动的流式低代码编程应用程序,它的主要功能是采用可视化编程,以拖拽节点、连接组合节点的形式来完成流程绘制,达到低代码开发和实现业务编程的目的。

https://gitee.com/Linxff/flow-eda

7 vue-super-flow

Vue-super-flow 是基于vue 开发的一款生成、预览流程图的组件。使用者可以根据不同的需求对图、节点、连线进行细致的控制。

# 参考网址 
https://caohuatao.github.io/guide

8 GoJS

收费

# 参考网址
https://gojs.net/latest/index.html

9 JointJS

收费

https://www.jointjs.com/

以上是关于Antv/X6图编辑器的应用——流程图实现的主要内容,如果未能解决你的问题,请参考以下文章

从0到1实现流程图应用01-开篇

Markdown Mermaid

使用react-flow制作流程图

Markdown Mermaid 实用教程

测试一下

CSDN的Markdown编辑器常用语句