mcpField
G
graphviz-diagrams

graphviz-diagrams

github.com/mindmorass设计与 UI254 次安装37 周前更新
代码仓库

关于 graphviz-diagrams

使用 Graphviz DOT 制作复杂图表的技能,适用于需要精确布局的结构可视化。输出同时包含可编辑源码和渲染图像。

主要功能

  1. 01使用 DOT 创建图表
  2. 02将图表渲染为图像
  3. 03在 Markdown 中附上源码和图像
  4. 04选择多种布局引擎
  5. 05使用常见图类型示例

适用场景

  1. 01可视化复杂依赖关系
  2. 02记录调用图和代码流程
  3. 03绘制网络拓扑或状态机

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/mindmorass/reflex --skill graphviz-diagrams

安装后在 Claude Code 中输入/graphviz-diagrams确认已加载。

详细介绍

Graphviz 图表技能

用途

使用 Graphviz DOT 语言创建复杂的图形可视化,同时提供源代码和预渲染图像。

适用场景

  • 复杂依赖关系图
  • 调用图和代码流程
  • 网络拓扑
  • 层级结构
  • 具有复杂转换的状态机
  • 任何需要精确控制布局的图形

输出格式

每个 Graphviz 图表都应包含:

  1. 内嵌 DOT 源代码 - 供参考和后续编辑
  2. 预渲染图像 - 可在任何 Markdown 渲染器中查看
文档结构
## Diagram: [Name]

### Source
```dot
digraph G {
    A -> B
}
```

### Rendered
![Diagram Name](./attachments/diagram-name.png)

渲染工作流

步骤 1:编写 DOT 源代码
dot_source = """
digraph G {
    rankdir=LR;
    A -> B -> C;
}
"""
步骤 2:渲染为图像
import subprocess
from pathlib import Path

def render_graphviz(
    dot_source: str,
    output_path: Path,
    format: str = "png",
    engine: str = "dot"
) -> Path:
    """
    Render DOT source to image file.

    Args:
        dot_source: DOT language source code
        output_path: Output file path (without extension)
        format: Output format (png, svg, pdf)
        engine: Layout engine (dot, neato, fdp, circo, twopi, sfdp)

    Returns:
        Path to rendered image
    """
    output_file = output_path.with_suffix(f".{format}")

    result = subprocess.run(
        [engine, f"-T{format}", "-o", str(output_file)],
        input=dot_source,
        text=True,
        capture_output=True
    )

    if result.returncode != 0:
        raise RuntimeError(f"Graphviz error: {result.stderr}")

    return output_file
步骤 3:嵌入 Markdown
def create_diagram_markdown(
    name: str,
    dot_source: str,
    image_path: str
) -> str:
    """Create markdown with both source and rendered image."""
    return f"""## Diagram: {name}

### Source
```dot
{dot_source}
渲染结果

{name} """


## DOT Language Reference

### Basic Graph Types

