CL-DOT is a small package for easily generating dot (a program in the Graphviz suite) output from arbitrary Lisp data.
Once again it was time to generate some output suitable for
Nothing new, stuff that I've done at least four times in three languages
(including twice in Lisp). But this time around the data I was going
to graph was sufficiently complicated
(at least a dozen different kinds of nodes) that it made sense to
actually think about it, and not write an unextensible 50-line function
to do the work.
There's a protocol of four generic functions, one of which must
be defined for every object in the graph (
three others which are used for expressing different relations
between objects in the graph (
OBJECT-KNOWS-OF). For example:
;; Conses (defmethod cl-dot:object-node ((object cons)) (make-instance 'cl-dot:node :attributes '(:label "cell \\N" :shape :box))) (defmethod cl-dot:object-points-to ((object cons)) (list (car object) (make-instance 'cl-dot:attributed :object (cdr object) ;; Make the CDR edges more important than the ;; CAR edges :attributes '(:weight 3)))) ;; Symbols (defmethod cl-dot:object-node ((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
the graph object you can either generate dot-format output to some
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 data))) (cl-dot:dot-graph graph "/tmp/test1ps"))
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 data '(:rankdir "LR")))) (cl-dot:dot-graph graph "/tmp/test2ps"))
ASDF-INSTALL the package and read the README for more details.