Abstract
CL-DOT is a small package for easily generating dot (a program in the GraphViz suite) output from arbitrary Lisp data. It should work with the following implementations:
Original author is Juho Snellman, current maintainer is Michael Weber. The code comes with a BSD-style license.
Download shortcut: http://www.foldr.org/~michaelw/projects/cl-dot/cl-dot.tar.gz.
CL-DOT together with this documentation can be downloaded from http://www.foldr.org/~michaelw/projects/cl-dot/cl-dot.tar.gz. Alternatively, it can be installed via ASDF-Install:
(asdf-install:install "http://www.foldr.org/~michaelw/projects/cl-dot/cl-dot.tar.gz")
The current version is 0.7.0.
A Subversion repository is available at http://svn.foldr.org/~michaelw/cl-dot/.
Please direct bug reports, patches, questions, and any other feedback to Michael Weber.
First, define methods for the generic functions in the GRAPH-OBJECT-
protocol for all objects that can appear in your graph. GRAPH-OBJECT-NODE must be defined for all objects, the others have a default implementation. For example:
;; Conses
(defmethod cl-dot:graph-object-node ((graph (eql 'example)) (object cons))
(make-instance 'cl-dot:node
:attributes '(:label "cell \\N"
:shape :box)))
(defmethod cl-dot:graph-object-points-to ((graph (eql 'example)) (object cons))
(list (car object)
(make-instance 'cl-dot:attributed
:object (cdr object)
:attributes '(:weight 3))))
;; Symbols
(defmethod cl-dot:graph-object-node ((graph (eql 'example)) (object symbol))
(make-instance 'cl-dot:node
:attributes `(:label ,object
:shape :hexagon
:style :filled
:color :black
:fillcolor "#ccccff")))
To generate a graph object for your data, call GENERATE-GRAPH-FROM-ROOTS.
From the graph object you can either generate dot-format output to some stream with PRINT-GRAPH, or call dot directly on the data with DOT-GRAPH. For example:
(let* ((data '(a b c #1=(b z) c d #1#))
(graph (cl-dot:generate-graph-from-roots 'example (list data))))
(cl-dot:dot-graph graph "/tmp/test.png" :format :png))
You can also specify attributes for the whole graph:
(let* ((data '(a b c #1=(b z) c d #1#))
(graph (cl-dot:generate-graph-from-roots 'example (list data) '(:rankdir "LR"))))
(cl-dot:dot-graph graph "/tmp/test.png" :format :png))
To generate a drawing for an undirected graph you can call DOT-GRAH in the following way
(cl-dot:dot-graph graph "/tmp/test.png" :format :png :directed nil)
When the directed keyword argument is set to nil (the default value is t) DOT-GRAPH outputs an undirected graph instead of directed. To do that it needs the neato program from the graphviz package, which is used to layout undirected graphs. The path to the neato program is stored in the *NEATO-PATH* special variable.
Note that neato will not fold automatically duplicate edges, i.e if you have an edge from a to b and then from b to a (which is the case by definition for undirected graphs) you'll end up with both edges printed by 'neato'. So if your in memory representation contains both edges (most of the times it will as most graph algorithms depend on that when working with undirected graphs) you will have to remove one of the edges before
outputing the graph.
[Special variable]
*dot-path*
Path to
dot
[Special variable]
*neato-path*
Path to
neato
[Standard class]
attributed
Wraps an object (initarg
:OBJECT) withdotattribute information (a plist, initarg:ATTRIBUTES)
[Function]
dot-graph graph outfile &key format directed => result
Renders GRAPH to OUTFILE, by running the program in either
*DOT-PATH*or*NEATO-PATH*. When DIRECTED is t (the default) it will use the program in*DOT-PATH*to render a directed graph. Otherwise (when DIRECTED is set to nil) it will use the program in*NEATO-PATH*to render an undirected graph.The default FORMAT is Postscript.
[Generic function]
generate-graph-from-roots graph object &optional attributes => result
Construct a GRAPH with ATTRIBUTES starting from OBJECTS (a sequence of objects), using the
GRAPH-OBJECT-protocol.
[Method]
generate-graph-from-roots graph object &optional attributes => result
[Standard class]
node
A graph node with
dotattributes (a plist, initarg:ATTRIBUTES) and an optionaldotid (initarg:ID, autogenerated by default).
[Generic function]
graph-object-knows-of graph object => result
Return a list of objects that this object knows should be part of the graph, but which it has no direct connections to.
[Method]
graph-object-knows-of graph object => result
[Generic function]
graph-object-node graph object => result
Return a NODE instance for this object, or
NIL. In the latter case the object will not be included in the graph, but it can still have an indirect effect via other protocol functions (e.g.,GRAPH-OBJECT-KNOWS-OF). This function will only be called once for each object during the generation of a graph.
[Generic function]
graph-object-pointed-to-by graph object => result
Return a list of objects to which the NODE of this object should be connected. The edges will be directed from the other objects to this one. To assign dot attributes to the generated edges, each object can optionally be wrapped in a instance of
ATTRIBUTED.
[Method]
graph-object-pointed-to-by graph object => result
[Generic function]
graph-object-points-to graph object => result
Return a list of objects to which the NODE of this object should be connected. The edges will be directed from this object to the others. To assign dot attributes to the generated edges, each object can optionally be wrapped in a instance of
ATTRIBUTED.
[Method]
graph-object-points-to graph object => result
[Function]
print-graph graph &optional stream => result
Print a dot-format representation of GRAPH to STREAM.
The OBJECT- protocol has been deprecated in favor of the more general
GRAPH-OBJECT- protocol, which allows objects to be
presented differently for different graphs. For backwards
compatibility, the OBJECT- protocol functions are called by
their respective GRAPH-OBJECT- equivalents
when GENERATE-GRAPH is
used.
[Generic function]
generate-graph object &optional attributes => result
Construct a GRAPH with ATTRIBUTES starting from OBJECT, using the
OBJECT-protocol.
[Method]
generate-graph object &optional attributes => result
CallsGENERATE-GRAPH-FROM-ROOTSwith a singleton list of object.
[Generic function]
object-knows-of object => result
[Method]
object-knows-of object => result
[Generic function]
object-node object => result
[Generic function]
object-pointed-to-by object => result
[Method]
object-pointed-to-by object => result
[Generic function]
object-points-to object => result
[Method]
object-points-to object => result
This documentation was prepared with DOCUMENTATION-TEMPLATE.