文本化图表实战:用D2构建高效架构图与系统设计

图表的本质是沟通,不是装饰。diagram-design这四年里,我对这句话的理解越来越深。大多数开发者画图,习惯打开画布拖拽几个方框、拉几条线,觉得“画完就行”。但在实际的架构评审、技术方案评审、甚至给新人讲业务逻辑的场景里,一张结构混乱、连线交叉、重点不清的图,带来的沟通成本远远大于它的表达价值。

我参与维护的一个内部项目,名字就叫diagram-design。它不是一个具体的绘图软件,而是一套围绕“如何用声明式文本快速产出高质量系统图表”的方法论与实践工具栈。你可以把它理解为:用写代码的方式画图,用工程化的思维管图。这篇文章我会把整套思路、常用工具选型、实操细节和踩过的坑完整梳理一遍,希望能给正在做技术文档、系统设计、或者日常需要画架构图的朋友一些可复用的参考。

1. 内容整体设计与思路拆解

1.1 为什么我放弃了拖拽式绘图

早年我也用那些所见即所得的绘图工具,画系统架构图确实方便,但维护起来是灾难。改一个节点的名称,可能要手工调整三条连线的位置;删掉一个模块,整张图的布局可能都要重排。最痛苦的是多人协作场景,每个人拖出来的图风格完全不同,合到一起简直没法看。

后来我把绘图场景做了一个分类,发现大约只有两类需求真正需要使用拖拽式工具:一类是极早期的灵感草图,不需要规范,就求一个快;另一类是给外部交付的精美配图,需要很强的视觉设计感。但这两类场景占我日常图表工作的比例其实不到两成。剩下八成多的需求是:系统架构说明、数据流描述、模块关系梳理、接口调用链展示。这些图的共同特点是结构性强,逻辑关系明确,而且往往要随着代码迭代持续更新。

我需要的不是一块无限画布,而是一个能描述“节点是什么、节点之间什么关系”的声明式系统。diagram-design的核心思路,就是把图表当作代码来管理。用文本定义节点和连线,用统一的布局引擎自动计算位置,用主题系统统一样式。这样一张图可以被review、被diff、被版本化管理,就像管理一段代码一样。

1.2 文本化图表的核心权衡

文本化方案最大的好处是可追踪、可复用、可自动化。但代价也很明显:布局控制力相对受限,复杂图元的视觉表现力不如手绘。所以在选型时我给自己定了一条原则:如果一张图需要我精确控制每个元素在画布上的像素位置,那说明它本质上是一张视觉设计稿,而不是一张架构图。架构图的价值在于传递关系,不在于美感。

基于这个原则,diagram-design的技术栈选型很明确:选择那些具备自动布局能力、语法简单、且支持程序化导出的文本图表工具。我在实际项目中主要使用D2作为主力语言,辅助PlantUML处理部分UML时序场景。选D2而不是更流行的Mermaid,有一部分原因是D2对复杂架构图的描述能力更强,布局引擎处理嵌套和连接关系的效果更干净,这个后面会详细拆解。

1.3 一张好图的标准

在展开细节之前,我觉得有必要先定义清楚“好图”的标准。diagram-design项目的内部规范里,我们对一张图只有四个要求:结构清晰、信息完整、层级合理、风格统一。

结构清晰指阅读顺序明确,重要的依赖关系一眼能看出来;信息完整指必要的角色、协议、数据流标签都在,不缺失关键信息;层级合理指通过容器、分组正确表达了系统的边界,不能把不同抽象层级的东西混在一起;风格统一指颜色、线型、节点形状的使用有语义规范,而不是随心所欲。

这些标准听起来不难,但实际做起来非常考验使用者的抽象能力。这也是为什么我认为图表设计首先是设计问题,其次才是工具问题。

2. 核心细节解析与工具选型

2.1 主流文本图表语言横向对比

我画图这几年,接触过的文本化图表工具不下五种。这里我把d核心的三种做一个系统性对比,方便你根据自己场景做判断。

D2的优势在于设计理念。它的语法被刻意设计成“所见即所得”的逻辑,而不是“图灵完备”的编程语言。所有的连接、容器、样式描述都尽量贴近自然语言,学习成本很低。渲染底层采用了比Mermaid更现代的实现,默认主题的辨识度很高。

