可操作的完整示例
上方流程图使用内置 Mermaid;下方柱图是本页提供的自定义 echarts 围栏扩展。点击编辑源码、改值、移开选区,图表会依据同一段 Markdown 更新。读取 Markdown 可以验证渲染没有重新序列化围栏。
内置文本绘图与自定义图表
| 场景 | 建议 |
|---|---|
| Mermaid 的 flowchart、sequenceDiagram 等 | 安装 Mermaid,使用 mermaid 围栏 |
| PlantUML 时序、类、用例、组件、状态、部署等图 | 安装 TextDiagrams,使用 plantuml 或 puml 围栏 |
| Graphviz 关系、分组架构与依赖图 | 安装 TextDiagrams,使用 dot 或 graphviz 围栏 |
自己的 echarts JSON 数据协议 | 使用本例 codec、块级投影和受控渲染器 |
flow / flowchart.js 或其他 DSL | 自定义围栏识别和引擎适配器;不是内置语言别名 |
这里的 Mermaid 流程图正文以 flowchart LR 开始,围栏仍叫 mermaid。不要把 Mermaid flowchart 与 flowchart.js 的 DSL 当作同一种语法;内置扩展不会自动把 flow 交给另一个引擎。
安装依赖和已有能力
pnpm add '@quirekit/msfe-markdown-extras@workspace:*' echarts
import { Mermaid } from '@quirekit/msfe-markdown-extras'
import { VueComponentViewRenderer } from '@quirekit/msfe-vue'
import PreviewControls from './preview-controls.vue'
const diagrams = Mermaid.configure({
controls: VueComponentViewRenderer(PreviewControls),
})
内置 Mermaid 已管理关闭围栏识别、异步渲染、失败时显示源码、重试和释放。其公开配置目前是预览操作 controls,没有名为 render 的任意引擎替换参数。需要完全不同的渲染过程时,创建自己的扩展。
当前内置渲染启用严格安全模式、禁用 HTML 标签并校验 SVG;不接受文档内初始化指令,存在源码长度和边数量限制。无法渲染时保留可读源码。语法范围由所安装的 Mermaid 版本决定,参见 Mermaid 官方用法。
PlantUML 与 Graphviz/DOT
独立 MSFE 宿主安装 TextDiagrams;MD Editor 默认已安装。它与 Mermaid 分别识别自己的语言,不争抢同一个围栏:
import { Mermaid, TextDiagrams } from '@quirekit/msfe-markdown-extras'
const extensions = [Mermaid, TextDiagrams]
```plantuml
@startuml
客户端 -> 服务端: 请求
服务端 --> 客户端: 响应
@enduml
```
```dot
digraph G {
rankdir=LR;
草稿 -> 审阅 -> 发布;
}
```
MD Editor 的“插入 → 文本绘图”打开与 Classic、Block 共用的源码工作台。保存后仍是标准 Markdown 围栏;取消或渲染失败不会提交草稿,已有错误源码继续可读、可修改。features.extras.mermaid 与 features.extras.textDiagram 分别控制 Mermaid 和 PlantUML / DOT 能力。
文本绘图独立文档
通用工作台、25 个双语模板、CodeMirror 快捷键、SVG / PNG 下载、独立 Vue 接入和资源部署统一在文本绘图文档站维护。可以直接打开在线工作台或支持范围。以上为本地固定端口预览,规划域名为 text-diagram.quirekit.com。
本页继续说明 MSFE 的围栏集成与自定义图表扩展。PlantUML 使用本地官方 JavaScript 核心,语法与外观不承诺同完整 Java 发行版一致;失败时保留源码。
1. 定义数据协议
本例接受的 JSON 是 { type: 'bar' | 'line', labels: string[], values: number[] },两组数组等长,1–50 项,数值必须有限。文本限制 16,000 个 UTF-16 单元。charts/data.ts 拒绝未知字段,避免误以为支持任意 ECharts 配置。
~~~echarts
{"type":"line","labels":["Jan","Feb","Mar"],"values":[12,20,16]}
~~~
这是可复制的最小业务协议,不是 MSFE 内置 ECharts 功能,也不是完整 EChartsOption 导出器。扩展数据字段时,同时扩展校验、图表映射和测试。不要把源码交给 eval / new Function;JSON 无法也不应该承载 formatter 函数。
2. 只识别已确认的完整围栏
charts/extension.ts 使用 defineSource({ nodes: ['FencedCode'] }),检查 CodeInfo、两个 CodeMark 与允许的父上下文,读取 CodeText。未闭合、未知语言或不符合范围的结构返回 null,继续显示源码。
为了使完整例子可审查,自定义 ECharts 示例仅替换顶层围栏;列表和引用中的 ECharts 保持源码。内置 Mermaid 有自己的容器处理。若扩展本例支持嵌套,必须处理列表标记、引用前缀、缩进和光标命中,而不能直接把 match.from 扩成整行就认为完成。
3. 通过块级投影提供视图
addProjectionLayers() 返回 placement: 'block',再通过 componentView(chartRenderer, props) 描述非编辑预览。块级布局在 CodeMirror 计算视口之前提供,避免跨行替换引起高度错误。
保留稳定的 renderer 身份与 key,属性变化交给 update()。活动选区进入范围会显露源码;不要让图表 DOM 成为第二个编辑器。没有确认修改需求的预览 codec 可以令 patch() 返回 null。
4. 管理加载、尺寸和释放
charts/renderer.ts 将运行时 scope 和 requestMeasure 传入 Vue 视图。每次源码变化先取消旧请求,再在子作用域中加载 ECharts。卸载、换文档、取消后迟到的资源都必须释放。
容器先有实际尺寸,再调用 echarts.init()。ResizeObserver 负责容器尺寸变化后的 resize();释放时断开观察器并 dispose()。本例固定图表高度,并在状态切换后通知 CodeMirror 测量。这些要求对应 ECharts 容器尺寸与销毁文档。
加载失败展示说明、精确围栏源码和重试按钮;源码内容不因错误而丢失。只读下关闭编辑源码动作,但仍可查看和重试。
5. 接入 flowchart.js 或另一套引擎
复用本例的完整结构,但需要逐项替换:
- 为扩展和投影层设置唯一名称,把允许语言改为
flow,别与 Mermaid 争抢同一围栏。 - 将
parseChartData()换成该 DSL 的校验及长度限制;不要把 DSL 当 JSON 解析。 - 在浏览器生命周期中按需加载自己的引擎。flowchart.js 的公共流程是
parse(source)后在有尺寸的目标容器上drawSVG(...),具体参数以 官方项目文档 为准。 - 将引擎实例、SVG、事件和可能的全局依赖封装进独立资源租约;更新先释放旧实例。不要假设另一引擎的取消、清理或 CSS 行为与 ECharts 一样。
- 限制链接、HTML、外部资源和危险 SVG 输出;保留可复制源码回退,并补上缩放、主题及跨选区验证。
本页交互示例实际运行 Mermaid 与 ECharts;flowchart.js 是上述适配路径,不宣称已随 MSFE 安装或验证。复杂布局引擎也可移至 Worker,但仍需版本/取消校验和受控的 DOM 渲染出口。
验收清单
比较编辑前后的精确源码;覆盖有效/无效 JSON、快速连续改值、加载中换文档、离开视口、切换主题、窄容器、只读、复制、撤销及原生选区显露。不要只验证“出现一张图”。继续阅读 资源生命周期 和 投影层。