antv x6

1,777 阅读6分钟

antv x6介绍

X6 是 AntV 旗下的图编辑引擎,方便我们快速搭建 DAG 图、ER 图、流程图等应用。

安装

npm i @antv/x6 --save
yarn add @antv/x6

使用

// 引入
import { Graph } from '@antv/x6';

// 创建容器
<div id="container"></div>

// 准备数据
const data = {
  // 节点
  nodes: [
    {
      id: 'node1', // String,可选,节点的唯一标识
      x: 40,       // Number,必选,节点位置的 x 值
      y: 40,       // Number,必选,节点位置的 y 值
      width: 80,   // Number,可选,节点大小的 width 值
      height: 40,  // Number,可选,节点大小的 height 值
      label: 'hello', // 文本
      shape: "rect", // 长方形
      angle: 20, // 旋转角度
    },
    {
      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
    },
  ],
};

// 渲染画布
const graph = new Graph({
  container: document.getElementById('container'),
  width: 800,
  height: 600,
  background: {
    color: '#fffbe6', // 设置画布背景颜色
  },
  grid: {
    size: 10,      // 网格大小 10px
    visible: true, // 渲染网格背景
  },
});

// 渲染节点和边
graph.fromJSON(data)

// 缩放和平移
grape.zoom(0.5) // 缩放
grape.translate(80, 40) // 平移

// 节点(nodes)图形
shape: "rect", // 默认图形

// 节点定制样式
通过 `attrs` 对象来配置节点样式
attrs: {
    body: {
        fill: "#2ECC71",
        stroke: "#fff",
        strokeDasharray: "10,2",
    },
    label: {
        text: "Hello",
        fill: "red",
        fontSize: 13,
    },
},

// 边(edges)图形
shape: 'double-edge'

// 边定制样式
attrs: {
    line: {
        stroke: "orange",
    },
},

画布 graph

画布平移

const graph = new Graph({
  panning: true, // 开启拖拽平移
  // 等同于上面的开启拖拽平移
  panning: {
      enabled: true, // 开启拖拽
      modifiers: 'shift', // 需要结合shift键拖拽
      // 触发画布拖拽的行为,默认为 `['leftMouseDown']`
      eventTypes: ['leftMouseDown', 'rightMouseDown', 'mouseWheel'],
  },
})

可以通过以下 API 来启用/禁止画布平移:
    graph.isPannable() // 画布是否可以平移
    graph.enablePanning() // 启用画布平移
    graph.disablePanning() // 禁止画布平移
    graph.togglePanning() // 切换画布平移状态

画布缩放

graph.zoom() // 获取缩放级别
graph.zoom(0.2) // 在原来缩放级别上增加 0.2
graph.zoom(-0.2) // 在原来缩放级别上减少 0.2

画布内容居中

graph.centerContent()

画布导出

导出SVG

import { DataUri } from "@antv/x6";

this.graph.toSVG((dataUri) => {
  // 下载
  DataUri.downloadDataUri(DataUri.svgToDataUrl(dataUri), '文件名.svg')
}, {})

toSVG 方法还支持第二个参数:
    interface ToSVGOptions {
      preserveDimensions?: boolean | Size // 设置导出svg的尺寸,
      viewBox?: Rectangle.RectangleLike
      copyStyles?: boolean // 是否复制外部样式表中的样式,默认是true
      stylesheet?: string // 自定义样式表
      serializeImages?: boolean
      beforeSerialize?: (this: Graph, svg: SVGSVGElement) => any
    }


导出PNG/JPEG

import { DataUri } from "@antv/x6";

// PNG
this.graph.toPNG((dataUri) => {
  // 下载
  DataUri.downloadDataUri(dataUri, '文件名.png')
})

// JPEG
this.graph.toJPEG((dataUri) => {
  // 下载
  DataUri.downloadDataUri(dataUri, '文件名.jpeg')
})

toPNG/toJPEG 方法第二个参数除了 toSVG 的所有参数外,还支持以下参数:
interface ToImageOptions {
  width?: number // 导出图片的宽度
  height?: number // 导出图片的高度
  backgroundColor?: string // 导出图片的背景色
  padding?: NumberExt.SideOptions // 图片的padding
  quality?: number // 从 0 到 1 的区间内图片的质量。超出取值范围,会使用默认值 0.92
}

销毁画布

graph.dispose()

节点 node

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

创建节点的方式两种

方式一:构造函数

import { Shape } from '@antv/x6'

// 创建节点实现方式1
const rect = new Shape.Rect({
    x: 100,
    y: 200,
    width: 80,
    height: 40,
    angle: 30,
    attrs: {
        body: {
            fill: 'blue',
        },
        label: {
            text: 'Hello',
            fill: 'white',
        },
    },
})

/**
 * 创建节点实现方式2
 * 等同于上面,只是写法不一样,
 * 先创建节点,然后调用节点提供的方法来设置节点的大小、位置、旋转角度、样式等
 * position:设置节点位置
 * resize:设置节点大小
 * rotate:旋转节点
 * attr:设置节点样式
 **/