Mermaid最大的优点是有GitHub原生渲染支持,在Markdown生态里的集成度最高。如果你只是想在项目文档里画一个简单的流程图,Mermaid的性价比极高。但它处理复杂嵌套结构的时候,布局容易乱,且生僻场景的定制能力弱于D2。

PlantUML则是UML场景的老牌选手。它的时序图、用例图、活动图语法经过多年打磨非常成熟,在Java技术栈的项目里应用广泛。缺点是图形风格相对“朴素”,插到现代风格的技术文档里会显得有些突兀。

我的个人使用建议是:系统架构图优先D2,嵌入式文档中的简单流程优先Mermaid,UML时序图优先PlantUML。当然这个结论比较主观,适合自己团队的工具才是最好的。

特性D2MermaidPlantUML
语法简洁度极简简单中等
自动布局质量高中中
嵌套容器支持强一般强
GitHub原生渲染部分支持支持不支持
主题定制能力可编程定制有限有限
动画/交互演示支持有限弱
适用范围架构图、流程图文档内嵌图UML图为主

2.2 为什么D2适合作为主力方案

D2有一个至今让我印象深刻的特性,就是你写注释的时候,它会把注释变成节点文字的一部分,自然排进布局里。这个设计大大减少了“文字旁注”的需求,因为很多时候我们画图时被信息塞满,就是因为没有地方写补充说明。D2的语法让描述性文字天然成为图表内容,而不是事后添加的浮层。

另外一个让我从Mermaid转向D2的关键点,是它对复杂架构图的布局处理。早期Mermaid对复杂布局的抽搐问题很严重,节点一多就乱成一团。D2的默认布局引擎要稳定得多,尤其在处理双向连接、多层容器嵌套的时候,几乎不需要人工干预。配合ELK布局引擎,即使在非常复杂的网络拓扑场景下,也能保持清晰的可读性。

我还特别看重D2的原生命令行动画。日常评审的时候,用一行命令把静态图变成逐步演进的动画示意图,讲数据流的动态过程特别直观。我的经验是,评审会上放一张静态图,和放一段强调先后顺序的动画图,听讲者的理解效率完全是两个档次。

2.3 安装与环境配置

D2的安装非常简单,支持常见的包管理工具,也可以直接下载编译好的二进制文件。我日常的开发环境覆盖macOS和Linux两类系统,全流程如下:

在macOS下,如果安装了Homebrew,只需要一条命令:

brew install d2

在Linux服务器上,我习惯用官方提供的一键脚本安装:

curl -fsSL https://d2lang.com/install.sh | sh -s --

Windows环境不建议使用WSL之外的方案,因为D2的字体渲染依赖较底层的库,原生Windows支持虽然存在,但体验不如在WSL里使用顺畅。

安装完成后记得补一个可选的辅助工具,用于导出PDF和PPT格式:

brew install tala

TALA是D2官方推荐的布局引擎之一,跟默认引擎相比,它在处理有向图布局时更擅长利用垂直空间。我的直观感受是,涉及层次化架构图(比如分层系统设计)的时候,TALA的布局结果比默认引擎更接近我们手绘架构图的习惯。

2.4 语言基础:从语法规范到设计约束

D2的核心语法核心简单到令人难以置信。节点就是普通的文字,连接用两个箭头表示,容器用花括号包裹。下面这段代码是一段入门示例:

用户 -> 认证服务: 发起登录请求 认证服务 -> 用户数据库: 校验凭证 认证服务 -> 用户: 返回令牌

三行代码,一张完整的调用时序图就出来了。这个语法设计有一个隐含的优势:任何人都能看代码预判输出图的样子,不需要在工具和画布之间来回切换预览。

D2支持多种箭头类型和修饰符。实线表示同步调用,虚线表示异步消息,加粗箭头表示高优先级请求,指针修饰符表示数据流方向。这些细节能力,让它在描述系统交互场景时完全够用。而且D2原生支持自定义关键词修饰,比如你可以给连接线打上一个标签,描述协议类型是HTTP还是GRPC,这样读图的人不需要额外去查文档。

3. 实操过程与核心环节实现

3.1 从空白文件到第一张架构图

我现在用一个实际的微服务架构图解示例,完整走一遍diagram-design的工作流。这个场景是我在给一个内部系统设计权限模块时画的图,参考价值比较高。

首先创建目录和文件:

mkdir diagram-design-tutorial cd diagram-design-tutorial touch auth-architecture.d2

