xiaohongshu
xiaohongshu
graphviz-diagrams
Create complex graph visualizations using Graphviz DOT language, with both source code and pre-rendered images.
Full skill instructions
Create complex graph visualizations using Graphviz DOT language, with both source code and pre-rendered images.
Every Graphviz diagram should include:
## Diagram: [Name]
### Source
```dot
digraph G {
A -> B
}
```
### Rendered

dot_source = """
digraph G {
rankdir=LR;
A -> B -> C;
}
"""
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
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}
"""
## DOT Language Reference
### Basic Graph Types
#### Directed Graph (digraph)
```dot
digraph G {
A -> B;
B -> C;
A -> C;
}
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;
}
| Shape | Use Case |
|---|---|
box | Process, action |
ellipse | Start/end, terminal |
diamond | Decision |
circle | State |
record | Structured data |
Mrecord | Rounded record |
cylinder | Database |
folder | Directory/collection |
component | Component |
note | Annotation |
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];
}
| Arrowhead | Description |
|---|---|
normal | Filled triangle (default) |
empty | Open triangle |
dot | Filled circle |
odot | Open circle |
diamond | Filled diamond |
none | No arrowhead |
vee | V-shape |
box | Filled square |
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"];
}
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>
>];
}
| Engine | Best For | Description |
|---|---|---|
dot | Hierarchies | Directed graphs, trees, DAGs |
neato | Networks | Undirected graphs, spring model |
fdp | Large networks | Force-directed, scalable |
sfdp | Very large | Multiscale force-directed |
circo | Circular | Circular layouts |
twopi | Radial | Radial layouts from root |
# 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;
}
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}
"""
md_path = tmpdir / f"{title}.md"
md_path.write_text(content)
# Import to Joplin (imports markdown and referenced images)
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
Before creating Graphviz diagrams:
dot -V)xiaohongshu
technical spec
product ux expert
database patterns
Conduct multi-agent task orchestration and workflow coordination.
Initialize project with Conductor artifacts (product definition,
Expert in web animations, transitions, and motion design using Framer Motion and CSS
Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...
PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.
Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...
Display project status, active tracks, and next actions
Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.
Generate, edit, and beat-sync AI video with leading models in one workspace.
The world's fastest calendar for remote work
Transform Your Design with AI Designer by ImgCreator.ai
Revolutionizing Video Production with AI-Powered Creativity
Extend an image past the frame and let AI fill the new aspect ratio.
Discover your celebrity doppelgänger with StarByFace!
ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.
Opus.ai: Revolutionize Your Web Experience