主题
端口与锚点
端口是文档里声明的“可连接位置”,锚点是布局算出来的“具体坐标”。 前者回答“能不能连”,后者回答“连到哪个像素”。
端口先声明,边再引用
ts
{
id: "service",
type: "component",
ports: [
{ id: "api", side: "right", constraint: "side" },
],
}ts
{
source: { node: "web" },
target: { node: "service", port: "api" },
}如果边引用了一个没有声明的端口,parseDocument 会报 UNKNOWN_PORT,布局不会猜一个位置。
默认锚点
形状没有提供 anchors 时,端口按 side 和 offset 落在节点盒子上:
side | 点的位置 |
|---|---|
top | (x + width × offset, y) |
right | (x + width, y + height × offset) |
bottom | (x + width × offset, y + height) |
left | (x, y + height × offset) |
offset 可以是 0 到 1 的数字,也可以是 "25%" 这样的百分比字符串。对普通矩形来说, 这通常已经够用。
端口约束与同侧槽位
constraint | 行为 |
|---|---|
fixed | side 和 offset 都固定;缺省值,兼容 v1 |
side | side 固定,offset 自动分配 |
free | 根据对端方向选 side,再自动分配槽位 |
attachEndpoints 会把同一节点同一侧的自动端口集中排序,按最小间距 12px 等距分配。 边的书写顺序不会改变结果;空间不足时压缩并发出 PORT_CROWDED 警告。
自定义锚点
圆盘、星形、头像这类形状,盒子的边缘不一定就是图形的真实表面。此时在注册项里实现 anchors:
ts
anchors(port, _props, box) {
if (port.id === "center") {
return { x: box.x + box.width / 2, y: box.y + box.height / 2 };
}
return defaultAnchor(port, box);
},边和端口装饰都读取同一份 ctx.anchors。所以只要锚点改对,端口圆环和线端点会一起移动, 不会出现“看起来在端口上,实际连到别处”的情况。
没有指定端口时
边没有写 port 时,布局会在两端盒子的边框上选一个朝对方的点。这个点不是形状表面上的 任意点,而是盒子的边框点;要精确控制位置,就声明端口。
当两个节点左右相邻、两端的高度范围又有交集时,路由可以直接走一条直线。只有在无法避免时 才会折一次,原因见布局与路由。
常见误解
- 端口不是装饰:画了一个小圆环,不会自动产生 anchor。
- 默认是 fixed:想让库自动排槽位,必须显式写
side或free。 - 端口不是全局 id:同一个端口名可以在多个节点上重复,边引用时必须带节点 id。
anchors不是布局:它只返回点,不能改变节点盒子大小。- hidePorts 只关掉装饰:锚点仍然存在,边仍然可以准确连接。