[Haskell-cafe] A query to users of graphviz

Ivan Lazar Miljenovic ivan.miljenovic at gmail.com
Thu May 6 09:51:30 EDT 2010


For anyone who uses my graphviz library: who uses the graphNodes and
functions?  Note that this also applies to anyone who uses augmentation
functions as well (more specifically, when they define global attributes
for use with an augmentation function).

If so, would it be a problem if I switched it from returning a list to
returning a Set?

The rationale being: Dot allows nodes to be "defined" twice (to specify
different attributes) and also that some nodes might only be defined
because they appear in an edge.  Here is an example containing both
problems:

,----
| digraph {
|         a [label="hello"]
|         subgraph { rank=same a b }
|         b -> c
| }
`----

Currently, graphNodes ignores the first problem and doesn't even
consider the second (though I thought I had implemented support for
this); however, I myself am needing this functionality soon, hence why
I'm considering this (note that this isn't a problem for graphEdges, as
multiple edges are OK).

Currently, graphNodes doesn't take this into account (for edges,
multiple definitions means the edge is drawn multiple times, so this
isn't a problem for graphEdges); as such, graphviz should really (but
doesn't) use nub on this.  A better solution would be to use Sets and
merge the results by merging together the applied attributes (and adding
the global attributes for nodes at the same time).

However, the problem with using Sets is that it means node type has to
be an instance of Ord.  I can't think of many types which you might use
as a node type that _wouldn't_ have an applicable Ord instance, but I
suppose it's possible.

As such, there are three possible options:

1) Leave as-is (just get it working properly with hack-y nubs, etc.):
   this will be extremely inefficient.

2) Use Sets (or a Map n Attributes, which will make merging Attributes
   easier); this will require an Ord constraint on the label type for
   the DotRepr class (i.e. it will be needed _everywhere_).  It may also
   not be as lazy as the current implementation, and the node order will
   be changed.

3) As with 2), but convert the result back to a list so that the current
   interface remains unchanged (with the added benefit of not requiring
   a major version bump).

With whichever option is chosen, then there is also the consideration of
whether any global attributes should be considered and added to the list
of attributes (this goes for graphEdges as well).

I personally am thinking of going with 3) and adding in global
attributes as well.  What do other people think?

-- 
Ivan Lazar Miljenovic
Ivan.Miljenovic at gmail.com
IvanMiljenovic.wordpress.com


More information about the Haskell-Cafe mailing list