主题
文档与校验
文档先回答两个问题:图里有哪些元素,它们怎么连。元素多大、放在哪、最后长什么样, 分别留给布局、形状和宿主;其余字段只是为这两件事补充条件。
正在渲染图表…
一份文档有什么
| 字段 | 表达什么 | 不表达什么 |
|---|---|---|
nodes | 有哪些元素,每个元素的 type 是什么 | 元素宽高、颜色、具体画法 |
edges | 谁连谁,连接哪个端口 | 线怎么绕、箭头怎么画 |
ports | 节点表面有哪些可连接的位置 | 端口最终落在哪个像素 |
children | 哪些节点属于当前容器 | 子节点怎么排列 |
styles | 这一类元素使用哪套画法 | 具体主题色值 |
layout | 布局意图,例如方向、间距、显式位置 | 完整的最终坐标 |
当前文档版本是 version: 2。parseDocument 仍接受 v1,并会在入口处升级。
layout.pins 是唯一的例外:它明确写给 explicit 引擎使用。其他引擎不会把 pin 当成普通布局数据,也不要指望它在所有引擎里都生效。
校验与形状是两层
parseDocument 检查结构和引用关系:
- 节点、边、端口、
children和 pin 是否指向存在的对象; children是否成环,是否有多个父节点;- 边引用的端口是否真的在节点上声明。
它不知道某个 type 应该长什么样,也不认识形状自己的 props。下一步的 bindDocument 才会读取注册表,用 schema 检查、补默认值并处理未知类型。
所以一个文档能通过解析,不代表每个自定义形状的 props 都正确。后者属于 bind 这一层, 并且同一条 props 诊断只会产生一次。
容器由形状声明
没有单独的 groups[]。children 表达父子关系,形状通过 ShapeEntry.container 声明它能 不能承载 children、标题带占多高:
ts
{
id: "orders",
type: "component",
label: "订单服务",
children: ["repository"],
}如果形状没有声明 container,bind 会发出 CHILDREN_ON_LEAF 警告;兼容期仍按容器处理。
这样同一个节点可以既带端口,又装子节点,不需要再引入第三种结构。
容易误会的地方
props是开放字段。解析器不会替你判断某个自定义形状到底需要哪些 prop。id不能包含/或#;端口锚点和场景 key 依赖这个约束。styles不是主题。它描述“怎么涂”,具体的 token 值由主题解析。type只是名字。注册表没有注册它,画面会走矩形回落,同时给出诊断。