前端可视化 - AntV G6 核心概念

743 阅读4分钟

一、是什么

官网介绍:G6 是一个图可视化引擎。它提供了图的绘制、布局、分析、交互、动画等图可视化的基础能力。旨在让关系变得透明,简单。让用户获得关系数据的 Insight。

二、核心概念

A_I0RoTKgsvSEAAAAAAAAAAAAAARQnAQ.png

图、 图元素:节点\边\Combo、图布局、交互与事件、动画、插件与工具

1. 图元素:节点\边\Combo

图的元素(Item)包含图上的节点 Node 、边 Edge 和 Combo 三大类。每个图元素由一个或多个 图形(Shape) 组成,且都会有自己的唯一关键图形(keyShape)

图元素属性:一般分为两种,样式属性、其它属性

配置属性的方式:7种

  1. 实例化图时,配置元素全局属性(全局的, 不能个性化配置) eg: defaultNode, defaultEdge
const graph = new G6.Graph({
  // ...                   // 图的其他配置
  // 节点在默认状态下的样式配置(style)和其他配置
  defaultNode: {
    size: 30, // 节点大小
    // ...                 // 节点的其他配置
    // 节点样式配置
    style: {
      fill: 'steelblue', // 节点填充色
      stroke: '#666', // 节点描边色
      lineWidth: 1, // 节点描边粗细
    },
    // 节点上的标签文本配置
    labelCfg: {
      // 节点上的标签文本样式配置
      style: {
        fill: '#fff', // 节点标签文字颜色
      },
    },
  },
  // 边在默认状态下的样式配置(style)和其他配置
  defaultEdge: {
    // ...                 // 边的其他配置
    // 边样式配置
    style: {
      opacity: 0.6, // 边透明度
      stroke: 'grey', // 边描边颜色
    },
    // 边上的标签文本配置
    labelCfg: {
      autoRotate: true, // 边上的标签文本根据边的方向旋转
    },
  },
});
  1. 在数据中配置(不同点、边可以有不同个性化配置,可以覆盖全局静态属性值)
const nodes = remoteData.nodes;
nodes.forEach((node) => {
  if (!node.style) {
    node.style = {};
  }
  switch (
    node.class // 根据节点数据中的 class 属性配置图形
  ) {
    case 'c0': {
      node.type = 'circle'; // class = 'c0' 时节点图形为 circle
      break;
    }
    case 'c1': {
      ...
    }
    case 'c2': {
     ...
    }
  }
});

graph.data(remoteData);
  1. 使用update、updateItem
graph.updateItem(node, {
  // 节点的样式
  style: {
    stroke: 'blue',
  },
  // 节点上文本的样式
  labelCfg: {
    style: {
      fill: '#fff',
      fontSize: 12,
    },
  },
});
  1. graph.node()
  • 必须在render之前调用,优先级最高,如果数据量大,每个节点上需要更新的内容多时,可能会有性能问题
// const data = ...
// const graph = ...
graph.node((node) => {
  return {
    id: node.id,
    type: 'rect',
    style: {
      fill: 'blue',
    },
  };
});


graph.data(data);
graph.render();

2. 图布局 Layout

当数据中没有节点位置信息,或者数据中的位置信息不满足需求时,需要借助一些布局算法对图进行布局

3. 图交互Behavior与事件

  • 交互行为 Behavior

eg:drag-canvas 、 zoom-canvas

  • 交互管理 Mode

一个 mode 是多种行为 Behavior 的组合,允许用户通过切换不同的模式进行交互行为的管理

  • 交互状态 State

用户可以为图中的元素(节点/边)设置不同的状态及不同状态下的样式。要达到交互更改元素样式,需要两步

  1. 实例化图时,通过 nodeStateStyles 和 edgeStateStyles 两个配置项可以配置元素在不同状态下的样式。
const graph = new G6.Graph({
  // ...                           // 其他配置项
  // 节点不同状态下的样式集合
  nodeStateStyles: {
    // 鼠标 hover 上节点,即 hover 状态为 true 时的样式
    hover: {
      fill: 'lightsteelblue',
    },
    // 鼠标点击节点,即 click 状态为 true 时的样式
    click: {
      stroke: '#000',
      lineWidth: 3,
    },
  },
  // 边不同状态下的样式集合
  edgeStateStyles: {
    // 鼠标点击边,即 click 状态为 true 时的样式
    click: {
      stroke: 'steelblue',
    },
  },
});
  1. 监听事件并切换元素状态
// 点击节点
graph.on('node:click', (e) => {
  // 先将所有当前是 click 状态的节点置为非 click 状态
  const clickNodes = graph.findAllByState('node', 'click');
  clickNodes.forEach((cn) => {
    graph.setItemState(cn, 'click', false);
  });
  const nodeItem = e.item; // 获取被点击的节点元素对象
  graph.setItemState(nodeItem, 'click', true); // 设置当前节点的 click 状态为 true
});

4. 插件与工具

为辅助用户在图上探索,G6 提供了一些辅助工具,其中一部分是插件工具,另一部分是交互工具。 插件工具:Minimap、Grid 交互工具: tooltip // 节点提示框

5. 动画

  • 全局动画:G6 的全局动画指通过图实例进行操作时,产生的动画效果
const graph = new G6.Graph({
  // ...                   // 图的其他配置项
  animate: true, // Boolean,切换布局时是否使用动画过度,默认为 false
  animateCfg: {
    duration: 500, // Number,一次动画的时长
    easing: 'linearEasing', // String,动画函数
  },
});
  • 元素动画:由于 G6 的内置节点和边是没有动画的,需要实现节点和边上的动画需要通过自定义节点自定义边时复写  afterDraw  实现。
// 放大、变小动画
G6.registerNode(
  'circle-animate',
  {
    afterDraw(cfg, group) {
      // 获取该节点上的第一个图形
      const shape = group.get('children')[0];
      // 该图形的动画
      shape.animate(
        (ratio) => {
          // 每一帧的操作,入参 ratio:这一帧的比例值(Number)。返回值:这一帧需要变化的参数集(Object)。
          // 先变大、再变小
          const diff = ratio <= 0.5 ? ratio * 10 : (1 - ratio) * 10;
          let radius = cfg.size;
          if (isNaN(radius)) radius = radius[0];
          // 返回这一帧需要变化的参数集,这里只包含了半径
          return {
            r: radius / 2 + diff,
          };
        },
        {
          // 动画重复
          repeat: true,
          duration: 3000,
          easing: 'easeCubic',
        },
      ); // 一次动画持续的时长为 3000,动画效果为 'easeCubic'
    },
  },
  'circle',
); // 该自定义节点继承了内置节点 'circle',除了被复写的 afterDraw 方法外,其他按照 'circle' 里的函数执行。