初始化/实例化图

通过 new G6.Graph(config) 进行图的实例化。其中参数 config 是 Object 类型的图的配置项,图的大部分功能可以通过该配置项进行全局配置。如 前提代码open in new window 这样实例化图:

const graph = new G6.Graph({
  container: 'mountNode', // 指定图画布的容器 id,与第 9 行的容器对应
  // 画布宽高
  width: 800,
  height: 500,
});

必要配置项

上面代码中实例化 Graph 的部分使用了三个必要的配置项:

  • container

类型:String | Object。图的 DOM 容器。可以是 String,为 DOM 容器的 id。也可以是 Object ,为 DOM 对象。

  • widthheight

类型:Number。图的画布的宽度和高度。

常用配置项

下面列举实例化图时常见的配置项,完整的配置项参见 Graph APIopen in new window

使用 canvas 或 svg 渲染

  • renderer

类型:String;默认:'canvas',可选项:'canvas' / 'svg' 。配置使用 canvas 或 svg 渲染,除 V3.3.x 外其他版本均支持。 G6 默认使用 Canvas 渲染图, SVG 渲染也支持 Canvas 的所有功能。需要注意的是,我们都知道 SVG 的性能较差,在大规模数据或图元的情况下请谨慎选择。SVG 除支持内置的所有节点/边类型以及自定义节点/边时使用与 Canvas 相同的图形外,还支持在自定义节点/边时使用 'dom' 图形,详见 使用 DOM 自定义节点open in new window

自适应画布

  • fitView

类型:Boolean;默认:'false'。图是否自适应画布。

  • fitViewPadding

类型:Number | Array;默认:0。图自适应画布时的四周留白像素值。fitViewtrue 时生效。

  • fitCenter

类型:Boolean;默认:'false'。是否平移图使其中心对齐到画布中心。v3.5.1 后支持。

全局元素配置

  • defaultNode

类型:Object。默认情况下全局节点的配置项,包括样式属性和其他属性。详见 内置节点open in new window 教程。

  • defaultEdge

类型:Object。默认情况下全局边的配置项,包括样式属性和其他属性。详见 内置边open in new window 教程。

  • nodeStateStyles

类型:Object。除默认状态外的其他状态下节点的样式配置。详见 状态 Stateopen in new window 教程。

  • edgeStateStyles

类型:Object。除默认状态外的其他状态下边的样式配置。详见 状态 Stateopen in new window 教程。

布局相关

  • layout

类型:Object。若数据中不存在节点位置,则默认为随机布局。配置布局类型及其参数。详见 使用布局 Layoutopen in new window 教程,图布局 APIopen in new window树图布局 APIopen in new window

交互行为相关

  • modes

类型:Array。配置多种交互模式及其包含的交互事件的。详见 交互模式 Modeopen in new window

动画相关

  • animate

类型:Boolean;默认:'false'。是否启用全局动画。启用后,布局变化时将会以动画形式变换节点位置。

  • animateCfg

类型:Object。全局动画的配置项,包括动画效果、动画时长等。详见 动画 Animationopen in new window

插件

  • plugins

类型:Array。配置辅助插件。详见 插件与工具open in new window

常用函数

在前面的代码中使用了两个必要的函数:

// 读取数据
graph.data(data);
// 渲染图
graph.render();
  • data(data):读取数据源 data 到图实例 graph 中。
  • render():渲染图。

Graph 的完整函数参见 Graph APIopen in new window

图元素总览

  • 图元素具有公共的通用属性和通用方法。图元素的属性包括:

图元素实例上具有对元素进行更新、销毁、获取属性、修改状态等通用方法open in new window,同时,对于实例的变更也可以通过调用 graphopen in new window 上的方法进行。

图形 Shape 与 keyShape

阅读时间约 2 分钟

图形 Shape

Shape 指 G6 中的图形、形状,它可以是圆形、矩形、路径等。它一般与 G6 中的节点、边、Combo 相关。G6 中的每一种节点/边/ Combo 由一个或多个 Shape 组成。节点、边、Combo、标签文本的配置都会被体现到对应的图形上。

KeyShape

如上所述,每一种节点/边/ Combo 都有一个唯一的关键图形 keyShape。keyShape 是在节点/边/ Combo 的 draw() 方法或 drawShape() 方法中返回的图形对象。它有两个主要特点:

响应样式

内置节点/边/ Combo 配置项中的 style 只体现在它的 keyShape 上。而内置节点/边/ Combo 的状态样式 (图实例的 nodeStateStyles / edgeStateStyles / comboStateStyles 或元素自身的 stateStyles) 中需要体现在 keyShape 或其他图形上的写法有所不同,详见 配置状态样式open in new window

想要更自由地响应样式(绘制或状态变化时),可以 自定义节点open in new window / 自定义边open in new window / 自定义 Comboopen in new window

Shape 的生命周期

当用户需要自定义节点open in new window自定义边open in new window自定义 Comboopen in new window 时,需要了解 Shape 的生命周期。使用内置节点/边/ Combo 则可以跳过这一部分内容。

从整体来看,Shape 的生命周期分为:

  • 初始化渲染;
  • 更新;
  • 操作;
  • 销毁。

Shape 作为 Graph 上的核心元素,这几个阶段都需要考虑,但是销毁可以交给 Graph 来处理,所以在定义 Shape 时不需要考虑,仅需要考虑三个阶段即可:

  • 绘制:从无到有的绘制 Shape 及文本;
  • 更新:数据发生改变导致 Shape 及文本发生变化;
  • 操作:给 Shape 添加状态,如:selected,active 等。

所以我们在设计自定义节点/边/ Combo 时,定义了三个方法,若需要自定义节点/边/ Combo ,需要有选择性地复写它们:

  • draw(cfg, group): 绘制,提供了绘制的配置项(数据定义时透传过来)和图形容器,必须返回合理的图形作为 keyShape;
  • update(cfg, n): 更新,更新时的配置项(更新的字段和原始字段的合并)和元素对象;
  • setState(name, value, item): 响应节点/边/ Combo 状态的变化。

关于自定义节点和边的更多方法请参考 自定义节点与边 APIopen in new window

G6 中的元素(节点/边)是由一个或多个图形 Shapeopen in new window 组成,主要通过自定义节点或自定义边时在 draw 方法中使用 group.addShape 添加,G6 中支持以下的图形 Shape:

各图形 Shape 的通用属性

属性名含义备注
fill设置用于填充绘画的颜色、渐变或模式对应 Canvas 属性 fillStyle
stroke设置用于笔触的颜色、渐变或模式对应 Canvas 属性 strokeStyle
lineWidth描边宽度
lineDash描边虚线Number[] 类型代表实、虚长度
shadowColor设置用于阴影的颜色
shadowBlur设置用于阴影的模糊级别数值越大,越模糊
shadowOffsetX设置阴影距形状的水平距离
shadowOffsetY设置阴影距形状的垂直距离
opacity设置绘图的当前 alpha 或透明值对应 Canvas 属性 globalAlpha
fillOpacity设置填充的 alpha 或透明值
cursor鼠标在该节点上时的鼠标样式,CSS 的 cursoropen in new window 选项都支持

用法

group.addShape('rect', {
  attrs: {
    fill: 'red',
    shadowOffsetX: 10,
    shadowOffsetY: 10,
    shadowColor: 'blue',
    shadowBlur: 10,
    opacity: 0.8,
  },
  // must be assigned in G6 3.3 and later versions. it can be any value you want
  name: 'rect-shape',
});

各图形 Shape 的通用方法

attr()

设置或获取实例的绘图属性。

attr(name)

获取实例的属性值。

const width = shape.attr('width');

attr(name, value)

更新实例的单个绘图属性。

attr({...})

批量更新实例绘图属性。

rect.attr({
    fill: '#999',
    stroke: '#666'
});

圆图形 Circle

属性

属性名含义
x圆心的 x 坐标
y圆心的 y 坐标
r圆的半径

用法

group.addShape('circle', {
  attrs: {
    x: 100,
    y: 100,
    r: 50,
    fill: 'blue',
  },
  // must be assigned in G6 3.3 and later versions. it can be any value you want
  name: 'circle-shape',
});

矩形图形 Rect

属性

属性名含义备注
x矩形左上角的 x 坐标
y矩形左上角的 y 坐标
width矩形的宽度
height矩形的高度
radius定义圆角支持整数或数组形式, 分别对应左上、右上、右下、左下角的半径: - radius 缩写为 1 或 [ 1 ] 相当于 [ 1, 1, 1, 1 ] - radius 缩写为 [ 1, 2 ] 相当于 [ 1, 2, 1, 2 ] - radius 缩写为 [ 1, 2, 3 ] 相当于 [ 1, 2, 3, 2 ]

用法

group.addShape('rect', {
  attrs: {
    x: 150,
    y: 150,
    width: 150,
    height: 150,
    stroke: 'black',
    radius: [2, 4],
  },
  // must be assigned in G6 3.3 and later versions. it can be any value you want
  name: 'rect-shape',
});

椭圆图形 Ellipse

属性

属性名含义
x圆心的 x 坐标
y圆心的 y 坐标
rx水平半径
ry垂直半径

用法

group.addShape('ellipse', {
  attrs: {
    x: 100,
    y: 100,
    rx: 50,
    ry: 50,
    fill: 'blue',
  },
  // must be assigned in G6 3.3 and later versions. it can be any value you want
  name: 'ellipse-shape',
});

多边形图形 Polygon

属性

属性名含义备注
points多边形的所有端点坐标数组形式

用法

group.addShape('polygon', {
  attrs: {
    points: [
      [30, 30],
      [40, 20],
      [30, 50],
      [60, 100],
    ],
    fill: 'red',
  },
  // must be assigned in G6 3.3 and later versions. it can be any value you want
  name: 'polygon-shape',
});

图片图形 Image

属性

属性名含义备注
x图片左上角的 x 坐标
y图片左上角的 y 坐标
width图片宽度
height图片高度
img图片源G6 支持多种格式的图片:url、ImageData、Image、canvas

用法

group.addShape('image', {
  attrs: {
    x: 0,
    y: 0,
    img: 'https://g.alicdn.com/cm-design/arms-trace/1.0.155/styles/armsTrace/images/TAIR.png',
  },
  // must be assigned in G6 3.3 and later versions. it can be any value you want
  name: 'image-shape',
});

路径 Path

⚠️ 注意: 当边太细交互不易命中时,请设置 lineAppendWidth 属性值。

属性

属性名含义备注
path线条路径可以是 String 形式,也可以是线段的数组。
startArrow起始端的箭头true 时在边的结束端绘制默认箭头,为 false 时不绘制结束端箭头。也可以是一个通过 path 自定义的箭头
endArrow末尾端的箭头true 时在边的开始端绘制默认箭头,为 false 时不绘制开始端箭头。也可以是一个通过 path 自定义的箭头
lineAppendWidth边的击中范围提升边的击中范围,扩展响应范围,数值越大,响应范围越广
lineCap设置线条的结束端点样式
lineJoin设置两条线相交时,所创建的拐角形状
lineWidth设置当前的线条宽度
miterLimit设置最大斜接长度
lineDash设置线的虚线样式,可以指定一个数组一组描述交替绘制线段和间距(坐标空间单位)长度的数字。 如果数组元素的数量是奇数, 数组的元素会被复制并重复。例如, [5, 15, 25] 会变成 [5, 15, 25, 5, 15, 25]。

用法

