dabd531670421b4ad16a8ccd186965d18f81d46c
[worg.git] / org-tutorials / org-dot-diagrams.org
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
11
12 [[file:../index.org][{Back to Worg's index}]]
13
14 * Introduction
15
16 This tutorial summarizes one specific method which defines (process)
17 elements within tables in order to generate a simple work flow
18 diagram.
19
20 We first demonstrate a compact version for one-time usage (tables and
21 code snippet). Then, we show how to re-use this method for multiple
22 sets of tables in an efficient way.
23
24 * Defining the Process Elements
25
26 We are using tables to define our work-flow. The first table holds
27 the node identifiers (internal names), node labels, optional shape
28 definitions, and optional fill colors:
29
30 : #+name: example-node-table
31 : | *node*     | *label*        | *shape* | *fillcolor* |
32 : |------------+----------------+---------+-------------|
33 : | S_start    | start          | ellipse | green       |
34 : | S_fill     | fill form      |         |             |
35 : | S_send     | send form      |         |             |
36 : | S_complete | form complete? | diamond | yellow      |
37 : | S_do       | do task        |         | red         |
38 : | S_end      | end            | ellipse |             |
39
40 The second table contains information about connections between nodes
41 (using node identifiers) and optional labels:
42
43 : #+name: example-graph
44 : | from       | to         | label |
45 : |------------+------------+-------|
46 : | S_start    | S_fill     |       |
47 : | S_fill     | S_send     |       |
48 : | S_send     | S_complete |       |
49 : | S_complete | S_fill     | N     |
50 : | S_complete | S_do       | Y     |
51 : | S_do       | S_end      |       |
52
53 * ELISP code snippet for generating the diagram using dot
54
55 In the next step, we are going to generate the diagram file (in PNG
56 format) using [[https://code.google.com/p/pydot/][dot]]. You should make sure that you have a working dot
57 installation and probably tried out [[http://orgmode.org/worg/org-contrib/babel/languages/ob-doc-dot.html][a tutorial about using dot within
58 Org-mode]].
59
60 The author of this code is [[http://article.gmane.org/gmane.emacs.orgmode/73854][Rick Frankel]]. It is written in Emacs LISP
61 which directly executes the generated dot script:
62
63 : #+name: graph-from-tables
64 : #+HEADER: :var nodes=example-node-table graph=example-graph
65 : #+BEGIN_SRC emacs-lisp :file ~/example-diagram.png :colnames yes :exports results
66 :     (org-babel-execute:dot
67 :      (concat
68 :           "digraph {\n"
69 :           "//rankdir=LR;\n" ;; remove comment characters '//' for horizontal layout; add for vertical layout
70 :           (mapconcat
71 :            (lambda (x)
72 :              (format "%s [label=\"%s\" shape=%s style=\"filled\" fillcolor=\"%s\"]"
73 :                              (car x)
74 :                              (nth 1 x)
75 :                              (if (string= "" (nth 2 x)) "box" (nth 2 x))
76 :                              (if (string= "" (nth 3 x)) "none" (nth 3 x))
77 :                              )) nodes "\n")
78 :           "\n"
79 :           (mapconcat
80 :            (lambda (x)
81 :              (format "%s -> %s [taillabel=\"%s\"]"
82 :                              (car x) (nth 1 x) (nth 2 x))) graph "\n")
83 :           "}\n") params)
84 : #+END_SRC
85
86 As you can see, the node table and the graph table are being defined
87 in the header using the ~:var~ argument for babel. The resulting PNG
88 file name is defined as ~:file~ argument below.
89
90 By executing the babel script (e.g., ~C-c C-c~) the PNG file gets
91 created.
92
93 You can remove the dot-comment (~//~) in front of ~rankdir~ in order
94 to switch to a horizontal layout of the diagram.
95
96 [[file:../images/org-plot/example-diagram.png]]
97
98 * Re-using the code snippet with call-statements
99
100 When you are generating multiple diagrams within one single Org-mode
101 file, you might want to re-use the ELISP code for all of your
102 diagrams. However, you want to use different definition tables and a
103 different output file name. The ELISP code is the same for all of
104 them.
105
106 This can be achieved by using [[http://orgmode.org/manual/Evaluating-code-blocks.html][the ~call~ command]]. In this example, we
107 are re-using the ELISP code from above with two newly created tables
108 of the very important process 42 (please notice also the differences
109 in the ~name~ arguments of the tables):
110
111 : #+name: process42-node-table
112 : | *node*  | *label*             | *shape* | *fillcolor* |
113 : |---------+---------------------+---------+-------------|
114 : | mystart | start               | ellipse | yellow      |
115 : | mywatch | is Bob here?        | diamond |             |
116 : | mywait  | wait for 10 minutes |         | red         |
117 : | mytalk  | talk to Bob         |         |             |
118 : | myend   | end                 | ellipse | green       |
119
120 The second table contains information about connections between nodes
121 (using node identifiers) and optional labels:
122
123 : #+name: process42-graph
124 : | from    | to      | label |
125 : |---------+---------+-------|
126 : | mystart | mywatch |       |
127 : | mywatch | mywait  | N     |
128 : | mywait  | mywatch |       |
129 : | mywatch | mytalk  | Y     |
130 : | mytalk  | myend   |       |
131
132 The ~call~ statement consists of the name of the code
133 (~graph-from-tables~), an insider header argument for the new file
134 name, and arguments which defines the input tables. For [[http://article.gmane.org/gmane.emacs.orgmode/73972][technical
135 reasons]], we have to add table ranges as well (~[2:-1]~):
136
137 : #+call: graph-from-tables[:file ~/diagram-process42.png](nodes=process42-node-table[2:-1],graph=process42-graph[2:-1]) :results file
138
139 By invoking the call statement (place the cursor on it and use the
140 usual ~C-c C-c~ command to execute), you generate the diagram for our
141 process 42:
142
143 [[file:../images/org-plot/diagram-process42.png]]
144
145 That's it.
146
147 Pretty handy for generating (simple) process diagrams.
148