CL-DOT - Generate Dot Output from Arbitrary Lisp Data


 

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.


 

Contents

  1. Download
  2. Support
  3. Usage
  4. The CL-DOT dictionary
    1. *dot-path*
    2. *neato-path*
    3. attributed
    4. dot-graph
    5. generate-graph-from-roots
    6. node
    7. graph-object-knows-of
    8. graph-object-node
    9. graph-object-pointed-to-by
    10. graph-object-points-to
    11. print-graph
  5. Deprecated Functionality
    1. generate-graph
    2. object-knows-of
    3. object-node
    4. object-pointed-to-by
    5. object-points-to
  6. Acknowledgements

 

Download

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/.


 

Support

Please direct bug reports, patches, questions, and any other feedback to Michael Weber.


 

Usage

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.
 

The CL-DOT dictionary


[Special variable]
*dot-path*


Path to dot


[Special variable]
*neato-path*


Path to neato


[Standard class]
attributed


Wraps an object (initarg :OBJECT) with dot attribute 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 dot attributes (a plist, initarg :ATTRIBUTES) and an optional dot id (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.


 

Deprecated Functionality

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


Calls GENERATE-GRAPH-FROM-ROOTS with 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



 

Acknowledgements

This documentation was prepared with DOCUMENTATION-TEMPLATE.

BACK TO MY HOMEPAGE