gnu-application.org: Remove email addresses
[worg.git] / org-tutorials / org-dot-diagrams.org
blob9c8078af0918e7c6ae718f488c4b0bdf0019d5b0
1 #+OPTIONS:    H:3 num:nil toc:t \n:nil ::t |:t ^:t -:t f:t *:t tex:t d:(HIDE) tags:not-in-toc
2 #+STARTUP:    align fold nodlcheck hidestars oddeven lognotestate
3 #+SEQ_TODO:   TODO(t) INPROGRESS(i) WAITING(w@) | DONE(d) CANCELED(c@)
4 #+TAGS:       Write(w) Update(u) Fix(f) Check(c)
5 #+TITLE:      Org tutorial on generating simple process diagrams using dot and tables
6 #+AUTHOR:     Karl Voit
7 #+EMAIL:      tools AT Karl MINUS Voit DOT at
8 #+LANGUAGE:   en
9 #+PRIORITIES: A C B
10 #+CATEGORY:   org-tutorial
12 [[file:../index.org][{Worg's index}]] > [[file:index.org][{Org-tutorials}]]
14 * Introduction
16 This tutorial summarizes one specific method which defines (process)
17 elements within tables in order to generate a simple work flow
18 diagram using [[https://code.google.com/p/pydot/][dot]].
20 An alternative way of accomplishing the task would be using [[http://plantuml.com/][PlantUML]]
21 (a wrapper to [[http://www.graphviz.org/][Graphviz]]) which can be [[http://plantuml.com/emacs][integrated to Emacs]] as well.
23 We first demonstrate a compact version for one-time usage (tables and
24 code snippet). Then, we show how to re-use this method for multiple
25 sets of tables in an efficient way.
27 * Defining the Process Elements
29 We are using tables to define our work-flow. The first table holds
30 the node identifiers (internal names), node labels, optional shape
31 definitions, and optional fill colors:
33 : #+name: example-node-table
34 : | *node*     | *label*        | *shape* | *fillcolor* |
35 : |------------+----------------+---------+-------------|
36 : | S_start    | start          | ellipse | green       |
37 : | S_fill     | fill form      |         |             |
38 : | S_send     | send form      |         |             |
39 : | S_complete | form complete? | diamond | yellow      |
40 : | S_do       | do task        |         | red         |
41 : | S_end      | end            | ellipse |             |
43 The second table contains information about connections between nodes
44 (using node identifiers) and optional labels:
46 : #+name: example-graph
47 : | from       | to         | label |
48 : |------------+------------+-------|
49 : | S_start    | S_fill     |       |
50 : | S_fill     | S_send     |       |
51 : | S_send     | S_complete |       |
52 : | S_complete | S_fill     | N     |
53 : | S_complete | S_do       | Y     |
54 : | S_do       | S_end      |       |
56 * ELISP code snippet for generating the diagram using dot
58 In the next step, we are going to generate the diagram file (in PNG
59 format) using [[https://code.google.com/p/pydot/][dot]]. You should make sure that you have a working dot
60 installation and probably tried out [[https://orgmode.org/worg/org-contrib/babel/languages/ob-doc-dot.html][a tutorial about using dot within
61 Org-mode]].
63 The author of this code is [[https://orgmode.org/list/4c174089656ce0b08177f464325c4bf9@mail.rickster.com][Rick Frankel]]. It is written in Emacs LISP
64 which directly executes the generated dot script:
66 : #+name: graph-from-tables
67 : #+HEADER: :var nodes=example-node-table graph=example-graph
68 : #+BEGIN_SRC emacs-lisp :file ~/example-diagram.png :colnames yes :exports results
69 :     (org-babel-execute:dot
70 :      (concat
71 :           "digraph {\n"
72 :           "//rankdir=LR;\n" ;; remove comment characters '//' for horizontal layout; add for vertical layout
73 :           (mapconcat
74 :            (lambda (x)
75 :              (format "%s [label=\"%s\" shape=%s style=\"filled\" fillcolor=\"%s\"]"
76 :                              (car x)
77 :                              (nth 1 x)
78 :                              (if (string= "" (nth 2 x)) "box" (nth 2 x))
79 :                              (if (string= "" (nth 3 x)) "none" (nth 3 x))
80 :                              )) nodes "\n")
81 :           "\n"
82 :           (mapconcat
83 :            (lambda (x)
84 :              (format "%s -> %s [taillabel=\"%s\"]"
85 :                              (car x) (nth 1 x) (nth 2 x))) graph "\n")
86 :           "}\n") params)
87 : #+END_SRC
89 As you can see, the node table and the graph table are being defined
90 in the header using the ~:var~ argument for babel. The resulting PNG
91 file name is defined as ~:file~ argument below.
93 By executing the babel script (e.g., ~C-c C-c~) the PNG file gets
94 created.
96 You can remove the dot-comment (~//~) in front of ~rankdir~ in order
97 to switch to a horizontal layout of the diagram.
99 [[file:../images/org-dot/example-diagram.png]]
101 * Re-using the code snippet with call-statements
103 When you are generating multiple diagrams within one single Org-mode
104 file, you might want to re-use the ELISP code for all of your
105 diagrams. However, you want to use different definition tables and a
106 different output file name. The ELISP code is the same for all of
107 them.
109 This can be achieved by using [[https://orgmode.org/manual/Evaluating-code-blocks.html][the ~call~ command]]. In this example, we
110 are re-using the ELISP code from above with two newly created tables
111 of the very important process 42 (please notice also the differences
112 in the ~name~ arguments of the tables):
114 : #+name: process42-node-table
115 : | *node*  | *label*             | *shape* | *fillcolor* |
116 : |---------+---------------------+---------+-------------|
117 : | mystart | start               | ellipse | yellow      |
118 : | mywatch | is Bob here?        | diamond |             |
119 : | mywait  | wait for 10 minutes |         | red         |
120 : | mytalk  | talk to Bob         |         |             |
121 : | myend   | end                 | ellipse | green       |
123 The second table contains information about connections between nodes
124 (using node identifiers) and optional labels:
126 : #+name: process42-graph
127 : | from    | to      | label |
128 : |---------+---------+-------|
129 : | mystart | mywatch |       |
130 : | mywatch | mywait  | N     |
131 : | mywait  | mywatch |       |
132 : | mywatch | mytalk  | Y     |
133 : | mytalk  | myend   |       |
135 The ~call~ statement consists of the name of the code
136 (~graph-from-tables~), an insider header argument for the new file
137 name, and arguments which defines the input tables. For [[https://orgmode.org/list/5e6cbdf1d1de558009527836766630b7@mail.rickster.com][technical
138 reasons]], we have to add table ranges as well (~[2:-1]~):
140 : #+call: graph-from-tables[:file ~/diagram-process42.png](nodes=process42-node-table[2:-1],graph=process42-graph[2:-1]) :results file
142 By invoking the call statement (place the cursor on it and use the
143 usual ~C-c C-c~ command to execute), you generate the diagram for our
144 process 42:
146 [[file:../images/org-dot/diagram-process42.png]]
148 That's it.
150 Pretty handy for generating (simple) process diagrams.