const rect = new Shape.Rect()
rect.position(100, 200).resize(80, 40).rotate(30).attr({
    body: { fill: 'blue' },
    label: {
        text: 'Hello',
        fill: 'white',
    },
})

// 添加到画布
graph.addNode(rect)

方式二:graph.addNode(推荐使用这种方式)

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',
    },
  },
})

边 edge

属性名类型默认值描述
sourceTerminalDataundefined源节点或起始点
targetTerminalDataundefined目标节点或目标点
verticesPoint.PointLike[]undefined路径点
routerRouterDataundefined路由
connectorConnectorDataundefined连线
labelsLabel[]undefined标签
defaultLabelLabel默认标签默认标签

选项

source/target写法

graph.addEdge({
  source: rect1, // 源节点
  target: rect2, // 目标节点
  
  source: 'rect1', // 源节点 ID
  target: 'rect2', // 目标节点 ID
  
  source: { cell: rect1, port: 'out-port-1' },  // 源节点和链接桩 ID
  target: { cell: 'rect2', port: 'in-port-1' }, // 目标节点 ID 和链接桩 ID
  
  source: 'rect1',            // 源节点 ID
  target: { x: 100, y: 120 }, // 目标点
})

当源/目标是画布上的点时,需要开启 allowBlank 选项(默认已经开启)才能生效
const graph = new Graph({
  connecting: { allowBlank: true }
})

vertices

路径点:边从起始点开始,按顺序经过路径点,最后到达终止点。(一般不用,除非有特殊要求)

graph.addEdge({
  vertices: [
    { x: 100, y: 200 }, 
    { x: 300, y: 120 },
  ],
})

router

路由将对 vertices 进一步处理,并在必要时添加额外的点,然后返回处理后的点。

X6 默认提供了以下几种路由,点击下面的链接查看每种路由的使用方式:

graph.addEdge({
  vertices: [
    { x: 100, y: 200 }, 
    { x: 300, y: 120 },
  ],
  router: {
    name: 'orth',
    args: {},
  },
})

使用时只需要提供路由名称 name 和 参数 args 即可,不需要参数 args 时可以使用省略写法
graph.addEdge({
  router: 'orth',
  // 或
  // router: { name: 'orth' }
})

connector

链接器 connector 将路由返回的点加工成渲染边需要的 pathData

X6 默认提供了以下几种连接器,点击下面的链接查看每种连接器的使用方式。

graph.addEdge({
  vertices: [
    { x: 100, y: 200 }, 
    { x: 300, y: 120 },
  ],
  router: 'orth',
  connector: {
    name: 'rounded',
    args: {},
  },
})

使用时只需要提供连接器名称 name 和 参数 args 即可,不需要参数 args 时可以使用省略写法
graph.addEdge({
  connector: 'rounded',
  // 或
  // connector: { name: 'rounded' }
})

labels

标签:用于设置标签文本、位置、样式等

完整的 Label 配置项稍微有点复杂,所以在单独的教程中介绍

const edge = graph.addEdge({
  labels: [ { attrs: { label: { text: 'edge' } },},],
  labels: ['edge'], // 可以设置多个标签,当只设置标签文本是可以简化
  label: 'edge', // 设置单个标签,当只设置标签文本是可以简化
})

也可以调用 edge.setLabels() 和 edge.appendLabel() 来设置和添加标签
// 设置标签
edge.setLabels([{
  attrs: { label: { text: 'edge' } },
}])
// 或
edge.setLabels(['edge'])

// 添加单个标签
edge.appendLabel({
  attrs: { label: { text: 'edge' } },
})
// 或
edge.appendLabel('edge')

使用箭头 Marker

内置箭头

X6 提供了以下几种内置箭头,使用时只需要指定箭头名和参数(可省略)即可。

edge.attr({
  line: {
    sourceMarker: 'block', // 实心箭头
    targetMarker: {
      name: 'ellipse', // 椭圆
      rx: 10, // 椭圆箭头的 x 半径
      ry: 6,  // 椭圆箭头的 y 半径
    },
  },
})

自定义箭头

我们也可以通过 tagName 指定的 SVG 元素来渲染箭头

edge.attr({
  line: {
    sourceMarker: {
      tagName: 'path',
      d: 'M 20 -10 0 0 20 10 Z',
    },
    targetMarker: {
      tagName: 'path',
      fill: 'yellow',  // 使用自定义填充色
      stroke: 'green', // 使用自定义边框色
      strokeWidth: 2,
      d: 'M 20 -10 0 0 20 10 Z',
    },
  },
})

创建边的方式两种

方式一:构造函数

import { Shape } from '@antv/x6'

// 实现方式1
const edge = new Shape.Edge({
  source: rect1, // 源节点
  target: rect2, // 目标节点
})

// 实现方式2
const edge = new Shape.Edge()
edge.setSource(rect1).setTarget(rect2)

// 添加到画布
graph.addEdge(edge)

方式二:graph.addEdge(推荐使用这种方式)

const rect = graph.addEdge({
  shape: 'edge', // 指定使用何种图形,默认值为 'edge'
  source: rect1,
  target: rect2,
})

结束,欢迎指出需要改动的地方,谢谢