]> gitweb.factorcode.org Git - factor.git/blob - extra/graphviz/graphviz-docs.factor
Update Windows for word renames, fix lint errors
[factor.git] / extra / graphviz / graphviz-docs.factor
1 ! Copyright (C) 2011 Alex Vondrak.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors arrays graphviz.attributes help.markup
4 help.syntax kernel present sequences strings ;
5 IN: graphviz
6
7 { subgraph <subgraph> <anon> <cluster> } related-words
8 { graph <graph> <digraph> <strict-graph> <strict-digraph> } related-words
9 { node <node> add-node add-nodes } related-words
10 { edge <edge> add-edge add-path } related-words
11 { add add-node add-edge add-nodes add-path } related-words
12
13 HELP: <anon>
14 { $values
15         { "subgraph" subgraph }
16 }
17 { $description
18 "Constructs an empty, anonymous " { $link subgraph } " by automatically generating a (somewhat) unique " { $slot "id" } "."
19 }
20 { $notes
21 "Each " { $slot "id" } " has the form " { $snippet "\"_anonymous_n\"" } ", where " { $snippet "n" } " is a counter incremented by 1 each time an anonymous " { $slot "id" } " is generated (e.g., each time you call " { $link <anon> } " or " { $link <graph> } "). This is also how the Graphviz DOT parser internally handles anonymous graphs and subgraphs."
22 $nl
23 "Thus, while it's possible to manually create a " { $link subgraph } " whose " { $slot "id" } " conflicts with an " { $link <anon> } "'s , in practice it's unlikely to happen by accident."
24 }
25 { $examples
26     "Each " { $link <anon> } " will generate a " { $link subgraph } " with a new " { $slot "id" } ", such as:"
27     { $unchecked-example
28       "USING: graphviz prettyprint ;"
29       "<anon> . <anon> ."
30       "T{ subgraph { id \"_anonymous_5\" } { statements V{ } } }\nT{ subgraph { id \"_anonymous_6\" } { statements V{ } } }"
31     }
32     $nl
33     "More generally, the following should always be the case:"
34     { $example
35       "USING: accessors graphviz kernel prettyprint ;"
36       "<anon> <anon> [ id>> ] bi@ = ."
37       "f"
38     }
39 }
40 ;
41
42 HELP: <cluster>
43 { $values
44     { "id" object }
45     { "subgraph" subgraph }
46 }
47 { $description
48 "Constructs a cluster, which is a " { $link subgraph } " whose " { $slot "id" } " begins with the word " { $emphasis "\"cluster\"" } "."
49 $nl
50 { $snippet "id" } " must be an object supported by the " { $link present } " word. The string " { $snippet "\"cluster_\"" } " is automatically prefixed to the " { $slot "id" } " of the resulting " { $link subgraph } "."
51 }
52 { $notes
53 "Clusters are just a syntactic convention. Not all Graphviz layout engines treat clusters any differently from regular subgraphs. See the Graphviz documentation (" { $url "http://graphviz.org/Documentation.php" } ") for more information."
54 }
55 { $examples
56   { $example
57     "USING: graphviz prettyprint ;"
58     "\"foo\" <cluster> ."
59     "T{ subgraph { id \"cluster_foo\" } { statements V{ } } }"
60   }
61   $nl
62   { $example
63     "USING: accessors graphviz prettyprint ;"
64     "0 <cluster> id>> ."
65     "\"cluster_0\""
66   }
67 }
68 ;
69
70 HELP: <digraph>
71 { $values
72         { "graph" graph }
73 }
74 { $description
75 "Constructs an empty, non-strict, directed " { $link graph } "."
76 }
77 { $notes
78 "Because it's rare for " { $link graph } " " { $slot "id" } "s to be meaningful or useful, " { $link <digraph> } " automatically generates one, just as in "  { $link <anon> } "."
79
80 $nl
81
82 "If you want, you can still give the resulting " { $link graph } " a specific " { $slot "id" } " using standard words like " { $link >>id } ". For example,"
83 { $code "<digraph> \"G\" >>id" }
84 }
85 { $examples
86     { $example "USING: graphviz prettyprint ;" "<digraph> graph? ." "t" }
87     $nl
88     { $example "USING: accessors graphviz prettyprint sequences ;" "<digraph> statements>> empty? ." "t" }
89     $nl
90     { $example "USING: accessors graphviz prettyprint ;" "<digraph> strict?>> ." "f" }
91     $nl
92     { $example "USING: accessors graphviz prettyprint ;" "<digraph> directed?>> ." "t" }
93 }
94 ;
95
96 HELP: <edge>
97 { $values
98     { "tail" object }
99     { "head" object }
100     { "edge" edge }
101 }
102 { $description
103 "Constructs an " { $link edge } " with the given " { $slot "tail" } " and " { $slot "head" } ", each of which must be either:"
104 { $list
105   { "an " { $link array } " of objects supported by the " { $link present } " word, which is treated as an anonymous " { $link subgraph } " of " { $link node } "s with corresponding " { $slot "id" } "s;" }
106   { "a " { $link subgraph } "; or" }
107   { "any object supported by the " { $link present } " word, which is taken to be the " { $slot "id" } " of a " { $link node } "." }
108 }
109 }
110 { $notes
111 "There is more detailed information about how different " { $slot "tail" } " and " { $slot "head" } " types interact in the documentation for " { $link edge } "."
112 }
113 { $examples
114   { $example
115     "USING: accessors graphviz kernel prettyprint ;"
116     "1 \"one\" <edge>"
117     "[ tail>> . ] [ head>> . ] bi"
118     "\"1\"\n\"one\""
119   }
120   $nl
121   { $example
122     "USING: accessors classes graphviz kernel prettyprint strings ;"
123     "1 { 2 3 4 } <edge>"
124     "[ tail>> class-of . ] [ head>> class-of . ] bi"
125     "string\nsubgraph"
126   }
127   $nl
128   { $example
129     "USING: accessors graphviz kernel prettyprint ;"
130     "<anon> <anon> <edge>"
131     "[ tail>> id>> ] [ head>> id>> ] bi = ."
132     "f"
133   }
134 }
135 ;
136
137 HELP: <graph>
138 { $values
139         { "graph" graph }
140 }
141 { $description
142 "Constructs an empty, non-strict, undirected " { $link graph } "."
143 }
144 { $notes
145 "Because it's rare for " { $link graph } " " { $slot "id" } "s to be meaningful or useful, " { $link <graph> } " automatically generates one, just as in "  { $link <anon> } "."
146
147 $nl
148
149 "If you want, you can still give the resulting " { $link graph } " a specific " { $slot "id" } " using standard words like " { $link >>id } ". For example,"
150 { $code "<graph> \"G\" >>id" }
151 }
152 { $examples
153     { $example "USING: graphviz prettyprint ;" "<graph> graph? ." "t" }
154     $nl
155     { $example "USING: accessors graphviz prettyprint sequences ;" "<graph> statements>> empty? ." "t" }
156     $nl
157     { $example "USING: accessors graphviz prettyprint ;" "<graph> strict?>> ." "f" }
158     $nl
159     { $example "USING: accessors graphviz prettyprint ;" "<graph> directed?>> ." "f" }
160 }
161 ;
162
163 HELP: <node>
164 { $values
165     { "id" object }
166     { "node" node }
167 }
168 { $description
169 "Constructs a " { $link node } " with the given " { $slot "id" } ", which must be an object supported by the " { $link present } " word."
170 }
171 { $examples
172   { $example
173     "USING: graphviz prettyprint ;"
174     "\"foo\" <node> ."
175     "T{ node { id \"foo\" } }"
176   }
177   $nl
178   { $example
179     "USING: accessors graphviz prettyprint ;"
180     "0 <node> id>> ."
181     "\"0\""
182   }
183 }
184 ;
185
186 HELP: <strict-digraph>
187 { $values
188         { "graph" graph }
189 }
190 { $description
191 "Constructs an empty, strict, directed " { $link graph } "."
192 }
193 { $notes
194 "Because it's rare for " { $link graph } " " { $slot "id" } "s to be meaningful or useful, " { $link <strict-digraph> } " automatically generates one, just as in "  { $link <anon> } "."
195
196 $nl
197
198 "If you want, you can still give the resulting " { $link graph } " a specific " { $slot "id" } " using standard words like " { $link >>id } ". For example,"
199 { $code "<strict-digraph> \"G\" >>id" }
200
201 $nl
202
203 "In " { $emphasis "strict" } " " { $link graph } "s, there is at most one "  { $link edge } " between any two " { $link node } "s, so duplicates are ignored while rendering. See " { $vocab-link "graphviz.render" } " for more information."
204 }
205 { $examples
206     { $example "USING: graphviz prettyprint ;" "<strict-digraph> graph? ." "t" }
207     $nl
208     { $example "USING: accessors graphviz prettyprint sequences ;" "<strict-digraph> statements>> empty? ." "t" }
209     $nl
210     { $example "USING: accessors graphviz prettyprint ;" "<strict-digraph> strict?>> ." "t" }
211     $nl
212     { $example "USING: accessors graphviz prettyprint ;" "<strict-digraph> directed?>> ." "t" }
213 }
214 ;
215
216 HELP: <strict-graph>
217 { $values
218         { "graph" graph }
219 }
220 { $description
221 "Constructs an empty, strict, undirected " { $link graph } "."
222 }
223 { $notes
224 "Because it's rare for " { $link graph } " " { $slot "id" } "s to be meaningful or useful, " { $link <strict-graph> } " automatically generates one, just as in "  { $link <anon> } "."
225
226 $nl
227
228 "If you want, you can still give the resulting " { $link graph } " a specific " { $slot "id" } " using standard words like " { $link >>id } ". For example,"
229 { $code "<strict-digraph> \"G\" >>id" }
230
231 $nl
232
233 "In " { $emphasis "strict" } " " { $link graph } "s, there is at most one "  { $link edge } " between any two " { $link node } "s, so duplicates are ignored while rendering. See " { $vocab-link "graphviz.render" } " for more information."
234 }
235 { $examples
236     { $example "USING: graphviz prettyprint ;" "<strict-graph> graph? ." "t" }
237     $nl
238     { $example "USING: accessors graphviz prettyprint sequences ;" "<strict-graph> statements>> empty? ." "t" }
239     $nl
240     { $example "USING: accessors graphviz prettyprint ;" "<strict-graph> strict?>> ." "t" }
241     $nl
242     { $example "USING: accessors graphviz prettyprint ;" "<strict-graph> directed?>> ." "f" }
243 }
244 ;
245
246 HELP: <subgraph>
247 { $values
248     { "id" object }
249     { "subgraph" subgraph }
250 }
251 { $description
252 "Constructs an empty " { $link subgraph } " with the given " { $slot "id" } ", which must be an object supported by the " { $link present } " word."
253 }
254 { $notes
255 "The empty string, " { $snippet "\"\"" } ", counts as a distinct " { $slot "id" } ". To create an anonymous " { $link subgraph } ", use " { $link <anon> } "."
256 }
257 { $examples
258   { $example
259     "USING: graphviz prettyprint ;"
260     "\"subg\" <subgraph> subgraph? ."
261     "t"
262   }
263   $nl
264   { $example
265     "USING: accessors graphviz prettyprint ;"
266     "3.14 <subgraph> id>> ."
267     "\"3.14\""
268   }
269   $nl
270   { $example
271     "USING: accessors graphviz prettyprint sequences ;"
272     "\"foo\" <subgraph> statements>> empty? ."
273     "t"
274   }
275 }
276 ;
277
278 HELP: add
279 { $values
280     { "graph" { $or graph subgraph } }
281     { "statement" object }
282     { "graph'" { $or graph subgraph } }
283 }
284 { $description
285 "Adds an arbitrary object to the " { $slot "statements" } " slot of a " { $link graph } " or " { $link subgraph } ", leaving the updated tuple on the stack. This is the most basic way to construct a " { $link graph } "."
286 }
287 { $notes ! $warning
288   { $link add } " does not check the type of " { $snippet "statement" } ". You should ensure that " { $link graph } "s and " { $link subgraph } "s only contain instances of:"
289   { $list
290     { $link subgraph }
291     { $link node }
292     { $link edge }
293     { $link graph-attributes }
294     { $link node-attributes }
295     { $link edge-attributes }
296   }
297 }
298 { $examples
299   { $example
300     "USING: accessors graphviz prettyprint sequences ;"
301     "<graph>"
302     "    1 <node> add"
303     "statements>> [ id>> . ] each"
304     "\"1\""
305   }
306   $nl
307   { $example
308     "USING: accessors graphviz prettyprint sequences ;"
309     "<graph>"
310     "    1 <node> add"
311     "    2 <node> add"
312     "statements>> [ id>> . ] each"
313     "\"1\"\n\"2\""
314   }
315   $nl
316   { $example
317     "USING: accessors classes graphviz prettyprint sequences ;"
318     "<graph>"
319     "    1 <node> add"
320     "    2 <node> add"
321     "    1 2 <edge> add"
322     "statements>> [ class-of . ] each"
323     "node\nnode\nedge"
324   }
325 }
326 ;
327
328 HELP: add-edge
329 { $values
330     { "graph" { $or graph subgraph } }
331     { "tail" object }
332     { "head" object }
333     { "graph'" { $or graph subgraph } }
334 }
335 { $description
336 "Adds an " { $link edge } " in " { $snippet "graph" } " from " { $slot "tail" } " to " { $slot "head" } ". That is,"
337 { $code "X Y add-edge" }
338 "is shorthand for"
339 { $code "X Y <edge> add" }
340 }
341 { $examples
342   { $example
343     "USING: accessors graphviz io kernel sequences ;"
344     "<graph>"
345     "    1 2 add-edge"
346     "    3 4 add-edge"
347     "    1 2 add-edge ! duplicate"
348     "    5 6 add-edge"
349     "statements>> [ dup tail>> write \"--\" write head>> print ] each"
350     "1--2\n3--4\n1--2\n5--6"
351   }
352   $nl
353   { $example
354     "USING: accessors graphviz io kernel math.combinatorics"
355     "sequences ;"
356     "<graph>"
357     "    { \"a\" 2 \"c\" }"
358     "    2 [ first2 add-edge ] each-combination"
359     "statements>> [ dup tail>> write \"--\" write head>> print ] each"
360     "a--2\na--c\n2--c"
361   }
362 }
363 ;
364
365 HELP: add-node
366 { $values
367     { "graph" { $or graph subgraph } }
368     { "id" object }
369     { "graph'" { $or graph subgraph } }
370 }
371 { $description
372 "Adds a " { $link node } " with the given " { $slot "id" } " to " { $snippet "graph" } ". That is,"
373 { $code "X add-node" }
374 "is shorthand for"
375 { $code "X <node> add" }
376 }
377 { $examples
378   { $example
379     "USING: accessors graphviz prettyprint sequences ;"
380     "<graph>"
381     "    \"foo\" add-node"
382     "    \"bar\" add-node"
383     "    \"baz\" add-node"
384     "statements>> [ id>> . ] each"
385     "\"foo\"\n\"bar\"\n\"baz\""
386   }
387   $nl
388   { $example
389     "USING: accessors graphviz prettyprint sequences ;"
390     "<graph>"
391     "    5 iota [ add-node ] each"
392     "statements>> [ id>> . ] each"
393     "\"0\"\n\"1\"\n\"2\"\n\"3\"\n\"4\""
394   }
395 }
396 ;
397
398 HELP: add-nodes
399 { $values
400     { "graph" { $or graph subgraph } }
401     { "nodes" sequence }
402     { "graph'" { $or graph subgraph } }
403 }
404 { $description
405 "Adds a " { $link node } " to " { $snippet "graph" } " for each element in " { $snippet "nodes" } ", which must be a " { $link sequence } " of objects that are supported by the " { $link present } " word. Thus, the following two lines are equivalent:"
406 { $code
407     "{ X Y Z } add-nodes"
408     "X add-node Y add-node Z add-node"
409 }
410 }
411 { $examples
412   { $example
413     "USING: accessors graphviz prettyprint sequences ;"
414     "<graph>"
415     "    { 8 6 7 5 3 0 9 \"Jenny\" \"Jenny\" } add-nodes"
416     "statements>> length ."
417     "9"
418   }
419   $nl
420   { $example
421     "USING: accessors graphviz kernel math prettyprint sequences ;"
422     "<graph>"
423     "    100 [ \"spam\" ] replicate add-nodes"
424     "statements>> [ id>> \"spam\" = ] all? ."
425     "t"
426   }
427 }
428 ;
429
430 HELP: add-path
431 { $values
432     { "graph" { $or graph subgraph } }
433     { "nodes" sequence }
434     { "graph'" { $or graph subgraph } }
435 }
436 { $description
437 "Adds " { $link edge } "s to " { $snippet "graph" } " corresponding to a path through " { $snippet "nodes" } "."
438
439 $nl
440
441 "That is, an " { $link edge } " is added between each object and the one immediately following it in " { $snippet "nodes" } ". Thus, the following two lines are equivalent:"
442 { $code
443     "{ A B C D E } add-path"
444     "A B add-edge B C add-edge C D add-edge D E add-edge"
445 }
446 }
447 { $examples
448   { $example
449     "USING: accessors graphviz prettyprint sequences ;"
450     "<graph>"
451     "    f add-path"
452     "statements>> empty? ."
453     "t"
454   }
455   $nl
456   { $example
457     "USING: accessors graphviz prettyprint sequences ;"
458     "<graph>"
459     "    { \"the cheese stands alone\" } add-path"
460     "statements>> empty? ."
461     "t"
462   }
463   $nl
464   { $example
465     "USING: accessors graphviz io kernel sequences ;"
466     "<digraph>"
467     "  { 1 2 3 4 5 } add-path"
468     "statements>> [ dup tail>> write \" -> \" write head>> print ] each"
469     "1 -> 2\n2 -> 3\n3 -> 4\n4 -> 5"
470   }
471   $nl
472   { $example
473     "USING: accessors graphviz io kernel sequences ;"
474     "<strict-digraph>"
475     "  { \"cycle\" \"cycle\" } add-path"
476     "statements>> [ dup tail>> write \" -> \" write head>> print ] each"
477     "cycle -> cycle"
478   }
479 }
480 ;
481
482 HELP: edge
483 { $class-description
484 "Represents a Graphviz edge. Each " { $link edge } " is defined by its " { $slot "tail" } " slot and its " { $slot "head" } " slot. Each slot must be either"
485 { $list
486     { { $instance string } " representing the " { $slot "id" } " of a " { $link node } " or" }
487     { { $instance subgraph } ", which is a convenient way to represent multiple Graphviz edges." }
488 }
489
490 "In particular, using " { $link subgraph } "s gives us shorthand forms for the following cases:"
491
492 {
493     $table
494     {
495         ""
496         { { $slot "head" } " is a " { $link string } "..." }
497         { { $slot "head" } " is a " { $link subgraph } "..." }
498     }
499     {
500         { { $slot "tail" } " is a " { $link string } "..." }
501         { "edge from " { $slot "tail" } " node\nto " { $slot "head" } " node" }
502         { "edge from " { $slot "tail" } " node\nto each node in " { $slot "head" } }
503     }
504     {
505         { { $slot "tail" } " is a " { $link subgraph } "..." }
506         { "edge from each node in " { $slot "tail" } "\nto " { $slot "head" } " node" }
507         { "edge from each node in " { $slot "tail" } "\nto each node in " { $slot "head" } }
508     }
509 }
510 "For more details, see " { $vocab-link "graphviz.render" } "."
511 $nl
512 "In addition, an " { $link edge } " may store local attributes in its " { $slot "attributes" } " slot (" { $instance edge-attributes } " tuple)."
513 }
514 { $notes
515 "By convention, an " { $link edge } " orders its endpoints \"from\" " { $slot "tail" } " \"to\" " { $slot "head" } ", even if it belongs to an undirected " { $link graph } ", where such a distinction is generally meaningless. See the Graphviz documentation (" { $url "http://graphviz.org/Documentation.php" } "), and specifically the notes about ambiguous attributes (in " { $url "http://graphviz.org/content/attrs" } ") for more information."
516 } ;
517
518 HELP: graph
519 { $class-description
520 "Represents the top-level (or " { $emphasis "root" } ") graph used in Graphviz. Its structure is modeled after the DOT language (see " { $url "http://graphviz.org/Documentation.php" } "):"
521 $nl
522 { $table
523   {
524       { $strong "Slot name" }
525       { $strong "Value" }
526       { $strong "Meaning in DOT" }
527   }
528   {
529       { $slot "id" }
530       { $instance string }
531       { "the reference name of a graph, as in " { $strong "graph" } " " { $slot "id" } " " { $strong "{" } " ... " { $strong "}" } }
532   }
533   {
534       { $slot "strict?" }
535       { $instance boolean }
536       { "indicates strictness, as in " { $strong "strict graph {" } " ... " { $strong "}" } }
537   }
538   {
539       { $slot "directed?" }
540       { $instance boolean }
541       { "corresponds to " { $strong "digraph {" } " ... " { $strong "}" } " vs. " { $strong "graph {" } " ... " { $strong "}" } }
542   }
543   {
544       { $slot "statements" }
545       { $instance sequence }
546       { "the defining \"body\", as in " { $strong "graph {" } " ... " { $slot "statements" } " ... " { $strong "}" } }
547   }
548 }
549 $nl
550 "In particular, " { $slot "statements" } " should be a " { $link sequence } " containing only instances of:"
551 { $list
552   { $link subgraph }
553   { $link node }
554   { $link edge }
555   { $link graph-attributes }
556   { $link node-attributes }
557   { $link edge-attributes }
558 }
559 } ;
560
561 HELP: node
562 { $class-description
563 "Represents a single Graphviz node. Each " { $link node } " is uniquely determined by an " { $slot "id" } " (" { $instance string } ") and may have per-node attributes stored in its " { $slot "attributes" } " slot (" { $instance node-attributes } " tuple)." ! TODO see graphviz.attributes
564 } ;
565
566 HELP: subgraph
567 { $class-description
568 "Represents a logical grouping of nodes and edges within a Graphviz graph. See " { $url "http://graphviz.org/Documentation.php" } " for more information."
569 $nl
570 "Its structure is largely similar to " { $link graph } ", except " { $link subgraph } " only has two slots: " { $slot "id" } " (" { $instance string } ") and " { $slot "statements" } " (" { $instance sequence } "). The " { $slot "strict?" } " and " { $slot "directed?" } " slots of the parent " { $link graph } " are implicitly inherited by a " { $link subgraph } "."
571 $nl
572 { $slot "id" } " and " { $slot "statements" } " correspond to the name and defining \"body\" of a subgraph in the DOT language, as in " { $strong "subgraph" } " " { $slot "id" } " " { $strong "{" } " ... " { $slot "statements" } " ... " { $strong "}" } "."
573 $nl
574 "In particular, " { $slot "statements" } " should be a " { $link sequence } " containing only instances of:"
575 { $list
576   { $link subgraph }
577   { $link node }
578   { $link edge }
579   { $link graph-attributes }
580   { $link node-attributes }
581   { $link edge-attributes }
582 }
583 } ;
584
585 ARTICLE: { "graphviz" "data" } "Graphviz data structures"
586 "To use the " { $vocab-link "graphviz" } " vocabulary, we construct Factor objects that can be converted to data understood by Graphviz (specifically, that " { $emphasis "libgraph" } " and " { $emphasis "libgvc" } " can understand; see " { $vocab-link "graphviz.ffi" } ")."
587 $nl
588 "The following classes are used to represent their equivalent Graphviz structures:"
589 { $subsections node edge subgraph graph }
590 "Several constructor variations exist to make building graphs convenient."
591 $nl
592 "To construct different sorts of graphs:"
593 { $subsections <graph> <digraph> <strict-graph> <strict-digraph> }
594 "To construct different sorts of subgraphs:"
595 { $subsections <subgraph> <anon> <cluster> }
596 "To construct nodes and edges:"
597 { $subsections <node> <edge> }
598 "Finally, use the following words to combine these objects into a single " { $link graph } ":"
599 { $subsections add add-node add-edge add-nodes add-path }
600 ;
601
602 ARTICLE: { "graphviz" "gallery" "complete" } "Complete graphs"
603 "In graph theory, a " { $emphasis "complete graph" } " is one in which there is an edge between each pair of distinct nodes."
604 $nl
605 { $code
606 "USING: kernel math.combinatorics math.parser sequences"
607 "graphviz graphviz.notation graphviz.render ;"
608 ""
609 ": K_n ( n -- )"
610 "    <graph>"
611 "        node[ \"point\" =shape ]; "
612 "        graph[ \"t\" =labelloc \"circo\" =layout ];"
613 ""
614 "        over number>string \"K \" prepend =label"
615 ""
616 "        swap iota 2 [ first2 add-edge ] each-combination"
617 "    preview ;"
618 }
619 $nl
620 { $code "5 K_n" }
621 { $image "resource:extra/graphviz/gallery/k5.png" }
622 $nl
623 { $code "6 K_n" }
624 { $image "resource:extra/graphviz/gallery/k6.png" }
625 $nl
626 { $code "7 K_n" }
627 { $image "resource:extra/graphviz/gallery/k7.png" }
628 ;
629
630 ARTICLE: { "graphviz" "gallery" "bipartite" } "Complete bipartite graphs"
631 "In graph theory, a " { $emphasis "bipartite graph" } " is one in which the nodes can be divided into exactly two independent sets (i.e., there are no edges between nodes in the same set)."
632 $nl
633 { $code
634 "USING: formatting locals math.parser sequences"
635 "graphviz graphviz.notation graphviz.render ;"
636 ""
637 ":: partite-set ( n color -- cluster )"
638 "    color <cluster>"
639 "        color =color"
640 "        node[ color =color ];"
641 "        n iota ["
642 "            number>string color prepend add-node"
643 "        ] each ;"
644 ""
645 ":: K_n,m ( n m -- )"
646 "    <graph>"
647 "        node[ \"point\" =shape ];"
648 "        graph[ \"t\" =labelloc \"dot\" =layout \"LR\" =rankdir ];"
649 ""
650 "        n \"#FF0000\" partite-set"
651 "        m \"#0000FF\" partite-set"
652 ""
653 "        add-edge ! between clusters"
654 ""
655 "        ! set label last so that clusters don't inherit it"
656 "        n m \"K %d,%d\" sprintf =label"
657 "    preview ;"
658 }
659 $nl
660 { $code "3 3 K_n,m" }
661 { $image "resource:extra/graphviz/gallery/k33.png" }
662 $nl
663 { $code "3 4 K_n,m" }
664 { $image "resource:extra/graphviz/gallery/k34.png" }
665 $nl
666 { $code "5 4 K_n,m" }
667 { $image "resource:extra/graphviz/gallery/k54.png" }
668 ;
669
670 ARTICLE: { "graphviz" "gallery" "cycle" } "Cycle graphs"
671 "In graph theory, a " { $emphasis "cycle graph" } " is one in which all the nodes are connected in a single circle."
672 $nl
673 { $code
674 "USING: kernel math math.parser sequences"
675 "graphviz graphviz.notation graphviz.render ;"
676 ""
677 ": add-cycle ( graph n -- graph' )"
678 "    [ iota add-path ] [ 1 - 0 add-edge ] bi ;"
679 ""
680 ": C_n ( n -- )"
681 "    <graph>"
682 "        graph[ \"t\" =labelloc \"circo\" =layout ];"
683 "        node[ \"point\" =shape ];"
684 "        over number>string \"C \" prepend =label"
685 "        swap add-cycle"
686 "    preview ;"
687 }
688 $nl
689 { $code "5 C_n" }
690 { $image "resource:extra/graphviz/gallery/c5.png" }
691 $nl
692 { $code "6 C_n" }
693 { $image "resource:extra/graphviz/gallery/c6.png" }
694 $nl
695 { $code "7 C_n" }
696 { $image "resource:extra/graphviz/gallery/c7.png" }
697 ;
698
699 ARTICLE: { "graphviz" "gallery" "wheel" } "Wheel graphs"
700 "In graph theory, a " { $emphasis "wheel graph" } " on " { $emphasis "n" } " nodes is composed of a single node connected to each node of a cycle of " { $emphasis "n-1" } " nodes."
701 $nl
702 { $code
703 "USING: arrays kernel math math.parser sequences"
704 "graphviz graphviz.notation graphviz.render ;"
705 ""
706 ": add-cycle ( graph n -- graph' )"
707 "    [ iota add-path ] [ 1 - 0 add-edge ] bi ;"
708 ""
709 ": W_n ( n -- )"
710 "    <graph>"
711 "        graph[ \"t\" =labelloc \"twopi\" =layout ];"
712 "        node[ \"point\" =shape ];"
713 "        over number>string \"W \" prepend =label"
714 "        over add-node"
715 "        over 1 - add-cycle"
716 "        swap [ ] [ 1 - iota >array ] bi add-edge"
717 "    preview ;"
718 }
719 $nl
720 { $code "6 W_n" }
721 { $image "resource:extra/graphviz/gallery/w6.png" }
722 { $code "7 W_n" }
723 { $image "resource:extra/graphviz/gallery/w7.png" }
724 { $code "8 W_n" }
725 { $image "resource:extra/graphviz/gallery/w8.png" }
726 ;
727
728 ARTICLE: { "graphviz" "gallery" "cluster" } "Cluster example"
729 "This example is adapted from " { $url "http://graphviz.org/content/cluster" } "."
730 $nl
731 { $code
732 "USING: graphviz graphviz.notation graphviz.render ;"
733 ""
734 "<digraph>"
735 "    \"dot\" =layout"
736 ""
737 "    0 <cluster>"
738 "        \"filled\" =style"
739 "        \"lightgrey\" =color"
740 "        node[ \"filled\" =style \"white\" =color ];"
741 "        { \"a0\" \"a1\" \"a2\" \"a3\" } ~->"
742 "        \"process #1\" =label"
743 "    add"
744 ""
745 "    1 <cluster>"
746 "        node[ \"filled\" =style ];"
747 "        { \"b0\" \"b1\" \"b2\" \"b3\" } ~->"
748 "        \"process #2\" =label"
749 "        \"blue\" =color"
750 "    add"
751 ""
752 "    \"start\" \"a0\" ->"
753 "    \"start\" \"b0\" ->"
754 "    \"a1\" \"b3\" ->"
755 "    \"b2\" \"a3\" ->"
756 "    \"a3\" \"a0\" ->"
757 "    \"a3\" \"end\" ->"
758 "    \"b3\" \"end\" ->"
759 ""
760 "    \"start\" add-node[ \"Mdiamond\" =shape ];"
761 "    \"end\" add-node[ \"Msquare\" =shape ];"
762 "preview"
763 }
764 { $image "resource:extra/graphviz/gallery/cluster.png" }
765 ;
766
767 ARTICLE: { "graphviz" "gallery" "circles" } "Colored circles example"
768 "This example was adapted from the \"star\" example in PyGraphviz (" { $url "http://networkx.lanl.gov/pygraphviz/" } ") and modified slightly."
769 $nl
770 { $code
771 "USING: formatting kernel math sequences"
772 "graphviz graphviz.notation graphviz.render ;"
773 ""
774 ": colored-circle ( i -- node )"
775 "    [ <node> ] keep"
776 "    [ 16.0 / 0.5 + =width ]"
777 "    [ 16.0 / 0.5 + =height ]"
778 "    [ 16 * \"#%2x0000\" sprintf =fillcolor ] tri ;"
779 ""
780 "<graph>"
781 "    graph[ \"3,3\" =size \"circo\" =layout ];"
782 ""
783 "    node[ \"filled\" =style"
784 "          \"circle\" =shape"
785 "          \"true\"   =fixedsize"
786 "          \"\"       =label ];"
787 ""
788 "    edge[ \"invis\" =style ];"
789 ""
790 "    0 add-node[ \"invis\" =style \"none\" =shape ];"
791 ""
792 "    16 iota ["
793 "        [ 0 -- ] [ colored-circle add ] bi"
794 "    ] each"
795 "preview"
796 }
797 { $image "resource:extra/graphviz/gallery/circles.png" }
798 ;
799
800 ARTICLE: { "graphviz" "gallery" "fsm" } "Finite state machine example"
801 "This example is adapted from " { $url "http://graphviz.org/content/fsm" } "."
802 $nl
803 { $code
804 "USING: graphviz graphviz.notation graphviz.render ;"
805 ""
806 "<digraph>"
807 "    \"LR\" =rankdir"
808 "    \"8,5\" =size"
809 "    node[ \"doublecircle\" =shape ];"
810 "    { \"LR_0\" \"LR_3\" \"LR_4\" \"LR_8\" } add-nodes"
811 "    node[ \"circle\" =shape ];"
812 "    \"LR_0\" \"LR_2\" ->[ \"SS(B)\" =label ];"
813 "    \"LR_0\" \"LR_1\" ->[ \"SS(S)\" =label ];"
814 "    \"LR_1\" \"LR_3\" ->[ \"S($end)\" =label ];"
815 "    \"LR_2\" \"LR_6\" ->[ \"SS(b)\" =label ];"
816 "    \"LR_2\" \"LR_5\" ->[ \"SS(a)\" =label ];"
817 "    \"LR_2\" \"LR_4\" ->[ \"S(A)\" =label ];"
818 "    \"LR_5\" \"LR_7\" ->[ \"S(b)\" =label ];"
819 "    \"LR_5\" \"LR_5\" ->[ \"S(a)\" =label ];"
820 "    \"LR_6\" \"LR_6\" ->[ \"S(b)\" =label ];"
821 "    \"LR_6\" \"LR_5\" ->[ \"S(a)\" =label ];"
822 "    \"LR_7\" \"LR_8\" ->[ \"S(b)\" =label ];"
823 "    \"LR_7\" \"LR_5\" ->[ \"S(a)\" =label ];"
824 "    \"LR_8\" \"LR_6\" ->[ \"S(b)\" =label ];"
825 "    \"LR_8\" \"LR_5\" ->[ \"S(a)\" =label ];"
826 "preview"
827 }
828 { $image "resource:extra/graphviz/gallery/fsm.png" }
829 ;
830
831 ARTICLE: { "graphviz" "gallery" "record" } "Record example"
832 "This example is adapted (and slightly altered) from " { $url "http://graphviz.org/content/datastruct" } "."
833 $nl
834 "As it shows, special label syntax is still parsed, like escape sequences (see " { $url "http://graphviz.org/content/attrs#kescString" } ") or, in this case, record syntax (see " { $url "http://graphviz.org/content/node-shapes#record" } "). However, there is no equivalent to Graphviz's headport/tailport syntax, so we set the " { $link edge } " attributes explicitly."
835 $nl
836 { $code
837 "USING: graphviz graphviz.notation graphviz.render ;"
838 ""
839 "<digraph>"
840 "    graph[ \"LR\" =rankdir \"8,8\" =size ];"
841 "    node[ 8 =fontsize \"record\" =shape ];"
842 ""
843 "    \"node0\" add-node["
844 "        \"<f0> 0x10ba8| <f1>\" =label"
845 "    ];"
846 "    \"node1\" add-node["
847 "        \"<f0> 0xf7fc4380| <f1> | <f2> |-1\" =label"
848 "    ];"
849 "    \"node2\" add-node["
850 "        \"<f0> 0xf7fc44b8| | |2\" =label"
851 "    ];"
852 "    \"node3\" add-node["
853 "        \"<f0> 3.43322790286038071e-06|44.79998779296875|0\" =label"
854 "    ];"
855 "    \"node4\" add-node["
856 "        \"<f0> 0xf7fc4380| <f1> | <f2> |2\" =label"
857 "    ];"
858 "    \"node5\" add-node["
859 "        \"<f0> (nil)| | |-1\" =label"
860 "    ];"
861 "    \"node6\" add-node["
862 "        \"<f0> 0xf7fc4380| <f1> | <f2> |1\" =label"
863 "    ];"
864 "    \"node7\" add-node["
865 "        \"<f0> 0xf7fc4380| <f1> | <f2> |2\" =label"
866 "    ];"
867 "    \"node8\" add-node["
868 "        \"<f0> (nil)| | |-1\" =label"
869 "    ];"
870 "    \"node9\" add-node["
871 "        \"<f0> (nil)| | |-1\" =label"
872 "    ];"
873 "    \"node10\" add-node["
874 "        \"<f0> (nil)| <f1> | <f2> |-1\" =label"
875 "    ];"
876 "    \"node11\" add-node["
877 "        \"<f0> (nil)| <f1> | <f2> |-1\" =label"
878 "    ];"
879 "    \"node12\" add-node["
880 "        \"<f0> 0xf7fc43e0| | |1\" =label"
881 "    ];"
882 ""
883 "    \"node0\" \"node1\"   ->[ \"f0\" =tailport \"f0\" =headport ];"
884 "    \"node0\" \"node2\"   ->[ \"f1\" =tailport \"f0\" =headport ];"
885 "    \"node1\" \"node3\"   ->[ \"f0\" =tailport \"f0\" =headport ];"
886 "    \"node1\" \"node4\"   ->[ \"f1\" =tailport \"f0\" =headport ];"
887 "    \"node1\" \"node5\"   ->[ \"f2\" =tailport \"f0\" =headport ];"
888 "    \"node4\" \"node3\"   ->[ \"f0\" =tailport \"f0\" =headport ];"
889 "    \"node4\" \"node6\"   ->[ \"f1\" =tailport \"f0\" =headport ];"
890 "    \"node4\" \"node10\"  ->[ \"f2\" =tailport \"f0\" =headport ];"
891 "    \"node6\" \"node3\"   ->[ \"f0\" =tailport \"f0\" =headport ];"
892 "    \"node6\" \"node7\"   ->[ \"f1\" =tailport \"f0\" =headport ];"
893 "    \"node6\" \"node9\"   ->[ \"f2\" =tailport \"f0\" =headport ];"
894 "    \"node7\" \"node3\"   ->[ \"f0\" =tailport \"f0\" =headport ];"
895 "    \"node7\" \"node1\"   ->[ \"f1\" =tailport \"f0\" =headport ];"
896 "    \"node7\" \"node8\"   ->[ \"f2\" =tailport \"f0\" =headport ];"
897 "    \"node10\" \"node11\" ->[ \"f1\" =tailport \"f0\" =headport ];"
898 "    \"node10\" \"node12\" ->[ \"f2\" =tailport \"f0\" =headport ];"
899 "    \"node11\" \"node1\"  ->[ \"f2\" =tailport \"f0\" =headport ];"
900 "preview"
901 }
902 { $image "resource:extra/graphviz/gallery/record.png" }
903 ;
904
905 ARTICLE: { "graphviz" "gallery" } "Graphviz gallery"
906 "Below are some examples of the typical usage of the " { $vocab-link "graphviz" } " vocabulary."
907 $nl
908 "The images in the gallery were pre-compiled using Graphviz version 2.26.3. Depending on your particular Graphviz installation, these examples may not actually work for you, especially if you have a non-standard installation."
909 $nl
910 "Also, while most of the images have a reasonable size, some of these examples may be slow to load in the UI listener."
911 $nl
912 { $subsections
913     { "graphviz" "gallery" "complete" }
914     { "graphviz" "gallery" "bipartite" }
915     { "graphviz" "gallery" "cycle" }
916     { "graphviz" "gallery" "wheel" }
917     { "graphviz" "gallery" "cluster" }
918     { "graphviz" "gallery" "circles" }
919     { "graphviz" "gallery" "fsm" }
920     { "graphviz" "gallery" "record" }
921 }
922 ;
923
924 ARTICLE: "graphviz" "Graphviz"
925 "The " { $vocab-link "graphviz" } " vocabulary provides an interface to your existing Graphviz installation, thus allowing you to create, edit, and render Graphviz graphs using Factor. For more information about Graphviz, see " { $url "http://graphviz.org" } "."
926 $nl
927 "This vocabulary provides the basic tools to construct Factor representations of graphs. For more details, see:"
928 { $subsections { "graphviz" "data" } }
929 "Other vocabularies let you change a graph's look & feel, write cleaner code to represent it, and (of course) generate its Graphviz output:"
930 { $vocab-subsection "Graphviz attributes" "graphviz.attributes" }
931 { $vocab-subsection "Graphviz notation" "graphviz.notation" }
932 { $vocab-subsection "Rendering Graphviz output" "graphviz.render" }
933 $nl
934 "After reading the above, you can see several examples in action:"
935 { $subsections { "graphviz" "gallery" } }
936 ;
937
938 ABOUT: "graphviz"