Lisp HUG Maillist Archive

graphs with labelled edges

I would like to be able to draw graphs which have labels on their
edges.  There are two problems I don't know how to solve:

1. Is there any easy way using CAPI:GRAPH-PANE to label edges in the
   graph?  I guess I need to do something with :EDGE-PINBOARD-CLASS,
   but I'm not sure what!

2. Is there any way to make it be so that if there are two edges
   between a pair of nodes (so the same node appears twice in the
   children) that two edges are drawn?  This seems to me to be very
   hard as they need to avoid each other, and I can live without this
   by preprocessing the graph to make there just be one child with a
   the edge having label which is all the labels combined.

Is there any other grapher anyone knows of which could do (2)?

Thanks

--tim


Re: graphs with labelled edges

> From: "Tim Bradshaw" <tfb@cley.com>
> Sent: Tuesday, April 30, 2002 10:54 PM
> Subject: graphs with labelled edges
>
> I would like to be able to draw graphs which have labels on their
> edges.  There are two problems I don't know how to solve:
>
> 1. Is there any easy way using CAPI:GRAPH-PANE to label edges in the
>    graph?  I guess I need to do something with :EDGE-PINBOARD-CLASS,
>    but I'm not sure what!

Since the labels may extend beyond the bounding rectangle of the
edge, I think you need to create a separate pinboard object for
the label.

The following code might get you started:

_________________________________________________________________

(defun node-children (node)
  (when (< node 16)
    (list (* node 2)
          (1+ (* node 2)))))

(defvar *edges*) ; a list of triplets of the form
                 ; (from-data to-data line-pinboard-object)

(defun my-make-edge (pinboard from to)
  (let* ((edge (make-instance 'capi:line-pinboard-object)))
    (push (list from to edge) *edges*)
    edge))

(defun make-labelled-graph ()
  (let* ((*edges* '())
         (graph (capi:contain
                 (make-instance 'capi:graph-pane
                                :roots '(1)
                                :edge-pane-function 'my-make-edge
                                :children-function 'node-children)
                 :best-width 300
                 :best-height 400
                 :process nil ; so that dynamic binding of *edges* is
not lost
                 )))
    (loop for x in *edges*
          do (let* ((label (capi:with-geometry (third x)
                             (make-instance
                              'capi:item-pinboard-object
                              :text (format nil "~S-~S"
                                            (first x)
                                            (second x))
                              :x (+ capi:%x%
                                    (/ capi:%width% 2))
                              :y (+ capi:%y%
                                    (/ capi:%height% 2))))))
               (capi:manipulate-pinboard graph
                                         label
                                         :add-top)))))

(make-labelled-graph)

_________________________________________________________________


> 2. Is there any way to make it be so that if there are two edges
>    between a pair of nodes (so the same node appears twice in the
>    children) that two edges are drawn?  This seems to me to be very
>    hard as they need to avoid each other, and I can live without
>    this
>    by preprocessing the graph to make there just be one child with a
>    the edge having label which is all the labels combined.
>
> Is there any other grapher anyone knows of which could do (2)?

No ideas here.

>
> Thanks
>
> --tim

Simon.





Updated at: 2020-12-10 09:02 UTC