用文本编辑器打开这个文件,先定义顶层容器。权限系统按逻辑边界拆成三个部分:客户端层、网关层、服务层。D2里用花括号区分容器:

客户端层 { 管理后台 用户App } 网关层 { 接入网关 } 服务层 { 认证服务 权限服务 用户服务 }

D2的渲染引擎会自动把同级的容器并列排布,容器内的节点自动居中对齐。布局这一步完全不需要人工干预,这也是我坚持用文本画图的主要原因。

3.2 连接关系与数据流标注

容器定义好之后,开始加连接关系。这里有几个操作细节非常关键。容器之间的连接,D2默认是从容器的边界出发,指向目标容器的边界。如果你需要明确到具体的内部节点,要去掉容器名,直接用内部节点名。例如:

管理后台 -> 接入网关: HTTPS {style.stroke-dash: 3} 用户App -> 接入网关: HTTPS {style.stroke-dash: 3} 接入网关 -> 认证服务: JWT校验 认证服务 -> 用户服务: 读取用户信息 {style.stroke: green} 认证服务 -> 权限服务: 校验权限 {style.stroke: blue}

注意我在这里给连接线加了颜色属性。颜色在架构图里不是美化,而是语义编码。绿色表示读操作,蓝色表示校验操作。团队成员不需要看图例就能快速理解数据流的性质,这就是用规范替代交流成本。

3.3 布局调整与方向控制

D2默认的布局方向是水平从左到右,自顶向下。对于某些场景,比如用户访问链路的描述,垂直布局更合适,从上到下描述请求的流转路径。你只需要在文件顶部加一行:

direction: down

整张图就会切换成从上到下的布局。这个参数在D2的实现里是全局的,它会影响所有容器内节点的排列方向,但不影响节点之间的逻辑连接关系。如果你用ELK引擎,还需要注意一点,ELK天然偏向有向图布局,在复杂图上的表现优于默认引擎,但它不保证每个逻辑层级严格对齐。强制对齐这类需求,用TALA引擎效果更好。

3.4 样式定制与主题体系

D2支持完整的CSS风格变量定制。但在项目实践里我不建议直接修改每个节点的颜色,效率太低,而且容易造成风格不一致。正确做法是定义一套统一的主题,然后让所有图表自动继承。

D2可以在文件级别的meta信息里配置主题:

vars: { d2-config: { theme-id: 200 } }

200号主题是D2内置的“文档酷炫”风格,字体和配色更适合展示场景。除了内置主题,你还可以定义全局的CSS变量,让所有节点的边框、阴影、圆角保持一致:

vars: { d2-config: { theme-id: 200 dark-theme-id: 201 } }

对字体和配色要求比较高的团队,建议维护一个统一的主题基础文件,然后在每个图里通过import语句引入。这样整个知识库的图,视觉风格天然统一。

3.5 导出与集成

D2的编译输出选项支持SVG、PNG、PDF等格式。日常我在本地预览时使用中间输出格式,方便快速刷新:

d2 --watch auth-architecture.d2 /tmp/preview.svg

--watch参数让D2监听文件变化,每次保存自动重新渲染。这个模式在开发体验上非常好,你调整完代码,切到浏览器刷新一下就能看到最新的图。

交付场景下,我通常直接输出SVG文件嵌入文档。关键原因是SVG是矢量格式,放大不模糊,且在网页上可以天然交互,比如点击节点跳转链接。AI生成的图表或者图片格式,全部规避掉,统一用SVG提交到代码仓库。

4. 常见问题与排查技巧实录

4.1 布局乱飞问题与ELK引擎适配

用得久了,难免遇到D2的默认布局引擎在复杂图上表现不佳的情况,节点互相重叠、连接线缠绕。遇到过这种问题,先不用急着改代码,优先尝试切换布局引擎。D2支持在命令行指定:

d2 --layout=elk file.d2 out.svg

ELK引擎在层级关系复杂的架构图上表现明显更好。注意ELK引擎对箭头方向有一点敏感性,如果输出方向不符合预期,试着调一下direction参数,有时能解决问题。还有一个排查思路是检查容器层级是否清晰,如果所有的节点都在同一个层级,没有合适的父子关系,布局引擎很难自动判断结构主次,节点排列自然就混乱了。

4.2 样式继承无效背后的“就近原则”