group.addShape('path', {
  attrs: {
    startArrow: {
      // 自定义箭头指向(0, 0),尾部朝向 x 轴正方向的 path
      path: 'M 0,0 L 20,10 L 20,-10 Z',
      // 箭头的偏移量,负值代表向 x 轴正方向移动
      // d: -10,
    },
    endArrow: {
      // 自定义箭头指向(0, 0),尾部朝向 x 轴正方向的 path
      path: 'M 0,0 L 20,10 L 20,-10 Z',
      // 箭头的偏移量,负值代表向 x 轴正方向移动
      // d: -10,
    },
    path: [
      ['M', 100, 100],
      ['L', 200, 200],
    ],
    stroke: '#000',
    lineWidth: 8,
    lineAppendWidth: 5,
  },
  // must be assigned in G6 3.3 and later versions. it can be any value you want
  name: 'path-shape',
});

文本 Text

属性

属性名含义备注
fill设置用于填充绘画的颜色、渐变或模式对应 Canvas 属性 fillStyle
stroke设置用于笔触的颜色、渐变或模式对应 Canvas 属性 strokeStyle
shadowColor设置用于阴影的颜色
shadowBlur设置用于阴影的模糊级别数值越大,越模糊
shadowOffsetX设置阴影距形状的水平距离
shadowOffsetY设置阴影距形状的垂直距离
opacity设置绘图的当前 alpha 或透明值对应 Canvas 属性 globalAlpha
textAlign设置文本内容的当前对齐方式支持的属性:center / end / left / right / start,默认值为 start
textBaseline设置在绘制文本时使用的当前文本基线支持的属性: top / middle / bottom / alphabetic / hanging。默认值为 bottom
fontStyle字体样式对应 font-style
fontVariant设置为小型大写字母字体对应 font-variant
fontWeight字体粗细对应 font-weight
fontSize字体大小对应 font-size
fontFamily字体系列对应 font-family
lineHeight行高对应 line-height

用法

group.addShape('text', {
  attrs: {
    text: 'test text',
    x: 0,
    y: 10,
    fontSize: 14,
    textAlign: 'left',
    textBaseline: 'middle',
    fill: '#0000D9',
  },
  // must be assigned in G6 3.3 and later versions. it can be any value you want
  name: 'text-shape',
});

DOM svg

  • 仅在 Graph 的 renderer'svg' 时可以使用。

⚠️ 注意:

  • 只支持原生 HTML DOM,不支持各类 react、vue 组件;
  • 使用 dom 进行自定义的节点或边,不支持 G6 的交互事件,请使用原生 DOM 的交互事件。

特殊属性

属性名含义备注
htmlDOM 的 html 值

用法

group.addShape('dom', {
  attrs: {
    width: cfg.size[0],
    height: cfg.size[1],
    // DOM's html
    html: `
    <div style="background-color: #fff; border: 2px solid #5B8FF9; border-radius: 5px; width: ${
      cfg.size[0] - 5
    }px; height: ${cfg.size[1] - 5}px; display: flex;">
      <div style="height: 100%; width: 33%; background-color: #CDDDFD">
        <img alt="img" style="line-height: 100%; padding-top: 6px; padding-left: 8px;" src="https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*Q_FQT6nwEC8AAAAAAAAAAABkARQnAQ" width="20" height="20" />  
      </div>
      <span style="margin:auto; padding:auto; color: #5B8FF9">${cfg.label}</span>
    </div>
      `,
  },
  // must be assigned in G6 3.3 and later versions. it can be any value you want
  name: 'dom-shape',
  draggable: true,
});

内置节点类型说明

下面表格中显示了内置的各类节点,同时对一些特殊的字段进行了说明:

名称描述默认示例
circle圆形: - size 是单个数字,表示直径 - 圆心位置对应节点的位置 - color 字段默认在描边上生效 - 标签文本默认在节点中央 - 更多字段见 Circleopen in new window 节点教程img
rect矩形: - size 是数组,例如:[100, 50] - 矩形的中心位置是节点的位置,而不是左上角 - color 字段默认在描边上生效 - 标签文本默认在节点中央 - 更多字段见 Rectopen in new window 节点教程img
ellipse椭圆: - size 是数组,表示椭圆的长轴直径和短轴直径 - 椭圆的圆心是节点的位置 - color 字段默认在描边上生效 - 标签文本默认在节点中央 - 更多字段见 Ellipseopen in new window 节点教程img
diamond菱形: - size 是数组,表示菱形的宽和高 - 菱形的中心位置是节点的位置 - color 字段默认在描边上生效 - 标签文本默认在节点中央 - 更多字段见 Diamondopen in new window 节点教程img
triangle三角形: - size 是数组,表示三角形的底和高 - 三角形的中心位置是节点的位置 - color 字段默认在描边上生效 - 标签文本默认在节点下方 - 更多字段见 Triangleopen in new window 节点教程img
star星形: - size 是单个数字,表示星形的大小 - 星星的中心位置是节点的位置 - color 字段默认在描边上生效 - 标签文本默认在节点中央 - 更多字段见 Staropen in new window 节点教程img
image图片: - size 是数组,表示图片的宽和高 - 图片的中心位置是节点位置 - img 图片的路径,也可以在 style 里面设置 - color 字段不生效 - 标签文本默认在节点下方 - 更多字段见 Imageopen in new window 节点教程img
modelRect卡片: - size 是数组,表示卡片的宽和高 - 卡片的中心位置是节点的位置 - color 字段默认在描边上生效 - 标签文本默认在节点中央 - 若有 description 字段则显示在标签文本下方显示 description 内容 - 更多字段见 ModelRectopen in new window 节点教程img img
donut圆形: - size 是单个数字,表示直径 - 圆心位置对应节点的位置 - color 字段默认在描边上生效 - 标签文本默认在节点中央 - 必须指定合法的 donutAttrs 字段 - 更多字段见 Donutopen in new window 节点教程img

节点的通用属性

所有内置的节点支持的通用属性:

名称是否必须类型备注
idtrueString节点唯一 ID,必须是唯一的 string
xfalseNumberx 坐标
yfalseNumbery 坐标
typefalseString指定节点类型,内置节点类型名称或自定义节点的名称。默认为 'circle'
sizefalseNumber / Array节点的大小
anchorPointsfalseArray指定边连入节点的连接点的位置(相对于该节点而言),可以为空。例如: [0, 0],代表节点左上角的锚点,[1, 1],代表节点右下角的锚点
stylefalseObject节点的样式属性。
labelfalseString文本文字
labelCfgfalseObject文本配置项

样式属性 style

Object 类型。通过 style 配置来修改节点的填充色、边框颜色、阴影等属性。下表是 style 对象中常用的配置项:

名称是否必须类型备注
fillfalseString节点填充色
strokefalseString节点的描边颜色
lineWidthfalseNumber描边宽度
lineDashfalseNumber[]描边虚线,数组代表实、虚长度
shadowColorfalseString阴影颜色
shadowBlurfalseNumber阴影范围
shadowOffsetXfalseNumber阴影 x 方向偏移量
shadowOffsetYfalseNumber阴影 y 方向偏移量
opacityfalseNumber设置绘图的当前 alpha 或透明值
fillOpacityfalseNumber设置填充的 alpha 或透明值
cursorfalseString鼠标在该节点上时的鼠标样式,CSS 的 cursoropen in new window 选项都支持

下面代码演示在实例化图时全局配置方法中配置 style

const graph = new G6.Graph({
  container: 'mountNode',
  width: 800,
  height: 600,
  defaultNode: {
    // ... 其他属性
    style: {
      fill: '#steelblue',
      stroke: '#eaff8f',
      lineWidth: 5,
      // ... 其他属性
    },
  },
});

标签文本 label 及其配置 labelCfg

label String 类型。标签文本的文字内容。 labelCfg Object 类型。配置标签文本。下面是 labelCfg 对象中的常用配置项:

名称是否必须类型备注
positionfalseString文本相对于节点的位置,目前支持的位置有:'center''top''left''right''bottom'。默认为 'center'。modelRect 节点不支持该属性
offsetfalseNumber文本的偏移,position'bottom' 时,文本的上方偏移量;position'left' 时,文本的右方偏移量;以此类推在其他 position 时的情况。modelRect 节点的 offset 为左边距
stylefalseObject标签的样式属性。

上表中的标签的样式属性 style 的常用配置项如下:

名称是否必须类型备注
fillfalseString文本颜色
strokefalseString文本描边颜色
lineWidthfalseNumber文本描边粗细
opacityfalseNumber文本透明度
fontFamilyfalseString文本字体
fontSizefalseNumber文本字体大小
... 节点标签与边标签样式属性相同,统一整理在 Text 图形 APIopen in new window

下面代码演示在实例化图时全局配置方法中配置 labellabelCfg

const graph = new G6.Graph({
  container: 'mountNode',
  width: 800,
  height: 600,
  defaultNode: {
    // ... 其他属性
    label: 'node-label',
    labelCfg: {
      position: 'bottom',
      offset: 10,
      style: {
        fill: '#666',
      },
    },
  },
});

节点的配置方法

配置节点的方式有三种:实例化图时全局配置,在数据中动态配置,使用 graph.node(nodeFn) 函数配置。这几种配置方法可以同时使用,优先级:

使用 graph.node(nodeFn) 配置 > 数据中动态配置 > 实例化图时全局配置

即有相同的配置项时,优先级高的方式将会覆盖优先级低的。

⚠️ 注意:idlabel 应当配置到每个节点数据中外,其余的 节点的通用属性open in new window 以及各个节点类型的特有属性(见内置节点类型)均支持这三种配置方式。

实例化图时全局配置

用户在实例化 Graph 时候可以通过 defaultNode 配置节点,这里的配置是全局的配置,将会在所有节点上生效。

const graph = new G6.Graph({
  container: 'mountNode',
  width: 800,
  height: 600,
  defaultNode: {
    type: 'circle',
    // 其他配置
  },
});

在数据中动态配置

如果需要为不同节点进行不同的配置,可以将配置写入到节点数据中。这种配置方式可以通过下面代码的形式直接写入数据,也可以通过遍历数据的方式写入。

const data = {
  nodes: [{
    id: 'node0',
    size: 100,
    type: 'rect',
    ...    // 其他属性
    style: {
      ...  // 样式属性,每种节点的详细样式属性参见各节点文档
    }
  },{
    id: 'node1',
    size: [50, 100],
    type: 'ellipse',
    ...    // 其他属性
    style: {
      ...  // 样式属性,每种节点的详细样式属性参见各节点文档
    }
  },
    ... // 其他节点
  ],
  edges: [
    ... // 边
  ]
}

节点的连接点 anchorPoint

节点的连接点 anchorPoint 指的是边连入节点的相对位置,即节点与其相关边的交点位置。anchorPoints 是一个二维数组,每一项表示一个连接点的位置,在一个图形 Shapeopen in new window 中,连接点的位置如下图所示,x 和 y 方向上范围都是 [0, 1]: img

节点中有了 anchorPoints 之后,相关边可以分别选择连入起始点、结束点的哪一个 anchorPoint。当需要在节点之间连多条线时,这种机制能够使边的连入更美观。

边可以通过指定 sourceAnchortargetAnchor 分别选择起始点、结束点的 anchorPoint。sourceAnchortargetAnchor 取的值是相对应节点上 anchorPoints 数组的索引值。

下面数据演示了如何在节点上配置连接点、在边上指定连接点:

