Mermaid Wardley Maps(wardley-beta):业务战略地图的完整语法与实现原理
Mermaid 从 v11.14.0 起支持 Wardley Maps 图类型,通过纯文本描述即可绘制业务战略地图:将组件沿「可见性(Visibility)」与「演化(Evolution)」两个轴定位,用于表达价值链依赖、组件成熟度演进、自建/采购(build vs. buy)决策以及惯性阻力等战略分析内容。本文以 官方语法文档 为主体,完整讲解 wardley-beta 语法的全部语句、示例与限制,并结合 wardleyParser.ts、wardleyRenderer.ts 等源码,说明坐标换算、数据模型与 D3 渲染层的实际工作方式。
什么是 Wardley Map:双轴定位模型
Wardley Maps 是业务战略的可视化表示,将组件映射到两条坐标轴上:
- 可见性(Visibility,Y 轴):组件对用户可见/有价值的程度,0.0 表示基础设施层,1.0 表示用户直接面对的部分;
- 演化(Evolution,X 轴):组件成熟程度,0.0 表示新兴/萌芽(Genesis),1.0 表示商品化/公用事业(Commodity/Utility)。
这种双轴定位支撑四类战略分析:价值链依赖、组件随时间的演化、build vs. buy 决策、以及惯性与变革阻力。
下面是一个最小可运行的完整示例(来自文档,与 e2e 用例 1-should-render-tea-shop.mmd 的场景一致):
wardley-beta
title Tea Shop Value Chain
anchor Business [0.95, 0.63]
component Cup of Tea [0.79, 0.61]
component Tea [0.63, 0.81]
component Hot Water [0.52, 0.80]
component Kettle [0.43, 0.35]
component Power [0.10, 0.70]
Business -> Cup of Tea
Cup of Tea -> Tea
Cup of Tea -> Hot Water
Hot Water -> Kettle
Kettle -> Power
evolve Kettle 0.62
evolve Power 0.89
note "Standardising power allows Kettles to evolve faster" [0.30, 0.49]
图声明:wardley-beta、title 与 size
每个 Wardley 图必须以 wardley-beta 关键字开头(beta 发布标识):
wardley-beta
title Your Map Title
size [1100, 600]
| 语句 | 说明 |
|---|---|
wardley-beta |
必填的图类型标识(beta 发布) |
title |
可选,显示在顶部居中的标题 |
size [宽, 高] |
可选画布尺寸(像素),默认 [1100, 600] |
图类型由 wardleyDetector.ts 中的正则 /^\s*wardley-beta/i 匹配识别。从源码结构看,size 语句通过解析器调用 db.setSize() 写入画布尺寸;渲染时若图中指定了 size,会覆盖配置中的默认宽高(wardleyRenderer.ts#L81-L82:data.size?.width ?? configValues.width)。
坐标系:[visibility, evolution] 的 OWM 格式
重要:Wardley Maps 使用 OnlineWardleyMaps(OWM)格式的坐标顺序:[visibility, evolution]
- 第一个值(Visibility):0.0–1.0,自下而上,对应 Y 轴位置;
- 第二个值(Evolution):0.0–1.0,自左向右,对应 X 轴位置。
这与通常的 (x, y) 写法正好相反:
wardley-beta
title Coordinate Examples
component Infrastructure [0.30, 0.20] %% Low visibility, low evolution
component Product [0.70, 0.60] %% High visibility, mid evolution
component User Need [0.90, 0.95] %% High visibility, high evolution
解析层的坐标换算是理解行为的关键。wardleyParser.ts#L8-L28 中的 toPercent 函数同时接受两种写法:
- 0–1 区间的小数(如
0.8)会被乘以 100 转为百分比; - 0–100 区间的数值直接作为百分比使用;
- 超出范围则抛出错误:
must be between 0-1 (decimal) or 0-100 (percentage)。
随后 toCoordinates(visibility, evolution) 将第二个值映射为内部 x 坐标、第一个值映射为 y 坐标。渲染层再做一次线性投影(wardleyRenderer.ts#L165-L166):projectX = padding + (value/100) * chartWidth,projectY = height - padding - (value/100) * chartHeight(y 轴翻转,使可见性 0 在底部)。
组件(component)与锚点(anchor)
组件语法
component Name [visibility, evolution]
component Name [visibility, evolution] label [offsetX, offsetY]
component Name [visibility, evolution] (decorator)
示例:
wardley-beta
title Components
component API [0.60, 0.70]
component Database [0.40, 0.85] label [-50, 10]
component "Custom Service" [0.55, 0.35]
关于命名的规则:
- 名称可以包含连字符(如
real-time processing、end-user)而无需引号; - 仅当名称以非字母开头、或包含语法不接受的字符时才需要引号。
wardley-beta
title Hyphenated Names
component real-time processing [0.55, 0.40]
component end-user [0.90, 0.95]
end-user -> real-time processing
从源码看,label [offsetX, offsetY] 的偏移量在解析时支持负号语法:wardleyParser.ts#L105-L110 会根据 AST 中的 negX/negY 标记决定正负,再传入 addNode。
锚点(Anchors)
锚点表示用户或客户,渲染时使用加粗标签:
wardley-beta
title Anchors
anchor Customer [0.90, 0.95]
anchor Business [0.85, 0.90]
component Service [0.70, 0.75]
Customer -> Service
Business -> Service
解析器将 anchor 作为带 className: 'anchor' 的节点写入(wardleyParser.ts#L93-L96),渲染器据此应用粗体样式。
装饰器(Decorators)
惯性(Inertia)
标记对变革有阻力的组件,在节点上叠加惯性符号:
wardley-beta
title Inertia
component Legacy System [0.45, 0.40] (inertia)
component New Platform [0.65, 0.45]
Legacy System -> New Platform
来源策略(Source Strategy)
标注 build / buy / outsource / market 决策,分别以不同形状符号呈现:
(build)— 三角形符号(buy)— 菱形符号(outsource)— 方形符号(market)— 圆形符号
wardley-beta
title Sourcing Strategy
anchor Customer [0.80, 0.95]
component Custom App [0.45, 0.85] (build)
component Off-the-shelf Tool [0.85, 0.65] (buy)
component Managed Service [0.60, 0.40] (outsource)
component Cloud Platform [0.95, 0.25] (market)
Customer -> Custom App
Custom App -> Off-the-shelf Tool
Custom App -> Managed Service
Off-the-shelf Tool -> Cloud Platform
链接与依赖(Links)
A -> B %% Basic dependency
A --> B %% Basic dependency (alternative style)
A -> B; label %% With annotation
A -.-> B %% Dashed flow
A +> B %% Flow (with arrow marker)
A +< B %% Reverse flow
A +<> B %% Bi-directional flow
A +'text'> B %% Labeled flow
示例:
wardley-beta
title Link Types
component User [0.90, 0.95]
component App [0.75, 0.75]
component API [0.60, 0.60]
component Cache [0.65, 0.45]
component Database [0.15, 0.80]
User -> App
App +> API
API -> Database
API +<> Cache
Cache +'backup'> Database
解析层对 + 系列箭头有一套专门的识别逻辑(wardleyParser.ts#L46-L66 的 extractFlowFromArrow):
- 包含
<>判定为bidirectional(双向,两端箭头); - 包含
<判定为backward(反向流); - 包含
>判定为forward(正向流); +'text'>中的引号文本被提取为流的标签(flowLabel),优先于普通边标签;- 箭头含
-.->或.-.时标记为虚线。
数据模型 WardleyLink(wardleyBuilder.ts#L15-L21)记录了 source / target / dashed / label / flow 五个字段,渲染器据此绘制不同方向的箭头 marker。
演化与趋势(Evolution and Movement)
evolve:演化箭头
用红色虚线箭头表示组件的演化方向:
wardley-beta
title Evolution
component Database [0.40, 0.50]
component API [0.55, 0.60]
Database -> API
evolve Database 0.75
evolve API 0.80
趋势指示符(Trend Indicators)
表示组件预测的未来位置:
Component -.- (x, y)
注意:趋势使用标准的 (x, y) 顺序,而不是 [visibility, evolution]!
从解析器实现看,趋势数据(WardleyTrend { nodeId, targetX, targetY })由 evolve 语句填充:wardleyParser.ts#L190-L197 会先查找到组件当前位置,再把 evolve 的目标值作为目标 X 坐标、保持原 Y 坐标写入趋势表,渲染器将其绘制为红色虚线箭头(箭头 marker 颜色取 theme.evolutionStroke,默认 #dc3545)。
管线(Pipelines)
管线组件共享同一可见性(同一行),仅演化度不同,用于表达同一能力在不同技术代际上的演进:
wardley-beta
title Pipeline Evolution
component Database [0.40, 0.60]
pipeline Database {
component "File System" [0.25]
component "SQL DB" [0.50]
component "NoSQL" [0.70]
component "Cloud DB" [0.85]
}
实现上有几个值得注意的细节(wardleyParser.ts#L138-L171):
pipeline的父节点必须是已声明且带坐标的组件,否则抛出错误Pipeline "xxx" must reference an existing component with coordinates;- 每个管线成员会被分配一个合成 ID(格式
父节点_成员名),Y 坐标直接继承父节点的可见性; - 构建器
startPipeline会把父节点标记为isPipelineParent,成员标记为inPipeline,渲染时父节点显示为方形(边长为nodeRadius * 1.6); - 构建器还提供了
resolveNodeId(wardleyBuilder.ts#L175-L185):链接端点解析时先尝试精确 ID 匹配,再回退到按节点 label 匹配——因此可以直接用Database -> File System这样引用管线成员。
自定义演化阶段(Custom Evolution Stages)
默认横轴刻度为四个标准阶段:Genesis / Custom Built / Product / Commodity(定义于 wardleyRenderer.ts#L12)。可以用 evolution 语句自定义轴标签:
wardley-beta
title Custom Stages
evolution Unmodelled -> Divergent -> Convergent -> Modelled
component Raw Data [0.15, 0.20]
component Analysis [0.45, 0.50]
component Reports [0.75, 0.70]
双标签阶段(Dual Labels)
用 / 在同一阶段内显示两个名称:
wardley-beta
title Dual Label Stages
evolution Genesis / Concept -> Custom / Emerging -> Product / Converging -> Commodity / Accepted
component Novel Idea [0.05, 0.20]
component Custom Solution [0.35, 0.50]
component Product [0.65, 0.70]
component Utility [0.95, 0.90]
解析器会把 name / secondName 拼接为 "Genesis / Concept" 形式的单行标签(wardleyParser.ts#L77-L89)。
自定义阶段宽度(@ 边界值)
用 @ 指定每个阶段的边界位置(0.0–1.0),控制各阶段区段的实际宽度:
wardley-beta
title Custom Widths
evolution Genesis@0.2 -> Custom@0.4 -> Product@0.75 -> Commodity@1.0
component Novel [0.75, 0.15]
component Bespoke [0.70, 0.35]
component Product [0.65, 0.65]
component Utility [0.60, 0.90]
边界值在解析时被收集进 stageBoundaries 并通过 db.updateAxes() 写入轴配置。
注释与标注(Notes 和 Annotations)
note:上下文注释
在指定坐标处添加说明文字(文本必须加引号):
note "text" [visibility, evolution]
wardley-beta
title Notes
component API [0.60, 0.70]
component Database [0.40, 0.50]
API -> Database
note "Critical decision point" [0.65, 0.55]
note "High risk area" [0.40, 0.35]
annotation:带编号的标注
创建带编号的引用点,并可选放置标注框:
annotations [x, y] # Optional: position for annotation numbers
annotation number,[x, y] "text"
标注文本同样必须加引号:
wardley-beta
title Annotations
component API [0.60, 0.70]
component Cache [0.50, 0.55]
component Database [0.40, 0.40]
API -> Cache
Cache -> Database
annotations [0.10, 0.90]
annotation 1,[0.60, 0.65] "Critical component"
annotation 2,[0.50, 0.50] "Performance layer"
annotation 3,[0.40, 0.35] "Data persistence"
从解析器实现看,annotations 语句只取第一个作为标注框位置(ast.annotations[0]),每条 annotation N,[x,y] "text" 会生成一条 { number, coordinates, text } 记录(wardleyParser.ts#L199-L210)。
加速器与减速器(Accelerators / Deaccelerators)
影响演化速度的外部力量:
wardley-beta
title Forces
component Legacy [0.20, 0.85]
component Modern [0.55, 0.60]
component AI [0.70, 0.35]
Legacy -> Modern
Modern -> AI
accelerator "AI Adoption" [0.55, 0.25]
deaccelerator "Legacy Constraints" [0.15, 0.75]
两者与 note 一样采用 [visibility, evolution] 坐标,分别写入 accelerators / deaccelerators 列表后由渲染器绘制为带符号的力。
高级特性
标签定位(Label Positioning)
微调组件标签的相对位置:
component Name [visibility, evolution] label [offsetX, offsetY]
- 负 X 向左移,正 X 向右移;
- 负 Y 向上移,正 Y 向下移。
e2e 用例 1-should-render-tea-shop.mmd 中即使用了 label [19, -4]、label [-57, 4] 这类偏移来避免标签互相遮挡,可作为实际调参参考。
自定义画布尺寸
wardley-beta
title Custom Size
size [800, 1000]
注意画布越矮,纵向空间越紧张;size 只影响画布宽高,坐标仍是 0–1 的相对值,渲染层会按画布等比投影。
完整示例:软件平台战略地图
下面这个综合示例覆盖了上述几乎所有语法特性(自定义阶段、anchor、装饰器、evolve、加速器/减速器、编号标注、note、标签偏移):
wardley-beta
title Software Platform Strategy
size [1100, 800]
evolution Genesis@0.25 -> Custom@0.5 -> Product@0.75 -> Commodity@1.0
anchor Customer [0.90, 0.95]
component "Mobile App" [0.80, 0.85] (build)
component "Web App" [0.75, 0.80] label [-60, 10] (build)
component "API Gateway" [0.70, 0.65] (buy)
component "Auth Service" [0.60, 0.55] (outsource)
component "Database" [0.50, 0.45] (buy) (inertia)
component "Cloud Platform" [0.30, 0.95] (market)
Customer -> "Mobile App"
Customer -> "Web App"
"Mobile App" -> "API Gateway"
"Web App" -> "API Gateway"
"API Gateway" -> "Auth Service"
"API Gateway" -> "Database"
"Database" -> "Cloud Platform"
evolve "API Gateway" 0.85
evolve "Database" 0.75
accelerator "Cloud Native" [0.20, 0.85]
deaccelerator "Legacy Data" [0.45, 0.35]
annotations [0.10, 0.20]
annotation 1,[0.78, 0.82] "User touchpoints"
annotation 2,[0.70, 0.60] "Integration layer"
annotation 3,[0.50, 0.40] "Data persistence"
note "Build mobile-first experience" [0.85, 0.90]
note "Migrate to cloud-native database" [0.60, 0.50]
配置与主题(Configuration)
Wardley Maps 支持 Mermaid 标准主题系统。配置项在 config.type.ts#L2013-L2046 中定义为 WardleyDiagramConfig(继承 BaseDiagramConfig),在 Mermaid 全局配置中以 'wardley-beta' 为键访问:
| 配置项 | 类型 | 渲染器默认值 | 说明 |
|---|---|---|---|
width |
number | 900 | 画布宽度(会被图中 size 覆盖) |
height |
number | 600 | 画布高度(会被图中 size 覆盖) |
padding |
number | 48 | 画布内边距,坐标投影的留白区域 |
nodeRadius |
number | 6 | 组件节点半径(管线父节点方形边长为其 1.6 倍) |
nodeLabelOffset |
number | 8 | 节点标签与节点的默认间距 |
axisFontSize |
number | 12 | 坐标轴文字字号 |
labelFontSize |
number | 10 | 组件标签字号 |
showGrid |
boolean | false | 是否显示背景网格 |
useMaxWidth |
boolean | true | 是否限制 SVG 最大宽度 |
此外,渲染器(wardleyRenderer.ts#L31-L50)会从主题变量 themeVariables.wardley.* 读取颜色,未定义时回退到通用主题变量或固定默认值:
| 主题变量 | 回退默认值 | 用途 |
|---|---|---|
wardley.backgroundColor |
background / #fff |
画布背景 |
wardley.axisColor |
#000 |
坐标轴线 |
wardley.gridColor |
rgba(100,100,100,0.2) |
网格线 |
wardley.componentFill / componentStroke |
#fff / #000 |
组件填充/描边 |
wardley.linkStroke |
#000 |
依赖连线颜色 |
wardley.evolutionStroke |
#dc3545 |
演化趋势红色箭头 |
wardley.annotationStroke / annotationTextColor / annotationFill |
#000 / 主文本色 / #fff |
标注样式 |
实现架构:从文本到 SVG
结合源码结构,整条渲染链路为:
- 检测:wardleyDetector.ts 匹配
wardley-beta头部,将文本路由到 wardley 图模块; - 解析:wardleyParser.ts 调用
@mermaid-js/parser包(packages/parser/,Langium 语法实现)的parse('wardley', input)得到 AST,再由populateDb遍历 AST,把 size、evolution 阶段、anchor、component、note、pipeline、link、evolve、annotations、accelerator 逐项写入数据库。坐标在此阶段统一通过toPercent归一化为 0–100 百分比,非法值直接抛错,错误信息会带上组件名上下文(如Component "Database" evolution),便于定位; - 数据模型:wardleyBuilder.ts 中的
WardleyBuilder维护节点(Map,支持同 ID 合并更新)、链接、趋势、管线、标注、注释、加速器、减速器、标注框、轴配置与画布尺寸,最终build()输出WardleyBuildResult;任何缺失坐标的节点都会在构建时抛错Node "xxx" is missing coordinates; - 渲染:wardleyRenderer.ts 使用 D3 直接绘制 SVG——背景矩形、坐标轴、阶段刻度、节点、链接(含三个方向不同的箭头 marker)、趋势虚线、注释与标注框。值得注意的是源码注释明确指出 Wardley DB 不对文本做 HTML 净化,因此渲染时标签一律使用
.text()而非.html()写入。
e2e 回归用例位于 e2e/diagrams/wardley/,共 6 组场景:Tea Shop 基础图、数据演化阶段、管线、链接类型与标注、自定义画布尺寸、以及一个 GPT Tokeniser 架构地图,可直接作为各种语法组合的真实示例参考。
语法速查表(Syntax Summary)
| 元素 | 语法 | 示例 |
|---|---|---|
| Diagram | wardley-beta |
wardley-beta |
| Title | title Text |
title My Map |
| Size | size [width, height] |
size [1100, 800] |
| Component | component Name [vis, evo] |
component API [0.6, 0.7] |
| Anchor | anchor Name [vis, evo] |
anchor User [0.9, 0.95] |
| Link | A -> B |
API -> Database |
| Flow | A +> B |
User +> API |
| Evolve | evolve Name targetEvo |
evolve API 0.85 |
| Note | note "Text" [vis, evo] |
note "Key insight" [0.4, 0.5] |
| Annotation | annotation N,[x,y] "Text" |
annotation 1,[0.5,0.5] "Critical" |
| Inertia | (inertia) |
component DB [0.4, 0.6] (inertia) |
| Strategy | (build|buy|outsource|market) |
component API [0.6, 0.7] (buy) |
| Pipeline | pipeline Parent { ... } |
见上文管线示例 |
| Evolution | evolution Stage1 -> Stage2 -> ... |
见上文演化阶段示例 |
限制与注意事项
- 不支持手绘风格:
look: handDrawn目前不适用于 Wardley Maps。从源码结构看,该图类型使用了独立的 D3 自绘渲染器(wardleyRenderer.ts),而非 Mermaid 共享的形状/手绘系统,因此无法接入 rough.js 手绘效果; - 图类型仍处于 beta:关键字为
wardley-beta,后续大版本可能调整语法,使用时以当前仓库的 语法源文档 为准(docs/syntax/wardley.md由其自动生成,不要直接编辑); - 文本安全:Wardley 图不对标签文本做 HTML 净化,渲染层仅以纯文本方式写入,这是出于该图类型独立数据通路的实现选择;
- 坐标取值:虽然文档主示例使用 0–1 小数,但解析器实际同时兼容 0–100 的百分比写法,超出任一范围都会报错;
- 趋势语法
Component -.- (x, y)使用标准(x, y)顺序,与其余位置的[visibility, evolution]顺序不同,编写时不要混淆。
掌握以上内容后,你可以直接用纯文本描述业务价值链与组件演化战略,并通过 Mermaid 的 initialize 配置和主题变量微调画布与配色,将 Wardley Map 嵌入文档、站点或演示流程中。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0627
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00