flowgraph

A lightweight MoonBit library for building directed graphs and exporting to Graphviz DOT or Mermaid flowcharts.

moon add bobzhang/flowgraph@0.1.1
Download zip
Author
Version
0.1.1
License
Apache-2.0
Last updated
3 months ago
Downloads
35
README

#bobzhang/dot

A lightweight MoonBit library for building and visualizing directed graphs. Generate both Graphviz DOT format and Mermaid flowcharts from the same graph structure.

#Features

  • 🎨 Dual Output Formats: Export to DOT (Graphviz) or Mermaid flowcharts
  • 🎭 Flexible Styling: Customize node shapes, colors, and edge styles
  • 🔄 Bidirectional Edges: Support for bidirectional relationships
  • 📦 Subgraphs/Clusters: Group related nodes together
  • 🧩 Simple API: Fluent interface with method chaining
  • 🔤 Unicode Support: Handles special characters and Unicode labels
  • 📐 Configurable Layout: Control graph direction (LR, TB, BT, RL)

#Installation

moon add bobzhang/dot

#Quick Start

#Basic Graph (DOT Format)

///|
test "dot: quickstart" {
let builder = @flowgraph.DotBuilder::new()
builder
..add_node(id="a", label="Start")
..add_node(id="b", label="End")
.add_edge(src="a", dst="b", label="→")
inspect(
builder.to_dot(),
content=(
#|digraph Marshal {
#| rankdir=LR;
#| node [shape=box, style=rounded];
#|
#| a [label="Start"];
#| b [label="End"];
#|
#| a -> b [label="→"];
#|}
#|
),
)
}

#Basic Graph (Mermaid Format)

///|
test "quickstart-mermaid" (it : @test.Test) {
let builder = @flowgraph.DotBuilder::new()
builder
..add_node(id="a", label="Start")
..add_node(id="b", label="End")
.add_edge(src="a", dst="b", label="→")
let got = builder.to_mermaid()
inspect(
got,
content=(
#|flowchart LR
#|%% graph: Marshal
#|
#| a["Start"]
#| b["End"]
#|
#| a -->|→| b
#|
),
)
it.write(got)
it.snapshot(filename="\{it.name()}.mmd")
}

#Advanced Usage

#Custom Graph Direction and Styling

Control graph direction and add custom styling to nodes and edges:

///|
test "styled graph example" {
let builder = @flowgraph.DotBuilder::with_config(
graph_name="Workflow",
rankdir="TB", // Top to Bottom
)
builder
..add_node(id="start", label="Start", shape="circle", color="green")
..add_node(id="process", label="Process", shape="box", color="lightblue")
..add_node(id="end", label="End", shape="doublecircle", color="red")
..add_edge(
src="start",
dst="process",
label="begin",
style="solid",
color="black",
)
.add_edge(
src="process",
dst="end",
label="complete",
style="dashed",
color="blue",
)
}

Supported directions: LR (left-right), TB (top-bottom), BT (bottom-top), RL (right-left)

Node shapes: box, circle, ellipse, diamond, doublecircle, and more

Edge styles: solid, dashed, dotted, bold

#Bidirectional Edges

///|
test "bidirectional example" {
let builder = @flowgraph.DotBuilder::new()
builder
..add_node(id="client", label="Client")
..add_node(id="server", label="Server")
.add_bidirectional_edge(node1="client", node2="server", label="HTTP")
}

#Subgraphs (Clusters)

Group related nodes into visual clusters:

///|
test "subgraph example" {
let builder = @flowgraph.DotBuilder::new()
builder
..add_node(id="web1", label="Web Server 1")
..add_node(id="web2", label="Web Server 2")
..add_node(id="app1", label="App Server 1")
..add_node(id="app2", label="App Server 2")
..add_subgraph(name="frontend", label="Frontend Tier", nodes=["web1", "web2"])
..add_subgraph(name="backend", label="Backend Tier", nodes=["app1", "app2"])
..add_edge(src="web1", dst="app1", label="")
.add_edge(src="web2", dst="app2", label="")
}