const data = {
  nodes: [
    {
      id: 'node1',
      label: 'node1',
      x: 100,
      y: 200,
      // 该节点可选的连接点集合,该点有两个可选的连接点
      anchorPoints: [
        [0, 1],
        [0.5, 1],
      ],
      type: 'rect',
    },
    {
      id: 'node2',
      label: 'node2',
      x: 300,
      y: 400,
      // 该节点可选的连接点集合,该点有两个可选的连接点
      anchorPoints: [
        [0.5, 0],
        [1, 0.5],
      ],
      type: 'rect',
    },
  ],
  edges: [
    {
      source: 'node1',
      target: 'node2',
      // 该边连入 source 点的第 0 个 anchorPoint,
      sourceAnchor: 0,
      // 该边连入 target 点的第 0 个 anchorPoint,
      targetAnchor: 0,
      style: {
        endArrow: true,
      },
    },
    {
      source: 'node2',
      target: 'node1',
      // 该边连入 source 点的第 1 个 anchorPoint,
      sourceAnchor: 1,
      // 该边连入 source 点的第 1 个 anchorPoint,
      targetAnchor: 1,
      style: {
        endArrow: true,
      },
    },
  ],
};

自定义节点

G6.registerNode(typeName: string, nodeDefinition: object, extendedTypeName?: string) 进行自定义节点,方便用户开发更加定制化的节点,包括含有复杂图形的节点、复杂交互的节点、带有动画的节点等。其参数:

  • typeName:该新节点类型名称;
  • extendedTypeName:被继承的节点类型,可以是内置节点类型名,也可以是其他自定义节点的类型名。extendedTypeName 未指定时代表不继承其他类型的节点;
  • nodeDefinition:该新节点类型的定义,其中必要函数详见 自定义机制 APIopen in new window。当有 extendedTypeName 时,没被复写的函数将会继承 extendedTypeName 的定义。

使用 DOM 自定义节点

SVG 与 DOM 图形在 V3.3.x 中不支持。 仅在 Graph 的 renderer'svg' 时可以使用 DOM 自定义节点。

这里,我们演示使用 DOM 自定义一个名为 'dom-node' 的节点。在 draw 方法中使用 group.addShape 增加一个 'dom' 类型的图形,并设置其 html 为 DOM 的 html 值。

img

G6.registerNode(
  'dom-node',
  {
    draw: (cfg: ModelConfig, group: Group) => {
      return group.addShape('dom', {
        attrs: {
          width: cfg.size[0],
          height: cfg.size[1],
          // 传入 DOM 的 html
          html: `
        <div style="background-color: #fff; border: 2px solid #5B8FF9; border-radius: 5px; width: ${
          cfg.size[0] - 5
        }px; height: ${cfg.size[1] - 5}px; display: flex;">
          <div style="height: 100%; width: 33%; background-color: #CDDDFD">
            <img alt="img" style="line-height: 100%; padding-top: 6px; padding-left: 8px;" src="https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*Q_FQT6nwEC8AAAAAAAAAAABkARQnAQ" width="20" height="20" />  
          </div>
          <span style="margin:auto; padding:auto; color: #5B8FF9">${cfg.label}</span>
        </div>
          `,
        },
        draggable: true,
      });
    },
  },
  'single-node',
);

上面的代码自定义了一个名为 'dom-node' 的带有 DOM 的节点。值得注意的是,G6 3.3 需要用户为自定义节点中的图形设置 namedraggable。其中,name 可以是不唯一的任意值。draggabletrue 是表示允许该图形响应鼠标的拖拽事件,只有 draggable: true 时,图上的交互行为 'drag-node' 才能在该图形上生效。

现在,我们使用下面的数据输入就会绘制出带有 'dom-node' 节点的图。

img

const data = {
  nodes: [
    { id: 'node1', x: 50, y: 100 },
    { id: 'node2', x: 150, y: 100 },
  ],
  edges: [(source: 'node1'), (target: 'node2')],
};
const graph = new G6.Graph({
  container: 'mountNode',
  width: 500,
  height: 500,
  defaultNode: {
    type: 'dom-node',
    size: [120, 40],
  },
});
graph.data(data);
graph.render();

⚠️ 注意: G6 的节点/边事件不支持 DOM 类型的图形。如果需要为 DOM 节点绑定事件,请使用原生 DOM 事件。例如:

G6.registerNode(
  'dom-node',
  {
    draw: (cfg: ModelConfig, group: Group) => {
      return group.addShape('dom', {
        attrs: {
          width: cfg.size[0],
          height: cfg.size[1],
          // 传入 DOM 的 html,带有原生 onclick 事件
          html: `
        <div onclick="alert('Hi')" style="background-color: #fff; border: 2px solid #5B8FF9; border-radius: 5px; width: ${
          cfg.size[0] - 5
        }px; height: ${cfg.size[1] - 5}px; display: flex;">
          <div style="height: 100%; width: 33%; background-color: #CDDDFD">
            <img alt="img" style="line-height: 100%; padding-top: 6px; padding-left: 8px;" src="https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*Q_FQT6nwEC8AAAAAAAAAAABkARQnAQ" width="20" height="20" />  
          </div>
          <span style="margin:auto; padding:auto; color: #5B8FF9">${cfg.label}</span>
        </div>
          `,
        },
        draggable: true,
      });
    },
  },
  'single-node',
);

边总览

G6 提供了 9 种内置边:

  • line:直线,不支持控制点;
  • polyline:折线,支持多个控制点;
  • arc:圆弧线;
  • quadratic:二阶贝塞尔曲线;
  • cubic:三阶贝塞尔曲线;
  • cubic-vertical:垂直方向的三阶贝塞尔曲线,不考虑用户从外部传入的控制点;
  • cubic-horizontal:水平方向的三阶贝塞尔曲线,不考虑用户从外部传入的控制点;
  • loop:自环。

内置边类型说明

下面表格中显示了内置的各类边,同时对一些特殊的字段进行了说明:

