[{"data":1,"prerenderedAt":698},["ShallowReactive",2],{"msfe-doc:\u002Fextensions\u002Fdiagrams":3},{"id":4,"title":5,"body":6,"description":685,"extension":686,"keywords":687,"locale":691,"meta":692,"navigation":209,"order":193,"path":693,"section":694,"seo":695,"stem":696,"__hash__":697},"docs\u002Fextensions\u002Fdiagrams.zh-CN.md","图表与代码块预览",{"type":7,"value":8,"toc":672},"minimark",[9,13,26,30,33,122,135,138,154,252,266,277,281,290,322,398,413,416,440,443,447,458,478,493,497,523,530,534,548,560,564,578,601,604,608,611,651,654,657,668],[10,11,12],"h2",{"id":12},"可操作的完整示例",[14,15,16,17,21,22,25],"p",{},"上方流程图使用内置 ",[18,19,20],"code",{},"Mermaid","；下方柱图是本页提供的自定义 ",[18,23,24],{},"echarts"," 围栏扩展。点击编辑源码、改值、移开选区，图表会依据同一段 Markdown 更新。读取 Markdown 可以验证渲染没有重新序列化围栏。",[27,28],"msfe-demo",{"name":29},"charts\u002Feditor",[10,31,32],{"id":32},"内置文本绘图与自定义图表",[34,35,36,49],"table",{},[37,38,39],"thead",{},[40,41,42,46],"tr",{},[43,44,45],"th",{},"场景",[43,47,48],{},"建议",[50,51,52,68,85,100,111],"tbody",{},[40,53,54,58],{},[55,56,57],"td",{},"Mermaid 的 flowchart、sequenceDiagram 等",[55,59,60,61,63,64,67],{},"安装 ",[18,62,20],{},"，使用 ",[18,65,66],{},"mermaid"," 围栏",[40,69,70,73],{},[55,71,72],{},"PlantUML 时序、类、用例、组件、状态、部署等图",[55,74,60,75,63,78,81,82,67],{},[18,76,77],{},"TextDiagrams",[18,79,80],{},"plantuml"," 或 ",[18,83,84],{},"puml",[40,86,87,90],{},[55,88,89],{},"Graphviz 关系、分组架构与依赖图",[55,91,60,92,63,94,81,97,67],{},[18,93,77],{},[18,95,96],{},"dot",[18,98,99],{},"graphviz",[40,101,102,108],{},[55,103,104,105,107],{},"自己的 ",[18,106,24],{}," JSON 数据协议",[55,109,110],{},"使用本例 codec、块级投影和受控渲染器",[40,112,113,119],{},[55,114,115,118],{},[18,116,117],{},"flow"," \u002F flowchart.js 或其他 DSL",[55,120,121],{},"自定义围栏识别和引擎适配器；不是内置语言别名",[14,123,124,125,128,129,131,132,134],{},"这里的 Mermaid 流程图正文以 ",[18,126,127],{},"flowchart LR"," 开始，围栏仍叫 ",[18,130,66],{},"。不要把 Mermaid flowchart 与 flowchart.js 的 DSL 当作同一种语法；内置扩展不会自动把 ",[18,133,117],{}," 交给另一个引擎。",[10,136,137],{"id":137},"安装依赖和已有能力",[139,140,145],"pre",{"className":141,"code":142,"language":143,"meta":144,"style":144},"language-sh shiki shiki-themes github-light github-light github-dark","pnpm add '@quirekit\u002Fmsfe-markdown-extras@workspace:*' echarts\n","sh","",[18,146,147],{"__ignoreMap":144},[148,149,152],"span",{"class":150,"line":151},"line",1,[148,153,142],{},[139,155,159],{"className":156,"code":157,"language":158,"meta":144,"style":144},"language-ts shiki shiki-themes github-light github-light github-dark","import { Mermaid } from '@quirekit\u002Fmsfe-markdown-extras'\nimport { VueComponentViewRenderer } from '@quirekit\u002Fmsfe-vue'\nimport PreviewControls from '.\u002Fpreview-controls.vue'\n\nconst diagrams = Mermaid.configure({\n  controls: VueComponentViewRenderer(PreviewControls),\n})\n","ts",[18,160,161,178,191,204,211,234,246],{"__ignoreMap":144},[148,162,163,167,171,174],{"class":150,"line":151},[148,164,166],{"class":165},"sDD9d","import",[148,168,170],{"class":169},"sVPnS"," { Mermaid } ",[148,172,173],{"class":165},"from",[148,175,177],{"class":176},"s-HEn"," '@quirekit\u002Fmsfe-markdown-extras'\n",[148,179,181,183,186,188],{"class":150,"line":180},2,[148,182,166],{"class":165},[148,184,185],{"class":169}," { VueComponentViewRenderer } ",[148,187,173],{"class":165},[148,189,190],{"class":176}," '@quirekit\u002Fmsfe-vue'\n",[148,192,194,196,199,201],{"class":150,"line":193},3,[148,195,166],{"class":165},[148,197,198],{"class":169}," PreviewControls ",[148,200,173],{"class":165},[148,202,203],{"class":176}," '.\u002Fpreview-controls.vue'\n",[148,205,207],{"class":150,"line":206},4,[148,208,210],{"emptyLinePlaceholder":209},true,"\n",[148,212,214,217,221,224,227,231],{"class":150,"line":213},5,[148,215,216],{"class":165},"const",[148,218,220],{"class":219},"sUNQB"," diagrams",[148,222,223],{"class":165}," =",[148,225,226],{"class":169}," Mermaid.",[148,228,230],{"class":229},"sgQzM","configure",[148,232,233],{"class":169},"({\n",[148,235,237,240,243],{"class":150,"line":236},6,[148,238,239],{"class":169},"  controls: ",[148,241,242],{"class":229},"VueComponentViewRenderer",[148,244,245],{"class":169},"(PreviewControls),\n",[148,247,249],{"class":150,"line":248},7,[148,250,251],{"class":169},"})\n",[14,253,254,255,257,258,261,262,265],{},"内置 ",[18,256,20],{}," 已管理关闭围栏识别、异步渲染、失败时显示源码、重试和释放。其公开配置目前是预览操作 ",[18,259,260],{},"controls","，没有名为 ",[18,263,264],{},"render"," 的任意引擎替换参数。需要完全不同的渲染过程时，创建自己的扩展。",[14,267,268,269,276],{},"当前内置渲染启用严格安全模式、禁用 HTML 标签并校验 SVG；不接受文档内初始化指令，存在源码长度和边数量限制。无法渲染时保留可读源码。语法范围由所安装的 Mermaid 版本决定，参见 ",[270,271,275],"a",{"href":272,"rel":273},"https:\u002F\u002Fmermaid.js.org\u002Fconfig\u002Fusage.html",[274],"nofollow","Mermaid 官方用法","。",[10,278,280],{"id":279},"plantuml-与-graphvizdot","PlantUML 与 Graphviz\u002FDOT",[14,282,283,284,286,287,289],{},"独立 MSFE 宿主安装 ",[18,285,77],{},"；MD Editor 默认已安装。它与 ",[18,288,20],{}," 分别识别自己的语言，不争抢同一个围栏：",[139,291,293],{"className":156,"code":292,"language":158,"meta":144,"style":144},"import { Mermaid, TextDiagrams } from '@quirekit\u002Fmsfe-markdown-extras'\n\nconst extensions = [Mermaid, TextDiagrams]\n",[18,294,295,306,310],{"__ignoreMap":144},[148,296,297,299,302,304],{"class":150,"line":151},[148,298,166],{"class":165},[148,300,301],{"class":169}," { Mermaid, TextDiagrams } ",[148,303,173],{"class":165},[148,305,177],{"class":176},[148,307,308],{"class":150,"line":180},[148,309,210],{"emptyLinePlaceholder":209},[148,311,312,314,317,319],{"class":150,"line":193},[148,313,216],{"class":165},[148,315,316],{"class":219}," extensions",[148,318,223],{"class":165},[148,320,321],{"class":169}," [Mermaid, TextDiagrams]\n",[139,323,327],{"className":324,"code":325,"language":326,"meta":144,"style":144},"language-markdown shiki shiki-themes github-light github-light github-dark","```plantuml\n@startuml\n客户端 -> 服务端: 请求\n服务端 --> 客户端: 响应\n@enduml\n```\n\n```dot\ndigraph G {\n  rankdir=LR;\n  草稿 -> 审阅 -> 发布;\n}\n```\n","markdown",[18,328,329,334,339,344,349,354,359,363,369,375,381,387,393],{"__ignoreMap":144},[148,330,331],{"class":150,"line":151},[148,332,333],{},"```plantuml\n",[148,335,336],{"class":150,"line":180},[148,337,338],{},"@startuml\n",[148,340,341],{"class":150,"line":193},[148,342,343],{},"客户端 -> 服务端: 请求\n",[148,345,346],{"class":150,"line":206},[148,347,348],{},"服务端 --> 客户端: 响应\n",[148,350,351],{"class":150,"line":213},[148,352,353],{},"@enduml\n",[148,355,356],{"class":150,"line":236},[148,357,358],{},"```\n",[148,360,361],{"class":150,"line":248},[148,362,210],{"emptyLinePlaceholder":209},[148,364,366],{"class":150,"line":365},8,[148,367,368],{},"```dot\n",[148,370,372],{"class":150,"line":371},9,[148,373,374],{},"digraph G {\n",[148,376,378],{"class":150,"line":377},10,[148,379,380],{},"  rankdir=LR;\n",[148,382,384],{"class":150,"line":383},11,[148,385,386],{},"  草稿 -> 审阅 -> 发布;\n",[148,388,390],{"class":150,"line":389},12,[148,391,392],{},"}\n",[148,394,396],{"class":150,"line":395},13,[148,397,358],{},[14,399,400,404,405,408,409,412],{},[270,401,403],{"href":402},"\u002Fmd-editor","MD Editor"," 的“插入 → 文本绘图”打开与 Classic、Block 共用的源码工作台。保存后仍是标准 Markdown 围栏；取消或渲染失败不会提交草稿，已有错误源码继续可读、可修改。",[18,406,407],{},"features.extras.mermaid"," 与 ",[18,410,411],{},"features.extras.textDiagram"," 分别控制 Mermaid 和 PlantUML \u002F DOT 能力。",[10,414,415],{"id":415},"文本绘图独立文档",[14,417,418,419,424,425,430,431,436,437,276],{},"通用工作台、25 个双语模板、CodeMirror 快捷键、SVG \u002F PNG 下载、独立 Vue 接入和资源部署统一在",[270,420,423],{"href":421,"rel":422},"http:\u002F\u002F127.0.0.1:3260\u002F",[274],"文本绘图文档站","维护。可以直接打开",[270,426,429],{"href":427,"rel":428},"http:\u002F\u002F127.0.0.1:3260\u002Fplayground",[274],"在线工作台","或",[270,432,435],{"href":433,"rel":434},"http:\u002F\u002F127.0.0.1:3260\u002Freference\u002Fsupport",[274],"支持范围","。以上为本地固定端口预览，规划域名为 ",[18,438,439],{},"text-diagram.quirekit.com",[14,441,442],{},"本页继续说明 MSFE 的围栏集成与自定义图表扩展。PlantUML 使用本地官方 JavaScript 核心，语法与外观不承诺同完整 Java 发行版一致；失败时保留源码。",[10,444,446],{"id":445},"_1-定义数据协议","1. 定义数据协议",[14,448,449,450,453,454,457],{},"本例接受的 JSON 是 ",[18,451,452],{},"{ type: 'bar' | 'line', labels: string[], values: number[] }","，两组数组等长，1–50 项，数值必须有限。文本限制 16,000 个 UTF-16 单元。",[18,455,456],{},"charts\u002Fdata.ts"," 拒绝未知字段，避免误以为支持任意 ECharts 配置。",[139,459,461],{"className":324,"code":460,"language":326,"meta":144,"style":144},"~~~echarts\n{\"type\":\"line\",\"labels\":[\"Jan\",\"Feb\",\"Mar\"],\"values\":[12,20,16]}\n~~~\n",[18,462,463,468,473],{"__ignoreMap":144},[148,464,465],{"class":150,"line":151},[148,466,467],{},"~~~echarts\n",[148,469,470],{"class":150,"line":180},[148,471,472],{},"{\"type\":\"line\",\"labels\":[\"Jan\",\"Feb\",\"Mar\"],\"values\":[12,20,16]}\n",[148,474,475],{"class":150,"line":193},[148,476,477],{},"~~~\n",[14,479,480,481,484,485,488,489,492],{},"这是可复制的最小业务协议，不是 MSFE 内置 ECharts 功能，也不是完整 ",[18,482,483],{},"EChartsOption"," 导出器。扩展数据字段时，同时扩展校验、图表映射和测试。不要把源码交给 ",[18,486,487],{},"eval"," \u002F ",[18,490,491],{},"new Function","；JSON 无法也不应该承载 formatter 函数。",[10,494,496],{"id":495},"_2-只识别已确认的完整围栏","2. 只识别已确认的完整围栏",[14,498,499,502,503,506,507,510,511,514,515,518,519,522],{},[18,500,501],{},"charts\u002Fextension.ts"," 使用 ",[18,504,505],{},"defineSource({ nodes: ['FencedCode'] })","，检查 ",[18,508,509],{},"CodeInfo","、两个 ",[18,512,513],{},"CodeMark"," 与允许的父上下文，读取 ",[18,516,517],{},"CodeText","。未闭合、未知语言或不符合范围的结构返回 ",[18,520,521],{},"null","，继续显示源码。",[14,524,525,526,529],{},"为了使完整例子可审查，自定义 ECharts 示例仅替换顶层围栏；列表和引用中的 ECharts 保持源码。内置 Mermaid 有自己的容器处理。若扩展本例支持嵌套，必须处理列表标记、引用前缀、缩进和光标命中，而不能直接把 ",[18,527,528],{},"match.from"," 扩成整行就认为完成。",[10,531,533],{"id":532},"_3-通过块级投影提供视图","3. 通过块级投影提供视图",[14,535,536,539,540,543,544,547],{},[18,537,538],{},"addProjectionLayers()"," 返回 ",[18,541,542],{},"placement: 'block'","，再通过 ",[18,545,546],{},"componentView(chartRenderer, props)"," 描述非编辑预览。块级布局在 CodeMirror 计算视口之前提供，避免跨行替换引起高度错误。",[14,549,550,551,554,555,539,558,276],{},"保留稳定的 renderer 身份与 key，属性变化交给 ",[18,552,553],{},"update()","。活动选区进入范围会显露源码；不要让图表 DOM 成为第二个编辑器。没有确认修改需求的预览 codec 可以令 ",[18,556,557],{},"patch()",[18,559,521],{},[10,561,563],{"id":562},"_4-管理加载尺寸和释放","4. 管理加载、尺寸和释放",[14,565,566,569,570,573,574,577],{},[18,567,568],{},"charts\u002Frenderer.ts"," 将运行时 ",[18,571,572],{},"scope"," 和 ",[18,575,576],{},"requestMeasure"," 传入 Vue 视图。每次源码变化先取消旧请求，再在子作用域中加载 ECharts。卸载、换文档、取消后迟到的资源都必须释放。",[14,579,580,581,276,584,587,588,591,592,595,596,276],{},"容器先有实际尺寸，再调用 ",[18,582,583],{},"echarts.init()",[18,585,586],{},"ResizeObserver"," 负责容器尺寸变化后的 ",[18,589,590],{},"resize()","；释放时断开观察器并 ",[18,593,594],{},"dispose()","。本例固定图表高度，并在状态切换后通知 CodeMirror 测量。这些要求对应 ",[270,597,600],{"href":598,"rel":599},"https:\u002F\u002Fecharts.apache.org\u002Fhandbook\u002Fen\u002Fconcepts\u002Fchart-size\u002F",[274],"ECharts 容器尺寸与销毁文档",[14,602,603],{},"加载失败展示说明、精确围栏源码和重试按钮；源码内容不因错误而丢失。只读下关闭编辑源码动作，但仍可查看和重试。",[10,605,607],{"id":606},"_5-接入-flowchartjs-或另一套引擎","5. 接入 flowchart.js 或另一套引擎",[14,609,610],{},"复用本例的完整结构，但需要逐项替换：",[612,613,614,621,628,645,648],"ol",{},[615,616,617,618,620],"li",{},"为扩展和投影层设置唯一名称，把允许语言改为 ",[18,619,117],{},"，别与 Mermaid 争抢同一围栏。",[615,622,623,624,627],{},"将 ",[18,625,626],{},"parseChartData()"," 换成该 DSL 的校验及长度限制；不要把 DSL 当 JSON 解析。",[615,629,630,631,634,635,638,639,644],{},"在浏览器生命周期中按需加载自己的引擎。flowchart.js 的公共流程是 ",[18,632,633],{},"parse(source)"," 后在有尺寸的目标容器上 ",[18,636,637],{},"drawSVG(...)","，具体参数以 ",[270,640,643],{"href":641,"rel":642},"https:\u002F\u002Fgithub.com\u002Fadrai\u002Fflowchart.js",[274],"官方项目文档"," 为准。",[615,646,647],{},"将引擎实例、SVG、事件和可能的全局依赖封装进独立资源租约；更新先释放旧实例。不要假设另一引擎的取消、清理或 CSS 行为与 ECharts 一样。",[615,649,650],{},"限制链接、HTML、外部资源和危险 SVG 输出；保留可复制源码回退，并补上缩放、主题及跨选区验证。",[14,652,653],{},"本页交互示例实际运行 Mermaid 与 ECharts；flowchart.js 是上述适配路径，不宣称已随 MSFE 安装或验证。复杂布局引擎也可移至 Worker，但仍需版本\u002F取消校验和受控的 DOM 渲染出口。",[10,655,656],{"id":656},"验收清单",[14,658,659,660,573,664,276],{},"比较编辑前后的精确源码；覆盖有效\u002F无效 JSON、快速连续改值、加载中换文档、离开视口、切换主题、窄容器、只读、复制、撤销及原生选区显露。不要只验证“出现一张图”。继续阅读 ",[270,661,663],{"href":662},"\u002Fextensions\u002Fresources","资源生命周期",[270,665,667],{"href":666},"\u002Fextensions\u002Fprojections","投影层",[669,670,671],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sDD9d, html code.shiki .sDD9d{--shiki-default:#D73A49;--shiki-light:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVPnS, html code.shiki .sVPnS{--shiki-default:#24292E;--shiki-light:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s-HEn, html code.shiki .s-HEn{--shiki-default:#032F62;--shiki-light:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sUNQB, html code.shiki .sUNQB{--shiki-default:#005CC5;--shiki-light:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sgQzM, html code.shiki .sgQzM{--shiki-default:#6F42C1;--shiki-light:#6F42C1;--shiki-dark:#B392F0}",{"title":144,"searchDepth":180,"depth":180,"links":673},[674,675,676,677,678,679,680,681,682,683,684],{"id":12,"depth":180,"text":12},{"id":32,"depth":180,"text":32},{"id":137,"depth":180,"text":137},{"id":279,"depth":180,"text":280},{"id":415,"depth":180,"text":415},{"id":445,"depth":180,"text":446},{"id":495,"depth":180,"text":496},{"id":532,"depth":180,"text":533},{"id":562,"depth":180,"text":563},{"id":606,"depth":180,"text":607},{"id":656,"depth":180,"text":656},"从 Mermaid 流程图到 ECharts，构建具有加载、失败回退和清理的源码预览。","md",[20,117,688,24,689,517,690],"flowchart","diagram","async","zh-CN",{},"\u002Fextensions\u002Fdiagrams","扩展开发",{"title":5,"description":685},"extensions\u002Fdiagrams.zh-CN","DOUeaTiEpJz6M3pkutX9XMUIsH6wHyLwV1XadRs45Bs",1793046311420]