D2 如何用 shape: sequence_diagram 声明时序图并限制 near 用法?
2026/9/13 23:30:11 网站建设 项目流程

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.svg

d2 --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 行)中逐条校验,以下每条限制都有对应的固定报错文案:

  1. 取值范围near的值必须是某个形状的路径,或是以下常量之一:top-lefttop-centertop-rightcenter-leftcenter-rightbottom-leftbottom-centerbottom-right(d2ast/keywords.go 第 81-92 行 的NearConstantsArray)。不满足时报错:near key ... must be the absolute path to a shape or one of the following constants: ...

  2. 不能指向序列图内部对象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,编译器拒绝。

  3. 不能指向祖先或后代:报错分别为near keys cannot be set to an ancestornear keys cannot be set to an descendant

  4. 不能指向本身带常量 near 的对象:报错near keys cannot be set to an object with a constant near key

  5. 不能指向特殊对象的后代:包括 grid cell 和时序图参与者,报错为near keys cannot be set to descendants of special objects, like grid cells... like sequence diagram actors

  6. 常量 near 只能用于根级形状constant near keys can only be set on root level shapes

  7. 从常量 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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询