D2 如何用 shape: sequence_diagram 声明时序图并限制 near 用法?
【免费下载链接】d2D2 is a modern diagram scripting language that turns text to diagrams.项目地址: https://gitcode.com/GitHub_Trending/d2/d2
D2 支持用shape: sequence_diagram把一个作用域声明成时序图:直接子 key 成为参与者(actors),参与者的边成为按文件行序从上到下排列的消息。这个形状既可以设在根上,也可以设在任意容器上。同时,编译器对near字段有一组硬性限制,其中与序列图直接相关的两条是:near不能指向序列图内部的对象,也不能指向时序图参与者这类特殊对象的后代。本文基于仓库中的编译器校验逻辑(d2compiler/compile.go)与编译测试用例(d2compiler/compile_test.go),给出声明时序图的写法、可组合的结构,以及near的每条限制和对应报错。
准备:安装 D2 并准备 .d2 文件
按 README.md 的 Quickstart,安装后用 CLI 从.d2文件生成 SVG:
# First, install D2 curl -fsSL https://d2lang.com/install.sh | sh -s -- echo 'x -> y -> z' > in.d2 d2 --watch in.d2 out.svgd2 --watch会打开浏览器窗口显示out.svg,并在in.d2变化时实时重新渲染,适合边改边看时序图布局。形状值sequence_diagram的正式定义在 d2target/d2target.go。
声明时序图:根作用域或容器
两种写法都来自编译测试用例。
把整张图设为时序图(root_sequence用例):
shape: sequence_diagram把某个容器设为时序图(basic_sequence用例),编译器会把该对象的 shape 记录为sequence_diagram:
x: { shape: sequence_diagram }声明后,容器内直接子 key 是参与者,参与者之间的边是消息(sequence-timestamp用例的骨架):
shape: sequence_diagram a b a -> b布局由 d2layouts/d2sequence/sequence_diagram.go 中的newSequenceDiagram处理,其中两条编译期/布局期约束会直接报错:
- 一个参与者都没有时:
no actors declared in sequence diagram(sequence_diagram.go 第 109 行); - 参与者本身再声明成时序图时:
actors in sequence diagrams cannot themselves be sequence diagrams(sequence_diagram.go 第 103 行)。
消息的上下顺序由边在文件中的行号决定(getEdgeEarliestLineNum,sequence_diagram.go 第 64-76 行),所以调整脚本里边的书写顺序就能调整消息的先后。
组合 group、span 与 note
sequence_scoping用例展示了一个带group的完整写法:
x: { shape: sequence_diagram a b group: { a -> b a.t1 -> b.t1 b.t1.t2 -> b.t1 } }sequence_grouped_note用例展示了参与者下的 note(带引号的子 key 作为标注)以及用容器把它们分组:
shape: sequence_diagram a d choo: { d."this note" }这些结构在布局层的对应物:参与者有边的子对象成为 span(生命线旁的方框),只有标注的子对象成为 note,带标签的group容器会框住其中所有消息(见 sequence_diagram.go 第 143-169 行 与placeGroups)。写这些结构时的规则就是上面两条:参与者不能缺、参与者不能自身是时序图。
near 字段的限制
near用来把一个形状放到另一个形状的附近。编译器在validateNear(d2compiler/compile.go 第 1208-1277 行)中逐条校验,以下每条限制都有对应的固定报错文案:
取值范围:
near的值必须是某个形状的路径,或是以下常量之一:top-left、top-center、top-right、center-left、center-right、bottom-left、bottom-center、bottom-right(d2ast/keywords.go 第 81-92 行 的NearConstantsArray)。不满足时报错:near key ... must be the absolute path to a shape or one of the following constants: ...。不能指向序列图内部对象:
near_sequence用例(compile_test.go 第 2617-2627 行):x: { shape: sequence_diagram a } b.near: x.a预期报错(文档示例,测试断言的原文):
near_sequence.d2:5:9: near keys cannot be set to an object within sequence diagrams。即b想贴住时序图里的参与者x.a,编译器拒绝。不能指向祖先或后代:报错分别为
near keys cannot be set to an ancestor与near keys cannot be set to an descendant。不能指向本身带常量 near 的对象:报错
near keys cannot be set to an object with a constant near key。不能指向特殊对象的后代:包括 grid cell 和时序图参与者,报错为
near keys cannot be set to descendants of special objects, like grid cells或... like sequence diagram actors。常量 near 只能用于根级形状:
constant near keys can only be set on root level shapes。从常量 near 对象出发的边不能进入其自身:
edge from constant near ... cannot enter itself。
与序列图相关的要点是第 2、5 条:时序图的参与者和内部结构不参与near定位。注意这与边的行为不同——leaky_sequence用例(compile_test.go 第 2664-2674 行)中b -> x.a预期无错误,说明边可以引用序列图内部对象,而near不行。
验证
- 正向验证:按 Quickstart 执行
d2 --watch in.d2 out.svg,浏览器中打开的 SVG 即为渲染结果;改脚本会实时刷新。 - 反向验证:写一条违反限制的
near(例如上面第 2 条的b.near: x.a),编译会失败并输出形如文件:行:列: near keys cannot be set to an object within sequence diagrams的错误,定位信息指向nearkey 所在位置。各用例的完整预期错误串可在 d2compiler/compile_test.go 的expErr字段中核对。
【免费下载链接】d2D2 is a modern diagram scripting language that turns text to diagrams.项目地址: https://gitcode.com/GitHub_Trending/d2/d2
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考