版本
@antv/g6": “^4.8.10”
场景
@antv/g6通过继承的方法实现自定义形状时,自定义的函数会复写被继承的形状的对应函数,导致被继承的形状的某些特性丢失,通过以下方法解决此问题
方法
代码语言:javascript复制import {registerNode, Shape} from "@antv/g6";
// 获取形状工厂
const shapeFactory = Shape.Node
// 获取被继承的形状定义
const extendShape = shapeFactory.getShape('circle')
register('my-circle',
{
afterDraw(cfg, group, rst) {
// 调用被继承的形状定义的逻辑
if (extendShape && extendShape.afterDraw) {
extendShape.afterDraw(cfg, group, rst)
}
// 执行自己的逻辑
},
setState(name?: string, value?: string | boolean, item?: Item) {
// 调用被继承的形状定义的逻辑
if (extendShape && extendShape.setState) {
extendShape.setState(name, value, item)
}
// 执行自己的逻辑
}
},
'circle'
);
源码分析
G6/packages/core/src/element/shape.ts 注册节点,边,组合的逻辑类似,以注册节点api为例
代码语言:javascript复制public static registerNode(
shapeType: string,
nodeDefinition: ShapeOptions | ShapeDefine,
extendShapeType?: string,
) {
// 已经注册的节点形状映射
const shapeFactory = Shape.Node;
let shapeObj;
if (typeof nodeDefinition === 'string' || typeof nodeDefinition === 'function') {
const autoNodeDefinition = createNodeFromXML(nodeDefinition);
shapeObj = { ...shapeFactory.getShape('single-node'), ...autoNodeDefinition };
} else if (nodeDefinition.jsx) {
const { jsx } = nodeDefinition;
const autoNodeDefinition = createNodeFromXML(jsx);
shapeObj = {
...shapeFactory.getShape('single-node'),
...autoNodeDefinition,
...nodeDefinition,
};
} else {
// 如果节点定义是对象,也就是配置选项形式
shapeFactory.getShape(extendShapeType);
// 1. 获取被继承的形状定义,如果被继承的定义不存在则使用一个空的定义实现ShapeFramework
const extendShape = extendShapeType ? shapeFactory.getShape(extendShapeType) : ShapeFramework;
// 2. 合并定义,被继承的形状定义中的成员被直接覆盖
shapeObj = { ...extendShape, ...nodeDefinition };
}
shapeObj.type = shapeType;
shapeObj.itemType = 'node';
shapeFactory[shapeType] = shapeObj;
return shapeObj;
}
public static registerEdge(
shapeType: string,
edgeDefinition: ShapeOptions,
extendShapeType?: string,
) {
const shapeFactory = Shape.Edge;
const extendShape = extendShapeType ? shapeFactory.getShape(extendShapeType) : ShapeFramework;
const shapeObj = { ...extendShape, ...edgeDefinition };
shapeObj.type = shapeType;
shapeObj.itemType = 'edge';
shapeFactory[shapeType] = shapeObj;
return shapeObj;
}