#### Directed Graph (digraph)
```dot
digraph G {
    A -> B;
    B -> C;
    A -> C;
}
无向图(graph)
graph G {
    A -- B;
    B -- C;
    A -- C;
}
图属性
digraph G {
    // Graph attributes
    rankdir=LR;           // Direction: TB, BT, LR, RL
    splines=ortho;        // Edge style: line, polyline, curved, ortho, spline
    nodesep=0.5;          // Space between nodes
    ranksep=1.0;          // Space between ranks
    bgcolor="white";      // Background color
    fontname="Helvetica"; // Font for labels

    // Nodes and edges
    A -> B;
}
节点属性
digraph G {
    // Node defaults
    node [shape=box, style=filled, fillcolor=lightblue];

    // Individual node styling
    A [label="Start", shape=ellipse, fillcolor=green];
    B [label="Process
Data", shape=box];
    C [label="Decision", shape=diamond, fillcolor=yellow];
    D [label="End", shape=ellipse, fillcolor=red];

    A -> B -> C;
    C -> D;
}
常见节点形状
形状用途
box进程、操作
ellipse开始/结束、终端
diamond决策
circle状态
record结构化数据
Mrecord圆角记录
cylinder数据库
folder目录/集合
component组件
note注释
边属性
digraph G {
    // Edge defaults
    edge [color=gray, fontsize=10];

    A -> B [label="step 1", color=blue, penwidth=2];
    B -> C [label="step 2", style=dashed];
    C -> D [label="step 3", arrowhead=empty];
    D -> A [label="loop", style=dotted, constraint=false];
}
箭头样式
箭头描述
normal实心三角形(默认)
empty空心三角形
dot实心圆
odot空心圆
diamond实心菱形
none无箭头
veeV 形
box实心方形
子图和集群
digraph G {
    // Cluster (named subgraph with cluster_ prefix)
    subgraph cluster_frontend {
        label="Frontend";
        style=filled;
        fillcolor=lightgray;

        UI -> Components -> State;
    }

    subgraph cluster_backend {
        label="Backend";
        style=filled;
        fillcolor=lightyellow;

        API -> Service -> Database;
    }

    // Cross-cluster edges
    State -> API [label="HTTP"];
}
记录(结构化节点)
digraph G {
    node [shape=record];

    user [label="User|{id: int|name: string|email: string}"];
    order [label="Order|{id: int|user_id: int|total: decimal}"];

    user -> order [label="1:N"];
}
HTML 标签
digraph G {
    node [shape=none];

    table [label=<
        <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
            <TR><TD BGCOLOR="lightblue"><B>User</B></TD></TR>
            <TR><TD ALIGN="LEFT">id: int</TD></TR>
            <TR><TD ALIGN="LEFT">name: string</TD></TR>
            <TR><TD ALIGN="LEFT">email: string</TD></TR>
        </TABLE>
    >];
}

布局引擎

引擎最适合描述
dot层级结构有向图、树、DAG
neato网络无向图、弹簧模型
fdp大型网络力导向,可扩展
sfdp超大型网络多尺度力导向
circo环形布局环形布局
twopi径向布局从根节点向外的径向布局
用法
# Different engines produce different layouts
dot -Tpng graph.dot -o graph-hierarchical.png
neato -Tpng graph.dot -o graph-spring.png
circo -Tpng graph.dot -o graph-circular.png

常见模式

依赖关系图
digraph Dependencies {
    rankdir=BT;
    node [shape=box, style=filled, fillcolor=lightblue];

    // Packages
    app [label="app"];
    api [label="api"];
    core [label="core"];
    utils [label="utils"];
    db [label="database"];

    // Dependencies (arrows point to dependency)
    app -> api;
    app -> core;
    api -> core;
    api -> db;
    core -> utils;
    db -> utils;
}
状态机
digraph StateMachine {
    rankdir=LR;
    node [shape=circle];

    // Start state
    start [shape=point, width=0.2];

    // States
    idle [label="Idle"];
    loading [label="Loading"];
    success [label="Success", shape=doublecircle];
    error [label="Error"];

    // Transitions
    start -> idle;
    idle -> loading [label="fetch()"];
    loading -> success [label="200 OK"];
    loading -> error [label="error"];
    error -> idle [label="retry()"];
    success -> idle [label="reset()"];
}
调用图
digraph CallGraph {
    rankdir=TB;
    node [shape=box, fontname="Courier"];

    main [style=filled, fillcolor=lightgreen];
    main -> init;
    main -> process;
    main -> cleanup;

    init -> loadConfig;
    init -> connectDB;

    process -> validateInput;
    process -> transform;
    process -> save;

    transform -> normalize;
    transform -> enrich;

    save -> connectDB [style=dashed, label="reuse"];
}
网络拓扑
graph Network {
    layout=neato;
    overlap=false;
    node [shape=box];

    // Nodes
    internet [shape=cloud, label="Internet"];
    firewall [shape=box3d, label="Firewall"];
    lb [label="Load
Balancer"];
    web1 [label="Web 1"];
    web2 [label="Web 2"];
    app1 [label="App 1"];
    app2 [label="App 2"];
    db [shape=cylinder, label="Database"];

    // Connections
    internet -- firewall;
    firewall -- lb;
    lb -- web1;
    lb -- web2;
    web1 -- app1;
    web1 -- app2;
    web2 -- app1;
    web2 -- app2;
    app1 -- db;
    app2 -- db;
}
实体关系
digraph ERD {
    rankdir=LR;
    node [shape=record, fontname="Helvetica"];
    edge [arrowhead=none];

    user [label="<pk> User|id: PK\lname: string\lemail: string\l"];
    order [label="<pk> Order|id: PK\luser_id: FK\ltotal: decimal\l"];
    item [label="<pk> OrderItem|id: PK\lorder_id: FK\lproduct_id: FK\l"];
    product [label="<pk> Product|id: PK\lname: string\lprice: decimal\l"];

    user:pk -> order:pk [label="1:N", arrowhead=crow];
    order:pk -> item:pk [label="1:N", arrowhead=crow];
    product:pk -> item:pk [label="1:N", arrowhead=crow];
}
流程图
digraph Flowchart {
    rankdir=TB;
    node [fontname="Helvetica"];

    start [shape=ellipse, label="Start", style=filled, fillcolor=lightgreen];
    input [shape=parallelogram, label="Get Input"];
    validate [shape=diamond, label="Valid?"];
    process [shape=box, label="Process Data"];
    error [shape=box, label="Show Error", style=filled, fillcolor=lightyellow];
    output [shape=parallelogram, label="Output Result"];
    end [shape=ellipse, label="End", style=filled, fillcolor=lightcoral];

    start -> input;
    input -> validate;
    validate -> process [label="Yes"];
    validate -> error [label="No"];
    error -> input;
    process -> output;
    output -> end;
}

与发布器集成

Obsidian 集成
def publish_graphviz_to_obsidian(
    vault_path: str,
    folder: str,
    filename: str,
    diagram_name: str,
    dot_source: str
):
    """Publish Graphviz diagram to Obsidian with source and image."""
    from pathlib import Path

    vault = Path(vault_path)
    target_dir = vault / folder
    attachments_dir = vault / "attachments"

    target_dir.mkdir(parents=True, exist_ok=True)
    attachments_dir.mkdir(parents=True, exist_ok=True)

    # Render image
    image_name = f"{filename}-diagram.png"
    image_path = attachments_dir / image_name
    render_graphviz(dot_source, image_path.with_suffix(""), "png")

    # Create markdown with both source and image
    content = f"""# {diagram_name}

## Source

```dot
{dot_source}

