Home About Me

Building a Flowchart Editor in Vue.js with AntV X6

Getting started

For projects that need flowchart editing—especially when the requirements are still somewhat open-ended—x6 is a practical choice because it offers a lot of flexibility. Its documentation is also fairly approachable, so it works well as a reference point for putting together a basic editor in Vue.

The first step is simply to install the x6 dependency and prepare a container for the graph instance:

<div ref="containerRef" class="area-center-container" />

With the container in place, you can define a minimal graph dataset containing nodes and 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
    },
  ],
}

function initGraph() {
  const graph = new Graph({
    container: this.$refs.containerRef,
    grid: {
      size: 10, // 网格大小 10px
      visible: true // 渲染网格背景
    },
    snapline: {
      enabled: true, // 对齐线
      sharp: true
    },
    scroller: {
      enabled: true,
      pageVisible: false,
      pageBreak: false,
      pannable: true
    }
  })
  // 画布居中
  graph.centerContent()

  graph.fromJSON(data)
}

This is enough to get a very basic example running. The graph is initialized with a visible 10px grid, alignment guides through snapline, and a scrollable canvas with panning enabled through scroller. After initialization, graph.centerContent() centers the canvas content, and graph.fromJSON(data) renders the predefined nodes and edge.

If you want to adjust behavior further, the relevant options are all available in the official API documentation.

Adding a node sidebar

When building a usable flowchart editor, a draggable node palette is usually the next thing you need. In X6, the stencil example from the documentation can save a lot of boilerplate, since much of the sidebar behavior is already packaged for you.

As with the graph canvas, start by creating a container:

<el-aside ref="stencilRef" class="area-left" />

Then instantiate the stencil:

this.stencil = new Stencil({
    title: '流程节点侧边栏',
    target: graph,
    search: false,
    collapsable: true,
    stencilGraphWidth: this.$refs.stencilRef.$el.clientWidth,
    stencilGraphHeight: this.$refs.stencilRef.$el.clientHeight,
    groups: [
        {
            name: 'group',
            title: '流程图节点',
            collapsable: false
          }
        ],
    getDropNode: node => {
        let cloneNode = node.clone()
        switch (node.shape) {
            case 'rect':
                cloneNode = new RectShape()
                break
            case 'circle':
                cloneNode = new CircleShape()
                break
            case 'polygon':
                cloneNode = new PolylineShape()
                break
        }
        cloneNode.updateInPorts(graph)
        return cloneNode
    }
})
// 加载节点
this.stencil.load([new Rect(rectInfo), new Circle(circleInfo), new Polygon(polygonInfo)], 'group')

This setup creates a collapsible sidebar titled for flowchart nodes, binds it to the current graph, and sizes the stencil area using the actual dimensions of the sidebar element. A single group is defined to hold the available flowchart elements.

The more important part is getDropNode. Instead of dropping the original stencil node directly onto the canvas, it clones the selected item and swaps it into the corresponding business shape based on node.shape. In the example, rect, circle, and polygon are converted into RectShape, CircleShape, and PolylineShape respectively. After that, cloneNode.updateInPorts(graph) updates the node ports before returning the final dropped node.

Finally, the available nodes are loaded into the sidebar with:

  • new Rect(rectInfo)
  • new Circle(circleInfo)
  • new Polygon(polygonInfo)

all placed into the group group.

Putting it together

With those two parts combined, you have the basic structure of a Vue-based flowchart editor using AntV X6: a central canvas that can render graph data, plus a sidebar that lets users drag predefined nodes into the workflow area.

Online demo:

https://codesandbox.io/s/icy-meadow-rqihx