什么是G6
G6 是一个图可视化引擎。它提供了图的绘制、布局、分析、交互、动画等图可视化的基础能力。旨在让关系变得透明,简单。让用户获得关系数据的 Insight。
类似于D3,D3能实现的G6也能实现,但d3的官方文档是非汉语文档。
第一个示例
搭建环境
最近在看react文档,所以我是在react基础上来学习G6。
            
            
              js
              
              
            
          
          npm install --save @antv/g6导入G6
            
            
              js
              
              
            
          
          import G6 from '@antv/g6';创建容器
在G6进行绘制的时候,会根据id获取对应的节点,将canvas图绘制在这个div中。
            
            
              js
              
              
            
          
          <div id="mountNode"></div>绘制图
参考官网入门 快速上手 | G6 (antgroup.com)
Graph
Graph是G6最主要的一个类,通过graph实例就可以直接绘制图片。里面有两个主要API,data和render。
data 渲染数据
- 
nodes:定义点集 - x : 横坐标
 - y : 纵坐标
 
- 
edges:定义边集 - source : 开始节点
 - target : 结束节点
- 一个对象表示一条线
 
graph.render()
根据提供的数据渲染视图。
一些操作记录
graph.setMode(mode)
将事件交互封装在mode中,可以选择默认default和编辑状态。
            
            
              js
              
              
            
          
          const graph = new G6.Graph({
    container: div,
    width: 500,
    height: 500,
    modes: {
      default: [...],
      custom: [...]
    }
})
graph.setMode('custom')内置Behavior ------ 与mode搭配使用
参考官网:内置的 Behavior | G6 (antgroup.com)
- 拖动节点:drag-node
- 缩放:zoom-canvas
- 收起和展开:collapse-expand-combo
- 拖拽画布:drag-canvas
            
            
              js
              
              
            
          
          const graph = new G6.Graph({
    container: 'mountNode', // String | HTMLElement,必须,在 Step 1 中创建的容器 id 或容器本身
    width: 800, // Number,必须,图的宽度
    height: 500, // Number,必须,图的高度
    modes: {
        default: [
            'drag-canvas',
            'zoom - canvas'
        ],
    },
});自定义交互 registerBehavior
参考官网:自定义交互 Behavior | G6 (antgroup.com)
            
            
              js
              
              
            
          
          G6.registerBehavior('activate-node',{
    ...
    //返回布局的默认参数
    getDefaultCfg() {
        return {
          multiple: true//是否允许多选,默认为 true?
        };
     },
    //事件绑定
    getEvents() {
        return {
          'node:click': 'onNodeClick',
          'canvas:click': 'onCanvasClick'
        };
     }
     //回调 方法实现
     onNodeClick(e){}
     onCanvasClick(e){}
}自定义behavior后,使用与内置的相同,都是放在default中。
自定义节点 registerNode
type
在G6中,已经给我们提供了很多内置的节点样式。我们可以在data中对其进行修改。
            
            
              js
              
              
            
          
          nodes: [
        {
            id: 'node1', // String,该节点存在则必须,节点的唯一标识
            type: 'rect'
        },
        {
            id: 'node2', // String,该节点存在则必须,节点的唯一标识
            type: 'star'
        },
    ],创建
            
            
              js
              
              
            
          
          G6.registerNode('nodename',{
    option:{
        style:{}
        ...
    }
})
自定义边 registerEdge
参考官网:自定义边 | G6 (antgroup.com) 注册一个边类型
            
            
              js
              
              
            
          
          G6.registerEdge('hvh', {})继承-line为例
line是已经存在的内置边,如果觉得满足不了需求,又不想重新写一个。就可以选择在line的生命周期上穿插一些事件来满足你的需求。
            
            
              js
              
              
            
          
          import G6 from '@antv/g6'; 
G6.registerEdge( 'edgeName', 
{
    draw(cfg, group) { 
         // 定义的其他方法,都可以在draw里面调用, 
         // 如 drawShape、drawLabel 等。 
     },
     drawShape(cfg, group) { // }, 
     getLabelStyle(cfg) { 
         // 根据业务返回 label 的样式 
         return {}; 
     }, 
     update(cfg, item) { 
         // 更新绘制的元素 
     }, 
}, 'line',);Item 是一个基类
参考官网:元素实例方法 | G6 (antgroup.com) Node和Edge都会继承与Item上的属性和方法。需了解item的生命周期。
- 更新元素:item.update(model)
- 刷新元素:item.refresh()
- 更新元素位置,避免整体重绘:item.updatePosition(cfg)
- 销毁:item.destroy()
Shape
参考官网:图形样式属性 Shape Attr | G6 (antgroup.com)
如何给节点和边绑定事件
其实就是根据事件绑定回调。
参考文档:基础事件 Event | G6 (antgroup.com)
            
            
              js
              
              
            
          
          graph.on(eventName, evt => { // 一些操作 })还可以进行事件的监听
            
            
              js
              
              
            
          
          graph.on(timingEventName, evt => { // 一些操作 })
如何设置节点和边的状态
graph.setItemState(item, stateName, stateValue)
参考文档:状态 State | G6 (antgroup.com)
| 参数名 | 类型 | 描述 | 
|---|---|---|
| item | Number | 需要被设置状态的节点/边实例 | 
| stateName | String | 状态名称,可以是任意字符串 | 
| stateValue | Booelean | true 代表该状态是被激活,false 代表该状态被灭活 | 
            
            
              js
              
              
            
          
          //定义身体健康状态 
//健康
'bodyState:health': {
    // keyShape 该状态值下的样式
    fill: 'green',
    // ... 其他样式
    // name 为 shape-name1 的子图形在该状态值下的样式
    'shape-name1': {
      stroke: '#ccc'
      // ... 其他样式
    },
    // name 为 shape-name2 的子图形在该状态值下的样式
    'shape-name2': {
      fill: 'red'
      // ... 其他样式
    }
  },
  //
  // 多值状态 bodyState 为 suspect 时的样式
  'bodyState:suspect': {
    // ...
  },
  //生病
  // 多值状态 bodyState 为 ill 时的样式
  'bodyState:ill': {
    // ...
  }
  // ... 其他状态根据状态查找元素
graph.findAllByState(type, state)
| 名称 | 类型 | 是否必选 | 描述 | 
|---|---|---|---|
| type | string | true | 元素类型,可选值为 node、edge | 
| state | string | true | 状态名称 | 
简单来说就是将item节点的状态(stateName)设置为stateValue,3.4版本之前是只有二值状态的,在这之后就有多值状态了。
            
            
              js
              
              
            
          
          // 查询所有选中的元素 
const nodes = graph.findAllByState('node', 'selected');实战
data.js
- id: 非必选,内部会自动赋值
- x:500, y:100 该节点在画布中的位置,

- style: 节点样式
- label: 节点文本
- labelCfg: 节点文本样式
- nodeStateStyles: 节点多状态的样式
- anchorPoints: 自定义锚点数量和位置
自定义行为注册工厂
自定义行为、事件、模式通过一个方法(工厂)去注册。(后续陆续完善)
            
            
              js
              
              
            
          
          // register-factory.js 注册工厂函数
import shape from './shape/exports';
import behavior from './behavior/exports';
import registerEdges from './shape/edges/base-edge';
//注册不分先后
export default G6 => {
  // 注册图形
  shape(G6);
  // 注册行为
  behavior(G6);
  // 注册边
  registerEdges(G6);
};实例化的时候可以选择哪些事件是否开启。(更灵活)
            
            
              js
              
              
            
          
          //exports.js 行为暴露 -- 防止全部写在工厂里 显得赘余
import canvasEvent from './canvas-event'; // 画布行为
import selectNode from './select-node'; // 选中节点行为
import deleteItem from './delete-item'; // 删除节点
import activeEdge from './active-edge'; // 激活边
import hoverNode from './hover-node'; // hover节点
import dragNode from './drag-node'; // 拖拽节点
export default G6 => {
  canvasEvent(G6);
  selectNode(G6);
  deleteItem(G6);
  activeEdge(G6);
  hoverNode(G6);
  dragNode(G6);
};注册行为 behavior:所有的事件
事件一:画布拖拽事件
参考文档: 复合交互及其自定义 Behavior
自定义 Behavior 时,定义事件及处理事件的方法。
触发方式:回调方法 | 'node:click' : 'onNodeClick',
            
            
              js
              
              
            
          
           //BehaviorOption.getEvents()
G6.registerBehavior('behaviorName', {
  getEvents() {
    return {
      'node:click': 'onNodeClick',
      'edge:click': 'onEdgeClick',
      'mousemove': 'onMouseMove'
    }
  }
}案例:鼠标按下画布时修改cursor
设置触发事件和回调函数名的定义
            
            
              js
              
              
            
          
          getEvents () {
            return {
                'canvas:mousemove': 'onCanvasMouseMove',//鼠标在画布内部移动时不断触发,不能通过键盘触发
                'canvas:mousedown': 'onCanvasMouseDown',//鼠标按钮在画布上按下(左键或者右键)时触发,不能通过键盘触发
                'canvas:mouseup': 'onCanvasMouseUp',//画布上按下的鼠标按钮被释放弹起时触发,不能通过键盘触发
                'canvas:dragend': 'onCanvasDragEnd',//当拖拽完成后触发的事件,此事件作用在被拖曳画布上
            };
        },回调函数的实现
            
            
              js
              
              
            
          
          //设置点击鼠标 拖拽时的鼠标样式
        onCanvasMouseMove (e) {
            e.target.get('el').style.cursor = 'grab';
        },
        onCanvasMouseDown (e) {
            console.log(e);
            e.target.get('el').style.cursor = 'grabbing';
        },
        onCanvasMouseUp (e) {
            e.target.get('el').style.cursor = 'grab';
        },
        onCanvasDragEnd (e) {
            e.target.get('el').style.cursor = 'grab';
            this.graph.emit('on-canvas-dragend', e);
        },this.graph.emit('on-canvas-dragend', e);
事件获取画布相对于渲染时的偏移量 避免新增了元素 拖拽进入画布时的位置还是原来的初始值 即更新画布位置 以保证元素相对画布位置准确  参考:
 参考: