手把手教你快速上手AntvX6

1,145 阅读6分钟

1、安装依赖

npm install @antv/x6 --save

2、在对应页面引入x6

import { Graph } from '@antv/x6'

3、创建容器

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

4、准备数据

data: {
//节点基础信息存放数组
nodes: [
  {
    id: "node1",
    x: 0, //x轴坐标
    y: 0, //y轴坐标
    width: 80, //节点宽度
    height: 40, //节点高度
    label: "hello", //节点内容
  },
  {
    id: "node2",
    x: 300, //x轴坐标
    y: 0, //y轴坐标
    width: 80, //节点宽度
    height: 40, //节点高度
    label: "word", //节点内容
  },
],
//节点连接数组
edges: [
  {
    source: "node1",
    target: "node2",
  },
],
},

注意

id必须为字符串,不能为数字,否则连接线会丢失或者脱线

5、进行画布渲染

this.graph = new Graph({
  container: document.getElementById("mountNode"), //容器id
  width: 1000, //宽度
  height: 500, //高度
  background: {
    color: "white",
  },//背景颜色
  grid: {
    size: 10, //网格大小
    visible: true, //是否打开网格
  }, //画布网格
});
//实例化
this.graph.fromJSON(this.data);

注意

grid可以是个对象,也可以是布尔值和数字

6、节点平移(平移到指定位置)

//translate(x轴坐标,y轴坐标)
this.graph.translate(440, 180);

7、画布缩放

//zoom(数字,负数代表缩小,正数代表放大)
this.graph.zoom(440, 180);

8、内置节点样式

1、矩形、圆形、椭圆

nodes: [
  {
    id: "node1",
    shape: "circle",//内置节点样式
    x: 0, //x轴坐标
    y: 0, //y轴坐标
    width: 80, //节点宽度
    height: 40, //节点高度
    label: "hello", //节点内容
  },
  {
    id: "node2",
    x: 300, //x轴坐标
    y: 0, //y轴坐标
    width: 80, //节点宽度
    height: 40, //节点高度
    label: "word", //节点内容
  },
],

2、多边形

nodes: [
{
  id: "node4",
  shape: "polygon",
  x: 260, //x轴坐标
  y: 0, //y轴坐标
  width: 80, //节点宽度
  height: 40, //节点高度
  label: "多边形", //节点内容
  attrs: {
    body: {
      fill: "red", //节点背景颜色
      stroke: "blue", //节点边颜色
      // 指定 refPoints 属性,多边形顶点随图形大小自动缩放
      // https://x6.antv.vision/zh/docs/api/registry/attr#refpointsresetoffset
      refPoints: "0,10 10,0 20,10 10,20",
    },
  },
},
]

3、折线、路径

//折线
nodes: [
{
  id: "node5",
  shape: "polyline",
  x: 260, //x轴坐标
  y: 0, //y轴坐标
  width: 80, //节点宽度
  height: 40, //节点高度
  label: "多边形", //节点内容
  attrs: {
    body: {
      fill: "red", //节点背景颜色
      stroke: "blue", //节点边颜色
      // 指定 refPoints 属性,多边形顶点随图形大小自动缩放
      // https://x6.antv.vision/zh/docs/api/registry/attr#refpointsresetoffset
      refPoints: "0,10 10,0 20,10 10,20",
    },
  },
},
]

//路径
nodes: [
{
  id: "node6",
  shape: "path",
  x: 260, //x轴坐标
  y: 0, //y轴坐标
  width: 80, //节点宽度
  height: 40, //节点高度
  label: "多边形", //节点内容
  // 使用 path 属性指定路径的 pathData,相当于指定路径的 refD 属性
  // https://x6.antv.vision/zh/docs/api/registry/attr#refdresetoffset
  path: 'M 0 5 10 0 C 20 0 20 20 10 20 L 0 15 Z', //path等于svg的坐标
  attrs: {
    body: {
      fill: "red", //节点背景颜色
      stroke: "blue", //节点边颜色
    },
  },
},
]

