Rappid/jointJS中fromJSON加载自定义形状失败及自定义形状需求求助
解决JointJS/Rappid自定义形状无法通过fromJSON加载的问题
我来帮你搞定这个问题!要创建属性和basic.Circle一致但带特定类型的自定义形状,同时解决fromJSON加载失败的问题,关键在于正确定义自定义形状并确保JointJS能识别它的类型标识,具体步骤如下:
1. 正确定义自定义形状
首先,我们要基于basic.Circle扩展出自己的自定义形状,核心是给它设置一个唯一的type属性——这是fromJSON能识别它的关键:
// 先创建自定义命名空间(可选,但更规范) joint.shapes.custom = joint.shapes.custom || {}; // 定义自定义的StartCircle形状 joint.shapes.custom.StartCircle = joint.shapes.basic.Circle.extend({ defaults: joint.util.deepSupplement({ type: 'custom.StartCircle', // 必须:唯一的类型标识,fromJSON靠这个匹配构造函数 size: { width: 5, height: 3 }, // 把固定尺寸也纳入默认属性,简化实例创建 attrs: { circle: { width: 50, height: 30, fill: '#602320' }, text: { text: 'START', fill: '#ffffff', 'font-size': 10, stroke: '#000000', 'stroke-width': 0 } } }, joint.shapes.basic.Circle.prototype.defaults) });
这里用joint.util.deepSupplement是为了安全合并父类的默认属性,避免覆盖basic.Circle原有的必要配置,保证形状功能完整。
2. 使用自定义形状创建实例
现在你可以直接用这个自定义形状创建节点,用法和basic.Circle一致,但它会自带你预设的属性和专属类型:
// 创建自定义形状实例,无需重复写attrs和size const startShape = new joint.shapes.custom.StartCircle(); // 如果需要临时修改属性,也可以传入参数覆盖默认值 const customStartShape = new joint.shapes.custom.StartCircle({ position: { x: 100, y: 100 }, attrs: { text: { text: 'MY START' } } });
3. 确保fromJSON能识别自定义形状
fromJSON加载失败最常见的原因是自定义形状的定义在调用graph.fromJSON()之后执行,导致JointJS找不到对应type的构造函数。解决办法很简单:
- 把自定义形状的定义代码放在页面加载的最前面,或者在初始化Graph、调用
fromJSON之前执行。
如果你的旧数据里用的是basic.Circle的type,想兼容这些历史数据,可以给自定义形状注册别名:
// 让JointJS将旧的basic.Circle类型映射到新的自定义形状 joint.shapes.basic.Circle.alias = 'custom.StartCircle';
4. 测试保存和加载流程
现在你可以正常完成保存和加载操作了:
// 将当前Graph保存为JSON格式 const graphJSON = graph.toJSON(); // 加载JSON到新的Graph(务必确保自定义形状已提前定义) const newGraph = new joint.dia.Graph(); newGraph.fromJSON(graphJSON);
常见坑点提醒
- 自定义形状的
type必须唯一,不能和JointJS内置形状(比如basic.Circle)或其他自定义形状重复。 - 在Rappid的Stencil中使用时,要确保自定义形状的定义在Stencil配置之前加载,不然Stencil找不到这个形状。
- 不要直接覆盖
defaults属性,一定要用deepSupplement合并父类属性,避免丢失父类的核心配置导致形状异常。
内容的提问来源于stack exchange,提问作者Reputated_Enginius
相关产品推荐
相关产品推荐