#Unique Node IDs

Generate unique node identifiers automatically:

///|
test "auto-generated ids" {
let builder = @flowgraph.DotBuilder::new()
let id1 = builder.fresh_id() // "n0"
let id2 = builder.fresh_id() // "n1"
let id3 = builder.fresh_id() // "n2"
builder
..add_node(id=id1, label="First")
..add_node(id=id2, label="Second")
.add_node(id=id3, label="Third")
}

#API Reference

#DotBuilder

#Construction

  • DotBuilder::new() -> DotBuilder - Create a new builder with default settings
  • DotBuilder::with_config(graph_name~, rankdir~) -> DotBuilder - Create with custom configuration

#Node Methods

  • add_node(id~, label~, shape?, color?) - Add a node (optionally with custom styling)
  • fresh_id() -> String - Generate a unique node ID

#Edge Methods

  • add_edge(src~, dst~, label~, style?, color?) - Add a directed edge (optionally with custom styling)
  • add_bidirectional_edge(node1~, node2~, label~) - Add a bidirectional edge

#Subgraph Methods

  • add_subgraph(name~, label~, nodes~) - Add a subgraph cluster

#Output Methods

  • to_dot() -> String - Generate Graphviz DOT format
  • to_mermaid() -> String - Generate Mermaid flowchart format

#Configuration Methods

  • set_node_shape(shape) - Set default node shape
  • set_node_style(style) - Set default node style

#Use Cases

  • Dependency Graphs: Visualize package or module dependencies
  • State Machines: Represent state transitions
  • Flowcharts: Create process flow diagrams
  • Network Topology: Map network connections
  • Data Flow Diagrams: Show data transformation pipelines
  • Call Graphs: Visualize function call relationships
  • Architecture Diagrams: Document system architecture

#Examples

See the test files for more examples:

#License

Apache-2.0

#
DotBuilder

type DotBuilder

#
DotBuilder::add_bidirectional_edge

fn DotBuilder::add_bidirectional_edge(self : DotBuilder, node1~ : String, node2~ : String, label~ : String) -> Unit

Add a bidirectional edge (two arrows)

#
DotBuilder::add_edge

fn DotBuilder::add_edge(self : DotBuilder, src~ : String, dst~ : String, label~ : String, style? : String, color? : String) -> Unit

Add an edge from src to dst with optional label

#
DotBuilder::add_node

fn DotBuilder::add_node(self : DotBuilder, id~ : String, label~ : String, shape? : String, color? : String) -> Unit

Add a node with a label

#
DotBuilder::add_subgraph

fn DotBuilder::add_subgraph(self : DotBuilder, name~ : String, label~ : String, nodes~ : Array[String]) -> Unit

Add a subgraph (cluster) to group nodes

#
DotBuilder::fresh_id

fn DotBuilder::fresh_id(self : DotBuilder) -> String

Generate a unique node ID

#
DotBuilder::new

fn DotBuilder::new() -> DotBuilder

#
DotBuilder::set_node_shape

fn DotBuilder::set_node_shape(self : DotBuilder, shape : String) -> Unit

Set the default node shape Common shapes: "box", "circle", "ellipse", "diamond", "rectangle", "square", "triangle", "pentagon", "hexagon", "octagon", "doublecircle", "plaintext"

#
DotBuilder::set_node_style

fn DotBuilder::set_node_style(self : DotBuilder, style : String) -> Unit

Set the default node style

#
DotBuilder::to_dot

fn DotBuilder::to_dot(self : DotBuilder) -> String

Generate the complete DOT graph string

#
DotBuilder::to_mermaid

fn DotBuilder::to_mermaid(self : DotBuilder) -> String

Generate Mermaid flowchart graph string (useful for Markdown rendering)

#
DotBuilder::with_config

fn DotBuilder::with_config(graph_name~ : String, rankdir~ : String) -> DotBuilder

Create a new DotBuilder with custom graph name and direction rankdir can be: "TB" (top-bottom), "LR" (left-right), "BT" (bottom-top), "RL" (right-left)

Source Files