我在早期使用D2定制主题时踩过一个坑,就是试图在容器上定义样式,希望子节点继承,结果子节点的样式没有变化。这个设计跟CSS的继承逻辑不同,D2的样式生效采用就近原则,子节点如果没有显式定义样式,完全不会被父容器的样式影响。解决方案有两个:一是利用D2内置的Vars与场景,定义全局性的节点样式;二是在子节点上逐一指定样式,适合局部微调。理解了这个机制,样式定制就不再困惑。

4.3 中文字体渲染问题

中文字体渲染问题是一个很容易被忽略的细节。D2的默认字体在某些Linux发行版上不包含中文字形,渲染出来的图里中文全部变成方框乱码,非常影响阅读。解决方法是显式指定一个包含中文字形的字体。可以在文件里设置:

vars: { d2-config: { font-regular: "NotoSansSC" } }

也可以修改系统的fontconfig配置,让D2优先使用Noto Sans CJK系列字体。如果你在macOS上开发,本机的苹方字体一般能正常识别,不需要额外设置。我个人的实践是高频率生成中文图表时,把字体配置固化到主题里,而不是每次单独指定。

4.4 常见问题速查表

这里我把日常使用过程中出现过的问题归类成一个速查表,方便团队新人在遇到对应情况时快速定位。

问题现象可能原因解决建议
中文字符全部显示为框缺少中文字体配置在主题中指定全字体
连接线相互交叉严重布局引擎不适应图结构切换ELK或TALA引擎
样式定义失效子节点未显式继承样式使用就近原则显式定义
导出PNG文字模糊部分预览器对PNG缩放不佳改用SVG格式
节点文字被截断节点宽度未自适应调整节点尺寸或缩短文字
原图渲染慢使用了过多嵌套容器拆分成多张子图

4.5 命令行动画与评审提效

最后分享一个让评审效率倍增的小技巧。D2支持把图表导出为动画序列,配合命令行工具,可以控制动画的播放节奏。这个功能从我第一次使用起就固定在了我的评审流程里。当前实现方式是D2原生支持在SVG中生成带有动画步长信息的规范输出,再配合适当的工具链转换为视频或交互式SVG。

实际操作中,我会把一张包含数据流的架构图拆成多个动画步骤,第一步只显示用户发起请求,第二步显示网关转发,第三步显示认证成功,这样依次呈现。评审的时候,大家跟着动画顺序走一遍流程,理解速度远超对着静态图讲。这个技巧在给非技术同事讲系统逻辑时特别好用。

5. 团队协作与知识库沉淀经验

多人协作画图,最大的挑战是图的可维护性。文本化是第一步解决方案,D2的代码是普通的文本文件,天然适配代码评审流程。我们在项目里做了两个额外约定,保证了图库的长期可用。

第一个约定是图表文件和源数据必须放同一个仓库,图随代码变。每次涉及接口变更、模块重构,必须同步更新对应的D2文件,把这个作为代码评审的checklist项。否则过几个月再看,图就变成过期的历史文件了。

第二个约定是全部使用SVG格式输出嵌入文档。如果用图片格式提交,diff阶段很难看清楚文件和文件之间改了什么。SVG配合代码仓库,每次变更可以被精确审查。这两个约定执行之后,图表的时效性和质量都有了质的提升。

6. 写在最后的一点体会

回到文章开头那个观点,图表的本质是沟通,不是装饰。diagram-design整个项目实践下来,我最大的收获不是掌握了一个强大的工具,而是建立了一套用文本精确描述复杂关系的思维方式。画图的过程变成了一种帮助我理清思路的手段,而不是一个表达负担。

如果你现在正在纠结选什么图表工具,我的建议是从D2入手试一下。它的语法足够简单,你不会花太多时间在学习成本上。而一旦你体验到“改图就像改代码”的流畅感,大概率就不想回到拖拽式画图的方式了。最后补充一个建议,不管使用哪种工具,一定要为你的团队制定一份图表设计规约,明确颜色语义、层级规范和样式主线。没有规约的图库,最终都会变成无人愿意维护的垃圾场。

相关新闻

分布式NMPC水下航行器编队轨迹跟踪控制与Matlab仿真

分布式NMPC水下航行器编队轨迹跟踪控制与Matlab仿真