4、图片

// 不带边框
nodes: [
{
  id: "node8",
  shape: "image",
  x: 260, //x轴坐标
  y: 0, //y轴坐标
  width: 80, //节点宽度
  height: 40, //节点高度
  imageUrl:'https://gw.alipayobjects.com/os/s/prod/antv/assets/image/logo-with-text-73b8a.svg'
},
]

// 带边框
nodes: [
{
  id: "node9",
  shape: "image-bordered",
  x: 260, //x轴坐标
  y: 0, //y轴坐标
  width: 80, //节点宽度
  height: 40, //节点高度
  imageUrl:'https://gw.alipayobjects.com/os/s/prod/antv/assets/image/logo-with-text-73b8a.svg'
},
]

// 内嵌入矩形的图片
nodes: [
{
  id: "node9",
  shape: "image-embedded",
  x: 260, //x轴坐标
  y: 0, //y轴坐标
  width: 80, //节点宽度
  height: 40, //节点高度
  imageUrl:'https://gw.alipayobjects.com/os/s/prod/antv/assets/image/logo-with-text-73b8a.svg'
},
]

// 内嵌入椭圆的图片
nodes: [
{
  id: "node9",
  shape: "image-inscribed",
  x: 260, //x轴坐标
  y: 0, //y轴坐标
  width: 80, //节点宽度
  height: 40, //节点高度
  imageUrl:'https://gw.alipayobjects.com/os/s/prod/antv/assets/image/logo-with-text-73b8a.svg'
},
]

5、文本和圆柱

//文本
[{
 id: "node11",
  x: 160,
  y: 120,
  width: 360,
  height: 120,
  shape: 'text-block',
  text: `There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don't look even slightly believable.`, //文本
  attrs: {
    body: {
      fill: '#efdbff', //背景色
      stroke: '#9254de', //边
      rx: 4, //x轴弧度
      ry: 4, //y轴弧度
    },
  },
}]

//圆柱
[{
  id:'node21',
  shape: 'cylinder',
  x: 320,
  y: 120,
  width: 80,
  height: 120,
  label: '圆柱',//内容
  attrs: {
    top: {//顶部
      fill: '#fe854f',
      fillOpacity: 0.5, //透明度
    },
    body: {
      fill: '#ED8A19',
      fillOpacity: 0.8,
    },
  },
}]

6、自定义html

//方法1
[{
  id:'node22',
  shape: 'html',
  x: 120,
  y: 50,
  width: 120,
  height: 50,
  data:{},//存放的数据
  html: () => { //html如果需要拿到数据,要设置data属性
    const wrap = document.createElement('div')
    wrap.style.width = '100%'
    wrap.style.height = '100%'
    wrap.style.display = 'flex'
    wrap.style.alignItems = 'center'
    wrap.style.justifyContent = 'center'
    wrap.style.border = '2px solid #9254de'
    wrap.style.background = '#efdbff'
    wrap.style.borderRadius = '4px'
    wrap.innerText = 'Hello'
    return wrap
  },
}],

//方法2 html片段
[{
  x: 280,
  y: 120,
  width: 120,
  height: 45,
  shape: 'html',
  html() {
    const wrap = document.createElement('div')
    wrap.innerHTML = `
      <a href="#" class="my-btn">
        Submit
      </a>`
    return wrap
  },
}]
//注意 
1、使用html片段,需要将样式和html分离的时候,需要安装insert-css依赖
2、npm i insert-css
3import insertCss from 'insert-css'
4insertCss(`
  .my-btn{
    position: relative;
    display: inline-block;
    padding: 10px 20px;
    color: #03e9f4;
    font-size: 16px;
    text-decoration: none;
    text-transform: uppercase;
    overflow: hidden;
    transition: .3s;
    margin-top: 40px;
    letter-spacing: 3px
  }

  .my-btn:hover {
    background: #03e9f4;
    color: #fff;
    border-radius: 5px;
    box-shadow: 0 0 5px #03e9f4,
                0 0 25px #03e9f4,
                0 0 50px #03e9f4,
                0 0 100px #03e9f4;
  }
`)

其他样式

https://x6.antv.vision/zh/docs/tutorial/basic/cell#%E5%86%85%E7%BD%AE%E8%8A%82%E7%82%B9

9、内置边的样式

//节点连接数组
edges: [
  {
    shape: "double-edge", //内置边的样式
    source: "node1",
    target: "node2",
  },
  {
    shape: "shadow-edge", //内置边的样式
    source: "node2",
    target: "node3",
  },
],

其他样式

https://x6.antv.vision/zh/docs/tutorial/basic/cell#%E5%86%85%E7%BD%AE%E8%BE%B9

10、画布

1、画布平移

// 普通画布(未开启 [scroller])通过开启 `panning` 选项来支持拖拽平移,也就是画布可以被拖动

this.graph = new Graph({
  panning: true,
})

// 等同于
this.graph = new Graph({
  panning: {
    enabled: true, //开启平移
    modifiers:'alt',//可以设置也可以不设置,设置了代表需要配合按键才能拖动平移画布
 eventTypes: ['leftMouseDown', 'rightMouseDown',    'mouseWheel']//设置画布拖拽行为,分别为左键、右键、滚轮
  },
})

2、画布是否可以平移

isPannable()
this.graph.isPannable()
//一般用户判断当前画布的状态,返回的是true和false

3、启用画布平移

enablePanning()
this.graph.enablePanning()
//使当前画布可以平移

4、禁止画布平移

disablePanning()
this.graph.disablePanning()
//禁止当前画布可以平移

5、切换画布平移状态

disablePanning()
this.graph.togglePanning()
//如果当前画布为禁止,点击切换到可以平移画布,反之

6、缩放画布

zoom()
this.graph.zoom() // 获取缩放级别,也就是当前画布的值
this.graph.zoom(0.2) // 在原来缩放级别上增加 0.2
this.graph.zoom(-0.2) // 在原来缩放级别上减少 0.2

7、画布内容居中

centerContent()
this.graph.togglePanning()

8、导出svg

this.graph.toSVG((dataUri: string) => {
DataUri.downloadDataUri(DataUri.svgToDataUrl(dataUri), 'chart.svg')
}, {
//导出的svg大小
preserveDimensions: {
    width: 100,
    height: 100,
},
//导处svg的样式
stylesheet:`
    rect {
      fill: red; //节点颜色为红色
    }
  `//导出前做的操作
beforeSerialize:(svg)=>{
 console.log(111,svg)
}
})

9、导出png

this.graph.toPNG((dataUri: string) => {
  // 下载
  DataUri.downloadDataUri(dataUri, 'chart.png')
},
{
  //画布间距
  padding: {
    top: 20,
    right: 30,
    bottom: 40,
    left: 50,
  },
  width:10,//画布高度
  height:10,//画布宽度
  backgroundColor:'red',//画布背景颜色
  quality:1,//画布质量 0和1区间
  
})

10、销毁画布

dispose
graph.dispose()

11、基类

1、使用构造函数来创建节点和边

const rect = new Shape.Rect({
  id: "node1",
  x: 40,
  y: 40,
  width: 100,
  height: 40,
  label: "rect",
  zIndex: 2,
});

const circle = new Shape.Circle({
  id: "node2",
  x: 280,
  y: 200,
  width: 60,
  height: 60,
  label: "circle",
  zIndex: 2,
});

const edge = new Shape.Edge({
  id: "edge1",
  source: rect,
  target: circle,
  zIndex: 1,
});

this.graph.addNode(rect);
this.graph.addNode(circle);
this.graph.addEdge(edge);