渲染结果

![[{image_name}]] """

note_path = target_dir / f"{filename}.md"
note_path.write_text(content)

### Joplin Integration
```python
def publish_graphviz_to_joplin(
    notebook: str,
    title: str,
    diagram_name: str,
    dot_source: str
):
    """Publish Graphviz diagram to Joplin with source and image."""
    import tempfile
    from pathlib import Path

    with tempfile.TemporaryDirectory() as tmpdir:
        tmpdir = Path(tmpdir)

        # Render image
        image_path = tmpdir / "diagram.png"
        render_graphviz(dot_source, image_path.with_suffix(""), "png")

        # Create markdown
        content = f"""# {diagram_name}

## Source

```dot
{dot_source}

渲染结果

{diagram_name} """

    md_path = tmpdir / f"{title}.md"
    md_path.write_text(content)

    # 导入到 Joplin(导入 Markdown 和引用的图像)
    subprocess.run([
        "joplin", "import", str(tmpdir),
        "--notebook", notebook
    ], check=True)

## Graphviz vs Mermaid

| Feature | Graphviz | Mermaid |
|---------|----------|---------|
| **Layout control** | Precise, many engines | Automatic only |
| **Complexity** | Handles very large graphs | Better for simpler diagrams |
| **Rendering** | External tool required | Browser-native |
| **Styling** | Extensive options | Limited but sufficient |
| **Learning curve** | Steeper | Easier |
| **Use case** | Complex dependencies, call graphs | Quick diagrams, sequences |

**Use Graphviz when:**
- You need precise layout control
- Graph is large or complex
- You need specific node arrangements
- Creating dependency or call graphs

**Use Mermaid when:**
- Quick inline diagrams
- Sequence diagrams
- Simple flowcharts
- Native browser rendering preferred

## Prerequisites

### Install Graphviz
```bash
# macOS
brew install graphviz

# Ubuntu/Debian
sudo apt-get install graphviz

# Windows (chocolatey)
choco install graphviz

# Verify installation
dot -V

检查清单

创建 Graphviz 图表前:

  • 已安装 Graphviz(dot -V)
  • 输出目录可写
  • DOT 语法已验证
  • 已选择合适的布局引擎
  • 输出中包含源代码和图像
  • 图像路径适用于目标平台(Obsidian/Joplin)

评论

支持 Markdown