Racket Graphviz Integration
1 Basic concepts
2 API
2.1 Defining Subgraphs
make-digraph
make-vertex
2.2 Conversion to Pict
digraph->pict
dot->pict
2.3 Structs
digraph
vertex
edge
subgraph
3 Examples
3.1 Android Activity Lifecycle
3.2 Turnstile State Machine
7.7

Racket Graphviz Integration

Hadi Moshayedi <hadi@moshayedi.net>

The goal of this library is to make composition of pict and graphviz diagrams possible.

The composition is made possible through:

1 Basic concepts

This package helps with visualizing directed graphs, or digraphs for short. Each digraph consists of a set of vertexes and edges. For example the digraph in figure 1 consists of three vertexes and four edges.

image

Figure 1: An example digraph

There can be multiple edges between two vertexes, as shown in figure 2.

image

Figure 2: multiple edges between two nodes

Furthermore, a set of vertexes can be grouped in a subgraph, as show in figure 3.

image

Figure 3: Subgraphs

2 API

2.1 Defining Subgraphs

procedure

(make-digraph definitions #:ortho ortho)  digraph?

  definitions : list?
  ortho : boolean?
Creates a digraph. "definitions" is a list of vertex, edge, or subgraph definitions.

For example, figure 1 can be defined as the following, where vertexes and edges are defined using strings.

(make-digraph
 `("v0" "v1" "v2" "v0 -> v0" "v0 -> v1" "v1 -> v2" "v2 -> v0"))

figure 3 can be defined as the following:

(make-digraph
  `((subgraph "Coordinator"
              ("Parser -> Planner -> Executor"))
    (subgraph "Worker1"
              ("QueryProcessor1 -> DataPartition1"))
    (subgraph "Worker2"
              ("QueryProcessor2 -> DataPartition2"))
    "Executor -> QueryProcessor1" "QueryProcessor1 -> Executor"
    "Executor -> QueryProcessor2" "QueryProcessor2 -> Executor"))

procedure

(make-vertex label #:shape shape)  vertex?

  label : string?
  shape : (or/c pict? string?)

2.2 Conversion to Pict

procedure

(digraph->pict digraph)  pict?

  digraph : digraph?
Converts the given digraph to a pict.

procedure

(dot->pict definition)  pict?

  definition : string?
Converts the given digraph definition in dot language to a pict. For example, following code produces figure 4.

(dot->pict
"digraph {
 a -> b -> c;
 }")

image

Figure 4: @dot->pict example

2.3 Structs

struct

(struct digraph (objects ortho))

  objects : list?
  ortho : boolean?

struct

(struct vertex (name label shape attrs))

  name : string?
  label : string?
  shape : (or/c pict? string?)
  attrs : hash?

struct

(struct edge (nodes attrs))

  nodes : list?
  attrs : hash?

struct

(struct subgraph (label objects attrs))

  label : string?
  objects : list?
  attrs : hash?

3 Examples

3.1 Android Activity Lifecycle

(define (shadowed-box w h color)
  (inset (shadow (filled-rounded-rectangle w h 5
                                           #:color color
                                           #:border-color "black")
                 15 -3 3) 10))
 
(define start-pict (shadowed-box 120 40 "LightSkyBlue"))
(define node-pict (shadowed-box 160 40 "Gainsboro"))
(define running-pict (shadowed-box 150 40 "Aquamarine"))
(define terminal-pict (shadowed-box 150 40 "Salmon"))
 
(define d
  (make-digraph
   `(("Start" #:label "Activity Starts" #:shape ,start-pict)
     ("onCreate" #:label "onCreate()" #:shape ,node-pict)
     ("onStart" #:label "onStart()" #:shape ,node-pict)
     ("onResume" #:label "onResume()" #:shape ,node-pict)
     ("Running" #:label "Activity Running" #:shape ,running-pict)
     ("onPause" #:label "onPause()" #:shape ,node-pict)
     ("onStop" #:label "onStop()" #:shape ,node-pict)
     ("onDestroy" #:label "onDestroy()" #:shape ,terminal-pict)
     ("onRestart" #:label "onRestart()" #:shape ,node-pict)
     ("killed" #:label "Process is Killed" #:shape ,terminal-pict)
     (edge ("Start" "onCreate" "onStart" "onResume" "Running") #:weight "7")
     (edge ("Running" "onPause") #:label "Another activity activates" #:weight "7")
     (edge ("onPause" "onStop") #:label "Activity is no longer visible" #:weight "7")
     (edge ("onStop" "onDestroy") #:weight "7")
     (edge ("onPause" "onResume"))
     (edge ("onStop" "onRestart") #:label "Activity comes to foreground")
     (edge ("onRestart" "onStart"))
     (edge ("onStop" "killed"))
     (edge ("killed" "onCreate"))
     (same-rank "killed" "Running" "onRestart")) #:ortho #t))
 
(scale (inset (digraph->pict d) 10) 0.8)

image

Figure 5: Android Activity Lifecycle

3.2 Turnstile State Machine

(make-digraph
   `(("Locked" #:shape "circle" #:width "1.2")
     ("Unlocked" #:shape "circle" #:width "1.2")
     (edge ("Locked:n" "Locked:n") #:label "Push")
     (edge ("Locked" "Unlocked") #:label "Coin")
     (edge ("Unlocked" "Locked") #:label "Push")
     (edge ("Unlocked:n" "Unlocked:n") #:label "Coin")
     (same-rank "Locked" "Unlocked")))

image