名称描述
line连接两个节点的直线: - controlPoints 不生效 - 更多配置详见 line 边的配置img
polyline多段线段构成的折线,连接两个端点: - controlPoints 表示所有线段的拐点,不指定时根据 A* 算法open in new window自动生成折线 - 更多配置详见 polyline 边的配置img
arc连接两个节点的一段圆弧: - controlPoints 不生效 - 使用 curveOffset 指定弧的弯曲程度,其正负影响弧弯曲的方向 - 更多配置详见 arc 边的配置img
quadratic只有一个控制点的曲线: - controlPoints 不指定时,会默认线的一半处弯曲 - 更多配置详见 quadratic 边的配置img
cubic有两个控制点的曲线: - controlPoints 不指定时,会默认线的 1/3, 2/3 处弯曲 - 更多配置详见 cubic 边的配置img
cubic-vertical垂直方向的三阶贝塞尔曲线,不考虑用户从外部传入的控制点img
cubic-horizontal水平方向的三阶贝塞尔曲线,不考虑用户从外部传入的控制点img
loop自环。更多配置详见 loop 边的配置img

边的通用属性

所有内置的边支持的通用属性:

名称是否必须类型备注
idfalseString边唯一 ID,必须是唯一的 string
sourcetrueStringNumber起始点 id
targettrueString结束点 id
typefalseString指定边的类型,可以是内置边的类型名称,也可以是自定义边的名称。默认为 'line'
sourceAnchorfalseNumber边的起始节点上的锚点的索引值
targetAnchorfalseNumber边的终止节点上的锚点的索引值
stylefalseObject边的样式属性
labelfalseString文本文字,如果没有则不会显示
labelCfgfalseObject文本配置项

样式属性 style

Object 类型。通过 style 配置来修改边的颜色、线宽等属性。下表是 style 对象中常用的配置项:

