搜索文章

输入关键词开始搜索

技术拆解-Mermaid

思考#技术拆解#AI#D3#数据可视化#数据结构

运行

npm run dev:vite

然后访问:http://localhost:9000/

绘图

饼图

D3.js 可以参考饼图的代码: mermaid/packages/mermaid/src/diagrams/pie/pieRenderer.ts

flowchart

D3.js + Dagre

mindmap

Cytoscape + D3.js 布局用的 Cytoscape 画图用的 D3.js

草图风格 Rough

代码结构

  • spec.ts:使用 Jest 框架编写的单元测试文件,主要用于测试 pie 模块的功能
  • Db.ts:数据管理,各种 add、set、get 方法
  • Detector.ts:识别 pie 的文本,并 import pieDiagram.js
  • Diagram.ts:对外的 Facade,包含了 Db、Renderer、Parser、Styles 等
  • Parser.ts:AST 解析文本为 Pie 对象
  • Renderer.ts:绘图
  • Styles.ts:样式 Token
  • Types.ts:类型定义

数据结构

图表

基类

/**
 * Generic Diagram DB that may apply to any diagram type.
 */
export interface DiagramDB {
  // config
  getConfig?: () => BaseDiagramConfig | undefined;

  // db
  clear?: () => void;
  setDiagramTitle?: (title: string) => void;
  getDiagramTitle?: () => string;
  setAccTitle?: (title: string) => void;
  getAccTitle?: () => string;
  setAccDescription?: (description: string) => void;
  getAccDescription?: () => string;

  setDisplayMode?: (title: string) => void;
  bindFunctions?: (element: Element) => void;
}

Pie

export interface PieDB extends DiagramDB {
  // config
  getConfig: () => Required<PieDiagramConfig>;

  // common db
  clear: () => void;
  setDiagramTitle: (title: string) => void;
  getDiagramTitle: () => string;
  setAccTitle: (title: string) => void;
  getAccTitle: () => string;
  setAccDescription: (description: string) => void;
  getAccDescription: () => string;

  // diagram db
  addSection: ({ label, value }: D3Section) => void;
  getSections: () => Sections;
  setShowData: (toggle: boolean) => void;
  getShowData: () => boolean;
}

draw()

/**
 * Type for function draws diagram in the tag with id: id based on the graph definition in text.
 *
 * @param text - The text of the diagram.
 * @param id - The id of the diagram which will be used as a DOM element id.
 * @param version - MermaidJS version from package.json.
 * @param diagramObject - A standard diagram containing the DB and the text and type etc of the diagram.
 */
export type DrawDefinition = (
  text: string,
  id: string,
  version: string,
  diagramObject: Diagram
) => void | Promise<void>;

布局 Layout

协议

flowchart

样式是在末尾定义的,给每个节点定义的样式,通过节点的 ID(比如 A、B、C)进行绑定。 感觉这样定义,表现力并不强?而且一些复杂的效果估计不好描述。 动画怎么描述?

flowchart LR
 subgraph subgraph_zv2q8ucnp["Shape descriptions"]
        customer(("Customer"))
        Support["Support"]
        Technician{{"Technician"}}
        Decision{"Decision"}
  end
    A(("Reported issue")) --> B["Ticket is created"]
    B --> C{"Working hours?"}
    C -- Yes --> E{{"Tickets are sent to day team for response"}}
    C -- No --> F["Tickets are sent to on-call staff for response"]
    E --> Worked{"Ticket being worked on?"}
    F --> Worked
    Worked -- Yes --> G["Work on the tickets based on priority"]
    Worked -- No --> Reminder["Reminder is sent"]
    Reminder --> Worked
    G --> H["Team fixes the issue"]
    H --> I{"Is the issue resolved?"}
    I -- Yes --> Done["Ticket is closed and follow-up email is sent"]
    I -- No --> H

     customer:::redNode
     Support:::pinkNode
     Technician:::yellowNode
     Decision:::blackNode
     A:::redNode
     C:::blackNode
     E:::yellowNode
     F:::pinkNode
     Worked:::reminderNode
     G:::pinkNode
     H:::pinkNode
     I:::reminderNode
     Done:::greenNode
    classDef redNode fill:#D50000,color:#000000
    classDef pinkNode fill:#E1BEE7,color:#000000
    classDef yellowNode fill:#FFF9C4,color:#000000
    classDef blackNode fill:#000000,stroke:#FFD600,stroke-width:4px,stroke-dasharray: 0,color:#FFFFFF
    classDef greenNode fill:#00F840,color:#000000
    classDef reminderNode stroke:#FFD600,stroke-width:4px,stroke-dasharray: 0,fill:#000000,color:#FFFFFF
    classDef blueSubgraph fill:#BBDEFB
    style A stroke:#2962FF,fill:#AA00FF
    style C fill:#00C853
    linkStyle 2 stroke:#00C853,fill:none
    linkStyle 3 stroke:#D50000,fill:none
    linkStyle 6 stroke:#00C853,fill:none
    linkStyle 7 stroke:#D50000,fill:none
    linkStyle 11 stroke:#00C853,fill:none
    linkStyle 12 stroke:#D50000,fill:none

Takeaways

为什么节点要展平成平铺的 g 结构:增加可编辑性

类似 Photoshop,层的概念,可以任意移动布局。 因此带有编辑概念的(Mermaid、Napkin),都是这样的平铺结构。

日志

log.info('REF0:');

不足

缺少动画

缺少 timeline 播放

资料

github: https://github.com/mermaid-js/mermaid

在线编辑器: https://github.com/mermaid-js/mermaid-live-editor

mermaidchart: https://www.mermaidchart.com/ 这个是企业版,支持了拖拽布局、AI、画布、节点样式编辑等功能。 其中画布、节点样式编辑目前仅支持 Flowchart 和 Sequence Diagram。