flowgraph

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

    Download zip
    Author
    Version
    0.1.2
    License
    Apache-2.0
    Last updated
    5 days ago
    Downloads
    52

    #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="quickstart-mermaid.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