* docs: remove readme and navigation in site * docs: remove v4 core concept docs * docs: update history and lod plugin docs * chore: update dumirc config * docs: add api shape overview doc * docs: update manual docs * docs: update manual and tutorial docs * chore: update dumirc * docs: remove design sector * docs: update docs meta data * docs: update api docs
7.7 KiB
title | order |
---|---|
自定义边 | 2 |
示例
import { Graph as BaseGraph, extend, Extensions } from '@antv/g6';
// 自定义变类型,继承一个已有的边类型或边基类 Extensions.BaseEdge
class CustomNode extends Extensions.LineEdge {
// 覆写方法,可覆写的类方法见下文
}
const Graph = extend(BaseGraph, {
// 注册自定义边
edges: {
'custom-edge': CustomEdge,
},
});
const graph = new Graph({
// ... 其他配置
edge: {
type: 'custom-edge', // 使用注册的节点
},
});
覆写方法
draw
:::info{title=提示}
大多数情况下并不需要覆写 draw 方法,更常用的做法是覆写 drawKeyShape
、drawLabelShape
等方法,这些方法将在下文介绍。
:::
G5 5.0 移除了 update
和 afterUpdate
方法。现在只需要复写 draw
方法和 afterDraw
方法,G6 将自动根据更新的属性增量更新图形。
draw 方法通过调用 this.drawKeyShape
等方法分别绘制边各部分。
你可以参考 line-edge
类型边的 draw 方法进行覆写。
afterDraw
在 draw
函数完成之后执行的逻辑,也可以用于绘制更多的图形,返回值和 draw
方法一致。在内置的节点类型中,没有对它进行实现。
drawKeyShape
绘制主图形(keyShape
),该图形是必须的,例如直线边的主图形是一条直线(line
) 以及首尾箭头(arrow
),曲线边的主图形则将直线换成了曲线路径(path
)。
覆写 drawKeyShape
方法绘制直线边的示例如下:
public drawKeyShape(
model: EdgeDisplayModel,
sourcePoint: Point,
targetPoint: Point,
shapeMap: EdgeShapeMap,
) {
const { keyShape: keyShapeStyle } = this.mergedStyles;
const { startArrow, endArrow, ...others } = keyShapeStyle;
const lineStyle = {
...others,
x1: sourcePoint.x,
y1: sourcePoint.y,
z1: sourcePoint.z || 0,
x2: targetPoint.x,
y2: targetPoint.y,
z2: targetPoint.z || 0,
isBillboard: true,
};
// 绘制箭头
this.upsertArrow('start', startArrow, others, model, lineStyle);
this.upsertArrow('end', endArrow, others, model, lineStyle);
// 绘制并返回图形
return this.upsertShape('line', 'keyShape', lineStyle, shapeMap, model);
}
若要绘制曲线或折线,drawKeyShape
中应当根据控制点,计算路径。例如内置的 quadratic-edge
的 drawKeyShape
方法:
public drawKeyShape(
model: EdgeDisplayModel,
sourcePoint: Point,
targetPoint: Point,
shapeMap: EdgeShapeMap,
) {
const { keyShape: keyShapeStyle } = this.mergedStyles as any;
const { startArrow, endArrow, ...others } = keyShapeStyle;
// 根据弧度位置、弧度等信息计算控制点
const controlPoint = this.getControlPoints(
sourcePoint,
targetPoint,
keyShapeStyle.curvePosition,
keyShapeStyle.controlPoints,
keyShapeStyle.curveOffset,
)[0];
const lineStyle = {
...others,
path: [
['M', sourcePoint.x, sourcePoint.y],
['Q', controlPoint.x, controlPoint.y, targetPoint.x, targetPoint.y],
],
};
// 绘制箭头
this.upsertArrow('start', startArrow, others, model, lineStyle);
this.upsertArrow('end', endArrow, others, model, lineStyle);
// 绘制并返回图形
return this.upsertShape('path', 'keyShape', lineStyle, shapeMap, model);
}
其中,this.getControlPoints
可以进行复写,从而自定义控制点计算逻辑,见 getControlPoints。
drawHaloShape
绘制主图形轮廓图形(haloShape
),通常在 selected
, active
状态下显示。
若需要覆写,则可以参考 BaseEdge.drawHaloShape
drawLabelShape
绘制文本图形(labelShape
)
若需要覆写,则可以参考 BaseEdge.drawLabelShape
drawLabelBackgroundShape
绘制文本图形的背景框图形(labelBackgroundShape
)
若需要覆写,则可以参考 BaseEdge.drawLabelBackgroundShape
drawOtherShapes
绘制上述内容之外的图形,可以在 drawOtherShapes
中完成,例如额外创建一个圆形:
public drawOtherShapes(
model: EdgeDisplayModel,
shapeMap: EdgeShapeMap,
) {
return {
extraShape: upsertShape(
'circle',
'other-circle-shape',
{
r: 4,
fill: '#0f0',
x: -20,
y: 0,
},
shapeMap,
),
};
}
成员属性及方法
getControlPoints
获取控制点,通常用于计算路径。例如折线边的控制点是拐点,曲线边的控制点是曲线的控制点。
当继承 Extensions.PolylineEdge、Extensions.QuadraticEdge、Extensions.CubicEdge、Extensions.CubicHorizontalEdge、Extensions.CubicVerticalEdge 时,可以通过复写 getControlPoints
来修改控制点的逻辑。
Extensions.PolylineEdge
的 getControlPoints
类型为:
(
/** 边的渲染数据 */
model: EdgeDisplayModel,
/** 边的起点 */
sourcePoint: Point,
/** 边的终点 */
targetPoint: Point,
) =>
/** 计算后的控制点 */
{
x: number;
y: number;
z?: number;
}[]
Extensions.QuadraticEdge
、Extensions.CubicEdge
、Extensions.CubicHorizontalEdge
、Extensions.CubicVerticalEdge
的 getControlPoints
类型为:
(
/** 边的起点 */
startPoint: Point,
/** 边的终点 */
endPoint: Point,
/** 控制点的投影在两端点连线上的百分比,范围 0 到 1 */
percent: number,
/** 数据中控制点配置 */
controlPoints: Point[],
/** 弧度距离 */
offset: number,
) =>
/** 计算后的控制点 */
{
x: number;
y: number;
z?: number;
}[];
getPath
Extensions.PolylineEdge
的成员方法,仅在继承它来实现自定义边时可复写。由于折线的自动寻径算法比较复杂,因此单独抽出了这个函数。也由于算法复杂性,折线边的性能稍差。如果有确定的折线边绘制规则,可以通过继承内置折线边,自定义 getPath
方法覆盖自动寻径的逻辑。函数类型为:
(
/** 边的渲染数据 */
model: EdgeDisplayModel,
/** 起点和终点 */
points: Point[],
/** 折线拐点的弧度 */
radius: number,
/** 折线弯折的配置 */
routeCfg?: RouterCfg,
/** 是否使用 A* 算法 */
auto?: boolean,
) =>
/** 路径 */
string;
RouterCfg
type RouterCfg = {
name: 'orth' | 'er';
/** 线与点之间的间距 */
offset?: number;
/** 网格大小 */
gridSize?: number;
/** 最大旋转角度(弧度) */
maxAllowedDirectionChange?: number;
/** 允许的边的方向 */
directions?: any[];
/** 起点和终点的权重 */
penalties?: {};
/** 是否使用简单的折线拐点寻径算法 */
simple?: boolean;
/** 计算两点之间距离的函数 */
distFunc?: (p1: PolyPoint, p2: PolyPoint) => number;
/** 简化的寻径函数 */
fallbackRoute?: (p1: PolyPoint, p2: PolyPoint, startNode?: Node, endNode?: Node, cfg?: RouterCfg) => PolyPoint[];
/** 最大循环次数 */
maximumLoops?: number;
/** 是否自动避开障碍物,默认为 false */
enableObstacleAvoidance?: boolean;
};