名称是否必须类型备注
strokefalseString边的颜色
lineWidthfalseNumber边宽度
lineAppendWidthfalseNumber边响应鼠标事件时的检测宽度,当 lineWidth 太小而不易选中时,可以通过该参数提升击中范围
endArrowfalseBoolean / Objecttrue 时在边的结束端绘制默认箭头,为 false 时不绘制结束端箭头;也可以使用内置箭头配置open in new window,例如: endArrow: { path: G6.Arrow.vee(10, 20, 10), // 内置箭头,参数为箭头宽度、长度、偏移量 d(默认为 0) d: 10 // 偏移量 } ;或通过 path 自定义的箭头,例如: endArrow: { path: 'M 0,0 L 20,10 L 20,-10 Z', // 自定义箭头路径 d: -2 // 偏移量 }
startArrowfalseBoolean / Objecttrue 时在边的开始端绘制默认箭头,为 false 时不绘制结束端箭头;也可以使用内置箭头配置open in new window,例如: startArrow: { path: G6.Arrow.vee(10, 20, 10), // 内置箭头,参数为箭头宽度、长度、偏移量 d(默认为 0) d: 10 // 偏移量 } ;或通过 path 自定义的箭头,例如: startArrow: { path: 'M 0,0 L 20,10 L 20,-10 Z', // 自定义箭头路径 d: -2 // 偏移量 }
strokeOpacityfalseNumber边透明度
shadowColorfalseString阴影颜色
shadowBlurfalseNumber阴影模糊程度
shadowOffsetXfalseNumber阴影 x 方向偏移量
shadowOffsetYfalseNumber阴影 y 方向偏移量
lineDashfalseArray设置线的虚线样式,可以指定一个数组。一组描述交替绘制线段和间距(坐标空间单位)长度的数字。 如果数组元素的数量是奇数, 数组的元素会被复制并重复。例如, [5, 15, 25] 会变成 [5, 15, 25, 5, 15, 25]。
cursorfalseString鼠标在该边上时的鼠标样式,CSS 的 cursoropen in new window 选项都支持

下面代码演示在实例化图时全局配置方法中配置 style

const graph = new G6.Graph({
  container: 'mountNode',
  width: 800,
  height: 600,
  defaultEdge: {
    // ... 其他属性
    style: {
      stroke: '#eaff8f',
      lineWidth: 5,
      // ... 其他样式属性
    },
  },
});

标签文本 label 及其配置 labelCfg

label String 类型。标签文本的文字内容。 labelCfg Object 类型。配置标签文本。下面是 labelCfg 对象中的常用配置项:

名称是否必须类型备注
refXfalseNumber标签在 x 方向的偏移量
refYfalseNumber标签在 y 方向的偏移量
positionfalseString文本相对于边的位置,目前支持的位置有:'start''middle''end'。默认为'middle'
autoRotatefalseBoolean标签文字是否跟随边旋转,默认 false
stylefalseObject标签的样式属性

上表中的标签的样式属性 style 的常用配置项如下:

名称是否必须类型备注
fillfalseString文本颜色
strokefalseString文本描边颜色
lineWidthfalseNumber文本描边粗细
opacityfalseNumber文本透明度
fontFamilyfalseString文本字体
fontSizefalseNumber文本字体大小
... 节点标签与边标签样式属性相同,统一整理在 Text 图形 APIopen in new window

下面代码演示在实例化图时全局配置方法中配置 labellabelCfg

const graph = new G6.Graph({
  container: 'mountNode',
  width: 800,
  height: 600,
  defaultEdge: {
    // ... 其他属性
    label: 'edge-label',
    labelCfg: {
      refY: -10,
      refX: 60,
    },
  },
});

边的配置方法

配置边的方式有三种:实例化图时全局配置,在数据中动态配置,使用 graph.edge(edgeFn) 函数配置。这几种配置方法可以同时使用,优先级:

使用 graph.edge(edgeFn) 配置 > 数据中动态配置 > 实例化图时全局配置

即有相同的配置项时,优先级高的方式将会覆盖优先级低的。

idsourcetargetlabel 应当配置到每条边数据中外,其余的 边的通用属性open in new window 以及各个边类型的特有属性(见内置边类型)均支持三种配置方式。

实例化图时全局配置

用户在实例化 Graph 时候可以通过 defaultEdge 配置边,这里的配置是全局的配置,将会在所有边上生效。

const graph = new G6.Graph({
  container: 'mountNode',
  width: 800,
  height: 600,
  defaultEdge: {
    type: 'line',
    // ... 其他配置
  },
});

在数据中动态配置

如果需要使不同边有不同的配置,可以将配置写入到边数据中。这种配置方式可以通过下面代码的形式直接写入数据,也可以通过遍历数据的方式写入。

const data = {
  nodes: [
    ... // 节点
  ],
  edges: [{
    source: 'node0',
    target: 'node1'
    type: 'polyline',
    ... // 其他配置
    style: {
      ...  // 样式属性,每种边的详细样式属性参见各边文档
    }
  },{
    source: 'node1',
    target: 'node2'
    type: 'cubic',
    ... // 其他配置
    style: {
      ...  // 样式属性,每种边的详细样式属性参见各边文档
    }
  },
    ... // 其他边
  ]
}

使用 graph.edge()

该方法可以为不同边进行不同的配置。 提示:

  • 该方法必须在 render 之前调用,否则不起作用;
  • 由于该方法优先级最高,将覆盖其他地方对边的配置,这可能将造成一些其他配置不生效的疑惑;
  • 该方法在增加元素、更新元素时会被调用,如果数据量大、每条边上需要更新的内容多时,可能会有性能问题。
// const data = ...
// const graph = ...
graph.edge((edge) => {
  return {
    id: edge.id,
    type: 'polyline',
    style: {
      fill: 'steelblue',
    },
  };
});

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

默认箭头

img

使用方法

在边的样式属性 style 中将 endArrowstartArrow 配置为 true 即可:

style: {
  endArrow: true,
  startArrow: true
}

内置箭头

v3.5.8 后支持。

各箭头概览

名称参数使用方法效果
triangle依次为箭头宽度(默认 10)、长度(默认 15)、偏移量(默认为 0,与 d 对应)endArrow: { path: G6.Arrow.triangle(10, 20, 25), d: 25 }img
vee依次为箭头宽度(默认 15)、长度(默认 20)、偏移量(默认为 0,与 d 对应)endArrow: { path: G6.Arrow.vee(10, 20, 25), d: 25 }img
circle依次为箭头半径(默认 5)、偏移量(默认为 0,与 d 对应)endArrow: { path: G6.Arrow.circle(10, 25), d: 25 }img
diamond依次为箭头宽度(默认 15)、长度(默认 15)、偏移量(默认为 0,与 d 对应)endArrow: { path: G6.Arrow.diamond(10, 20, 25), d: 25 }img
rect依次为箭头宽度(默认 10)、长度(默认 10)、偏移量(默认为 0,与 d 对应)endArrow: { path: G6.Arrow.rect(10, 20, 25), d: 25 }img
triangleRect依次为箭头三角形宽度(默认 15)、三角形长度(默认 15)、矩形宽度(默认 15)、矩形长度(默认 3)、三角形与矩形间距(默认为 5)、偏移量(默认为 0,与 d 对应)endArrow: { path: G6.Arrow.triangleRect(15, 15, 15, 3, 5, 25), d: 25 }img

使用方法

调用 G6.Arrow.arrowName 配置边的样式属性 styleendArrowstartArrowpath

style: {
  endArrow: {
    path: G6.Arrow.triangle(10, 20, 25), // 使用内置箭头路径函数,参数为箭头的 宽度、长度、偏移量(默认为 0,与 d 对应)
    d: 25
  },
  startArrow: {
    path: G6.Arrow.vee(15, 20, 15), // 使用内置箭头路径函数,参数为箭头的 宽度、长度、偏移量(默认为 0,与 d 对应)
    d: 15
  },
}

配置箭头样式

只有内置箭头和自定义箭头可以配置样式。

配置项

名称是否必须类型备注
fillfalseString填充颜色,默认无填充
strokefalseString描边颜色,默认与边颜色相同
lineWidthfalseNumber描边宽度,默认与边宽度相同
opacityfalseNumber透明度
shadowColorfalseString阴影颜色
shadowBlurfalseNumber阴影模糊程度
shadowOffsetXfalseNumber阴影 x 方向偏移量
shadowOffsetYfalseNumber阴影 y 方向偏移量
lineDashfalseArray描边的虚线样式,可以指定一个数组。一组描述交替绘制线段和间距(坐标空间单位)长度的数字。 如果数组元素的数量是奇数, 数组的元素会被复制并重复。例如, [5, 15, 25] 会变成 [5, 15, 25, 5, 15, 25]。

使用方法

// 内置箭头
style: {
  endArrow: {
    path: G6.Arrow.triangle(10, 20, 25), // 使用内置箭头路径函数,参数为箭头的 宽度、长度、偏移量(默认为 0,与 d 对应)
    d: 25,
    fill: '#f00',
    stroke: '#0f0',
    opacity: 0.5,
    lineWidth: 3,
    // ...
  },
}


// 自定义箭头
style: {
  endArrow: {
    path: 'M 0,0 L 20,10 L 20,-10 Z',
    d: 5,
    fill: '#f00',
    stroke: '#0f0',
    opacity: 0.5,
    lineWidth: 3,
    // ...
  },
}

攻击范围

边过细时点击很难被击中,可以设置 lineAppendWidth 来提升击中范围。

增加额外图形

通过实现 afterDraw 增加额外图形,为找到边的主要图形 path 上的某个点,可以使用 shape.getPoint(ratio) 获得。

img

G6.registerEdge(
  'mid-point-edge',
  {
    afterDraw(cfg, group) {
      // 获取图形组中的第一个图形,在这里就是边的路径图形
      const shape = group.get('children')[0];
      // 获取路径图形的中点坐标
      const midPoint = shape.getPoint(0.5);
      // 在中点增加一个矩形,注意矩形的原点在其左上角
      group.addShape('rect', {
        attrs: {
          width: 10,
          height: 10,
          fill: '#f00',
          // x 和 y 分别减去 width / 2 与 height / 2,使矩形中心在 midPoint 上
          x: midPoint.x - 5,
          y: midPoint.y - 5,
        },
      });
    },
    update: undefined,
  },
  'cubic',
);

更新节点或边的样式

阅读时间约 1 分钟

G6 提供了三种修改节点样式的方法。

实例化 Graph

实例化 Graph 时,可以通过在 defaultNodedefaultEdge 中指定 style 分别配置全局节点和全局边的样式属性。

const graph = new G6.Graph({
  container: 'mountNode',
  width: 1000,
  height: 800,
  defaultNode: {
    type: 'circle',
    style: {
      fill: '#fff',
      fontSize: 14,
    },
  },
  defaultEdge: {
    type: 'line-with-arrow',
    style: {
      fill: '#fff',
      fontSize: 14,
    },
  },
});

数据中指定 style

这种方式可以在数据中为不同的节点和边指定不同的样式。

const data = {
  nodes: [
    {
      id: 'node1',
      label: 'node1',
      style: {
        fill: '#fff',
        fontSize: 12,
      },
    },
  ],
};

使用 update / updateItem

使用 update / updateItem 更新节点或边。此方法用于动态更新节点或边的 keyShapeopen in new window

graph.updateItem(node, {
  // 节点的样式
  style: {
    stroke: 'blue',
  },
});

想要知道节点都支持哪些属性样式,请参考 节点样式属性open in new window

元素的显示/隐藏

使用下面六个函数可以实现节点、边、Combo 的显示/隐藏:

// 显示节点实例 nodeItem,该节点的 visible 属性值在该方法调用后被置为 true
nodeItem.show();

// 隐藏节点实例 nodeItem,该节点的 visible 属性值在该方法调用后被置为 false
nodeItem.hide();

// 显示边实例 edgeItem,该边的 visible 属性值在该方法调用后被置为 true
edgeItem.show();

// 隐藏边实例 edgeItem,该边的 visible 属性值在该方法调用后被置为 false
edgeItem.hide();

// 显示边实例 comboItem,该 Combo 的 visible 属性值在该方法调用后被置为 true
comboItem.show();

// 隐藏边实例 comboItem,该 Combo 的 visible 属性值在该方法调用后被置为 false
comboItem.hide();

示例

img

该示例摘取了元素显示/隐藏的相关操作部分,通过鼠标监听对节点、边、画布的点击事件,显示和隐藏元素:

// 鼠标点击节点,隐藏该节点
graph.on('node:click', (ev) => {
  const node = ev.item;
  console.log('before hide(), the nodevisible = ', node.get('visible'));
  node.hide();
  graph.paint();
  console.log('after hide(), the node visible = ', node.get('visible'));
});

// 鼠标点击边,隐藏该边
graph.on('edge:click', (ev) => {
  const edge = ev.item;
  console.log('before hide(), the edge visible = ', edge.get('visible'));
  edge.hide();
  graph.paint();
  console.log('after hide(), the edge visible = ', edge.get('visible'));
});

// 鼠标点击画布,显示所有节点和边
graph.on('canvas:click', (ev) => {
  const nodes = graph.getNodes();
  const edges = graph.getEdges();
  nodes.forEach((node) => {
    node.show();
  });
  edges.forEach((edge) => {
    edge.show();
  });
  graph.paint();
});
   // 2000 ms 后切换为允许节点重叠的 force 布局
      setTimeout(() => {
        graph.updateLayout('force'); // 参数为 String 代表布局名称
      }, 8000);

      // 4000 ms 后切换为不允许节点重叠且边长为 100 的 force 布局。
      setTimeout(() => {
        graph.updateLayout({
          type: 'force', // 布局名称
          preventOverlap: true, // 布局参数,是否允许重叠
          nodeSize: 40, // 布局参数,节点大小,用于判断节点是否重叠
          linkDistance: 100, // 布局参数,边长
        });
      }, 10000);

      // 6000 ms 后切换数据为 data2
      setTimeout(() => {
        graph.changeData(data2);
      }, 12000);

antv/g6添加图形image的img属性为静态图片的写法

img: require('@/aseets/images/logo.png')
 {
      id: 'node4',
      type: 'image',
      img: require('@/assets/image/g6/substation.png'),
      x: 500,
      y: 200,
      size: [50, 100],
      label: '变电所3'
    }
同vue使用图片的方式一样

监听和绑定事件

除了 内置交互行为 Behavioropen in new window交互模式 Modeopen in new window 搭配的事件管理方式外,G6 提供了直接的单个事件、时机的监听方法,可以监听画布、节点、边、以及各函数被调用的时机等。这些事件可以分为以下四个层次:

  • 画布、图形层次的事件,mousedownmouseupclickmouseentermouseleave 等;
  • 节点/边 上的事件,node:mousedownedge:click 等,以 type:eventName 为事件名称;
  • 时机事件:
    • 节点/边增删改时的事件, 例如:beforeadditemafteradditem 等;
    • 节点/边状态改变时的事件:beforerefreshitemafterrefreshitem
    • 布局时机:beforelayoutafterlayout

如果要了解 G6 支持的所有事件,请参考 Event APIopen in new window

G6 上所有的事件都需要在 graph 上监听。

graph.on('click', (ev) => {
  const shape = ev.target;
  const item = ev.item;
  if (item) {
    const type = item.getType();
  }
});

graph.on('node:click', (ev) => {
  const shape = ev.target;
  const node = ev.item;
});

Behavior

Behavior 是 G6 提供的定义图上交互事件的机制。它与交互模式 Modeopen in new window 搭配使用,如何将下文所述各种 Behavior 配置到图上,见 交互模式open in new window

内置 Behavior

理论上, G6 上的所有基础图形、Item(节点/边)都能通过事件来进行操作。