1. 项目概述与核心需求解析1.1 这个项目到底在解决什么问题先说结论:这个项目是用非线性模型预测控制(NMPC)解决水下航行器(UUV/AUV)的轨迹跟踪问题,而且特别强调“分布式”三个字——不是单台航行器自己跟…

2026/10/19 20:36:39 阅读更多 →
diagram-design跨平台图表设计工具:从数据建模到性能优化的完整复盘

diagram-design跨平台图表设计工具:从数据建模到性能优化的完整复盘

第一次接触某内部协作平台里的 diagram-design 模块时,我还没意识到图表设计这件事的水有多深。起初我以为无非就是提供几个形状、几条连线,让用户拖拖拽拽,能导出一张还算好看的图就算交差。真的动手做下去才发现,diagram-design…

2026/10/19 20:36:39 阅读更多 →
从零搭建艺术手工项目artcraft:流程、工具与实操

从零搭建艺术手工项目artcraft:流程、工具与实操

做艺术类手工项目这些年,我最大的感受是:多数人不是缺创意,而是缺一套能把想法稳稳落地的流程。artcraft这个项目名字,光是拆开看就很有意思——art是艺术,craft是工艺,合在一起就是“用工艺的方式做艺术&a…

2026/10/19 20:36:39 阅读更多 →

最新新闻

构造与析构:对象生命周期核心原理与工程踩坑实录

构造与析构:对象生命周期核心原理与工程踩坑实录

有段时间我在维护一个内部教学系统,里面有个很诡异的现象:新建账号第一次登录时,头像永远显示默认图,要手动刷新两次才能恢复。一开始我怀疑是缓存,查到最后发现,问题出在对象创建后的初始化阶段——那块逻…

2026/10/19 21:21:08 阅读更多 →
Matlab实现BP神经网络多输入单输出回归预测及K折交叉验证

Matlab实现BP神经网络多输入单输出回归预测及K折交叉验证

多输入单输出回归预测,是我在实操里遇到频次最高的建模需求之一。手里攒了一堆自变量,想预测一个连续的因变量,数据不算多、关系又不线性,这时候BP神经网络往往是最省心的选择。它不像线性回归那样对模型形式要求严格,…

2026/10/19 21:21:08 阅读更多 →
大模型开发三大支柱:数据流水线、算法与基础设施实战解析

大模型开发三大支柱:数据流水线、算法与基础设施实战解析

这两年聊大模型开发,很多人都下意识盯着模型结构本身:用哪个开源底座、改多少层、参数量多大。可真到了自己跑项目,你会发现卡你的往往不是那几十行模型代码,而是数据怎么喂进去、训练怎么稳定不崩、多卡上怎么不浪费显存、迭代一…

2026/10/19 21:21:08 阅读更多 →
QT网络聊天室实战:从TCP粘包到文件分块传输

QT网络聊天室实战:从TCP粘包到文件分块传输

简介:基于QT的网络聊天室项目集实时聊天与文件传输于一体,面向C/Qt学习者、网络编程入门者以及需要GUI与通信综合实践的开发者。资源共54个文件,压缩包388KB,以cpp/h源代码、ui界面文件、qrc资源文件为主体,辅以png/jp…

2026/10/19 21:21:08 阅读更多 →
macOS 编译 Chromium 全流程:从 GN 参数到 ninja 构建

macOS 编译 Chromium 全流程:从 GN 参数到 ninja 构建

磨了大半天,前四篇把环境、源码获取这些前置事项都梳理完了,这篇终于要进入真正烧 CPU 的环节——编译。很多人在这一步翻车,不是没把前面的准备做完,就是卡在一些看起来很诡异、实际上原因很朴素的错误里。我这篇就把自己反复踩出…

2026/10/19 21:21:07 阅读更多 →
零基础跑通JavaWeb校园外卖系统:从环境搭建到下单流程实战

零基础跑通JavaWeb校园外卖系统:从环境搭建到下单流程实战

简介:这份资源是基于JavaWeb的校园外卖管理系统完整源码与数据库,面向计算机相关专业学生、Java初学者及需要课程设计或期末大作业的开发者。项目采用JavaWeb技术栈实现,涵盖用户下单、订单管理、菜品展示等校园外卖核心业务场景,…

2026/10/19 21:18:02 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介:本资源为电源技术方向的学术研究文档,聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略,面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址: https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集,共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/19 10:02:04 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/19 1:30:52 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 2:54:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 9:10:22 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →