antv/x6的demo及案例

2,812 阅读2分钟

首先贴上git地址:gitee.com/wang-shuang…

重点要看以下文档,根据需求查找对应的API,示例

antv/x6文档:x6.antv.antgroup.com/tutorial/ge…

antv/x6 API:x6.antv.antgroup.com/api/graph/g…

antv/x6图表示例:x6.antv.antgroup.com/examples

case1

DEMO

1、画布,节点,边

参考x6.antv.antgroup.com/tutorial/ge…

将指定元素设为x6-shape,并添加背景,网格,svg,在svg内绘制节点,边

2、自定义节点

x6.antv.antgroup.com/tutorial/in…

需安装@antv/x6-vue-shape(需和@antv/x6在同一个大版本),使用register方法对组件进行注册,添加节点时shape使用注册的组件名。

import { register } from '@antv/x6-vue-shape'
import ctmNode from '@/views/x6node/ctmNode.vue'// 注册组件
register({
  shape: 'custom-vue-x6node',
  width: 100,
  height: 100,
  component: ctmNode,
})
​
this.graph.addNode({
  id: 'node3',
  shape: 'custom-vue-x6node', // 使用注册的组件
  width: 170,
  height: 154,
  x: 600,
  y: 0,
})

3、组合

x6.antv.antgroup.com/tutorial/in…

群组和普通节点本质上没区别,节点A通过addChild方法将节点B加入节点A后,节点A就成了群组

const parent = this.graph.addNode({
  id: 'group1',
  x: 10,
  y: 10,
  width: 600,
  height: 260,
  zIndex: 1,
  label: 'Parent',
})
const child1 = this.graph.addNode({
  id: 'child1',
  x: 20,
  y: 20,
  width: 100,
  height: 50,
  label: 'Child',
  zIndex: 10,
})
​
parent.addChild(child1)

4、流动线

录屏2024-12-17-16.54.07.gif

// 注册边
Graph.registerEdge('flow-edge', {
  inherit: 'edge',
  markup: [
    {
      tagName: 'path',
      selector: 'line',
      attrs: {
        fill: 'none',
      },
    },
    {
      tagName: 'circle',
      selector: 'circle',
    },
  ],
  attrs: {
    line: {
      connection: true,
      sourceMarker: null, // 实心箭头
      targetMarker: null,
      stroke: '#3155ce',
      strokeLinejoin: 'round',
      strokeWidth: 4,
    },
    circle: {
      r: 7,
      atConnectionRatio: 0,
      fill: {
        type: 'radialGradient',
        stops: [
          { offset: '0%', color: '#FFF' },
          { offset: '100%', color: '#6692FF' },
        ],
      },
    },
  },
})
​
// 使用自定义边
this.graph.addEdge({
  shape: 'flow-edge',
  id: '1001',
  source: 'node2',
  target: 'node1',
  vertices: [
    { x: 350, y: 250 },
    { x: 150, y: 250 },
  ],
  connector: {
    name: 'rounded',
    args: {},
  },
})
// 获取边
const edge1 = this.graph.getCellById('1001')
​
const options1 = {
  delay: 0,
  duration: 3000,
  timing: Timing.linear,
  start(p) {
    console.log('[start]', p)
  },
  // progress(p) {
  //   console.log('[progress]', p)
  // },
  complete(p) {
    console.log('[complete]', p)
    // 完成后重复动画
    edge1.updateAttrs(
      {
        circle: { atConnectionRatio: 0 },
      },
      { silent: true }
    )
    edge1.transition('attrs/circle/atConnectionRatio', 1, options1)
  },
  stop(p) {
    console.log('[stop]', p)
  },
  finish(p) {
    console.log('[finish]', p)
  },
}
​
 edge1.transition('attrs/circle/atConnectionRatio', 1, options1) // 初始原点位置设为1,并使用选项

案例

1、为了适配,做了如下处理:

  • css单位使用vw
  • 流程图相关单位为px,设计稿宽度为1920px,根据屏幕宽度使用px2px方法进行重设

2、实现效果图在文首

3、具体参考代码gitee.com/wang-shuang…,实现主要分为以下步骤

  • 注册自定义边,注册自定义节点

  • 初始化画布容器

  • 创建组,创建子节点,将子节点加入组

  • 初始化边

    • 通过anchor设置节点的锚点(不设默认为节点中心)
    • 使用vertices设置中间路径点
  • 给自定义节点赋值

    // 自定义组件
    export default {
      inject: ['getNode'], // 接收getNode方法
      // 使用data而不是props
      data() { 
        return {
          title: '-',
          column: 1,
          itemWidth: 128,
          list: [],
        }
      },
      mounted() {
        const node = this.getNode()
        node.on('change:data', ({ current }) => {
          const { title = '', column = 1, itemWidth, list = [] } = current
          this.title = title
          this.column = column
          if (itemWidth) {
            this.itemWidth = itemWidth
          }
          this.list = list
        })
      },
    }
    
    // 父组件
    // 设置组件的值
    node.setData({
      title: 'xxxx平台(M)',
      column: 5,
      list: [{}, {}],
    })
    
  • 添加动画