Racket + Graphviz

164 views
Skip to first unread message

Hadi Moshayedi

unread,
Jul 31, 2019, 6:52:05 PM7/31/19
to Racket Users
Hello Racketeers,

Recently I've started thinking about on how we can create different kinds of diagrams in Racket. One of the tools that seemed easy to be exposed as a library in Racket seems to be Graphviz. You can pipe in the graph definition into it and it will pipe out the json layout of how to draw the graph.

So I started working on https://github.com/pykello/racket-graphviz, which is in early stages, but I thought I can share here for some feedback.

Some highlights are:
 - Digraphs are defined as s-expressions
 - (digraph->pict ...) converts the digraph to a Racket Pict which can be composed with other Picts and you can use in slideshow, etc.
 - Graphviz has some standard node shapes, but with this library you can use any Pict value as the node shape! See the examples in the README file.

I have plans like being able to query the layout of each node so we can draw an arrow from a Graphviz layout to anything else.

After making this something useful, I was thinking about writing some other libraries to make different kinds of system diagrams (sequence diagram, timeline diagram, ...) easy to generate in Racket.

Any feedback? Do you think this can be useful?

-- Hadi

Stephen De Gabrielle

unread,
Aug 1, 2019, 11:45:24 AM8/1/19
to Racket Users
this looks very nice! Thank you for sharing this. 

Don't forget to put it in a `package` and publish it on https://pkgs.racket-lang.org/ 

kind regards, 

Stephen 

Ryan Kramer

unread,
Aug 1, 2019, 3:23:43 PM8/1/19
to Racket Users
This looks interesting! I have thought about trying to generate Entity Relationship diagrams given a database schema, but assumed that laying out the boxes would be a hard problem. Looks like GraphViz might do a decent job at this. I'll try it out and let you know how it goes.

Hadi Moshayedi

unread,
Aug 1, 2019, 4:14:47 PM8/1/19
to Ryan Kramer, Racket Users
On Thu, Aug 1, 2019 at 12:23 PM Ryan Kramer <default...@gmail.com> wrote:
This looks interesting! I have thought about trying to generate Entity Relationship diagrams given a database schema, but assumed that laying out the boxes would be a hard problem. Looks like GraphViz might do a decent job at this. I'll try it out and let you know how it goes.
 
Yesterday I learnt that also PlantUML can be used using stdin/stdout interface and it can generate SVG, which can be converted to Pict using rsvg. I was thinking spending some time on trying to have some kind of Racket library for that too. It might be a better tool for generating ER diagrams. See http://plantuml.com/ie-diagram

-- Hadi

Neil Van Dyke

unread,
Aug 1, 2019, 7:14:34 PM8/1/19
to Racket Users
Hadi Moshayedi wrote on 8/1/19 4:14 PM:
I tend to use UML's notation for "static object modeling" when doing
what's essentially entity-relationship modeling.  (There's other UML
models, but usually people just mean the main diagram, and often just to
show only attributes and inheritance and nothing else.  Few people might
do rigorous state modeling, protocol event traces, etc.)

Your DB schema is relational?  If you're willing to represent DB
relational tables and columns as UML classes with attributes, the UML
notation might be more compact and understandable than an ER one you'd
use, but you have to decide how much of the DB semantics you want to
represent, and how.  For example, if you want to talk about DB joins you
use, you might just use only attribute annotations for candidate keys,
*or* you might use much more visual UML associations that are in
addition to the attributes.  (For target implementations *without* joins
like that, you'd probably instead use association roles, without
attributes at all, and indicate navigability directions of the
associations.)

Regarding laying out the boxes, that particular UML notation might be
modeled as a constraint satisfaction problem, but it's a tricky one.[1] 
For example, in practice, you might usually want your generalization
associations to have a high priority for super being above sub, usually
less so for aggregation assemblies, link attributes (if you have those)
tending to come off a horizontal edge, etc.  Then you get into things
like edge routing for reducing crossings and bends, while still spacing
out your vertices, plus the various adornments on edges that complicate
things.  And maybe you want stability of layout between changes to also
be a factor... One of the several methodologists' camps that went into
UML (and from which that particular UML notation largely came), Rumbaugh
et al.'s OMT, developed an interactive diagramming tool that was more
limited than real CASE systems, but did the best job of constraint-based
interactive editing that I'd seen (but not enough constraints to do
automatic layout): OMTool, from a GE lab.[2]

[1] For a similar visual language, my industry R&D group once hired a
very smart PhD student in computational geometry graph drawing to tackle
it, and they made some progress, but it still wasn't entirely a solved
problem afterwards.

[2]  Racket aside: I actually used OMTool, until I no longer had access
to it, and kludged up a simple but practical Java generator/updater for
it, "https://www.neilvandyke.org/jomtool/". You'll notice Jomtool was
written in Emacs Lisp, rather than Java, even though I was an early Java
expert and advocate, and working in Java.  When I went looking for a new
platform for rapid R&D work, especially in PL and symbolic Web
processing, I admitted that a Lisp was more productive than my beloved
Java for many things, and I ended up choosing Scheme.  Even though
Scheme didn't have basic OO features, and I'd been working very heavily
in OO architecture/design/OOP/methodology, and had been invited to be on
a UML committee -- it still looked like a win.  Scheme turned out to be
a good choice for those R&D purposes, but industry is a much longer and
more complicated story, and there are disruption opportunities close on
the horizon.

Hadi Moshayedi

unread,
Aug 4, 2019, 1:45:57 AM8/4/19
to Ryan Kramer, Racket Users
On Thu, Aug 1, 2019 at 12:23 PM Ryan Kramer <default...@gmail.com> wrote:
This looks interesting! I have thought about trying to generate Entity Relationship diagrams given a database schema, but assumed that laying out the boxes would be a hard problem. Looks like GraphViz might do a decent job at this. I'll try it out and let you know how it goes.

I actually tried this today. I added a function er-diagram which you can find an example

The script linked above generates the following diagram:

image.png

Not perfect, but not too bad.

You can find implementation of the er-diagram function at

(The API for the package is evolving, so I am holding off on writing a documentation until
it becomes stable. But thanks to Stephen, I've uploaded the package to the package catalog,
so you can now do "raco pkg install racket-graphviz")

-- Hadi

Neil Van Dyke

unread,
Aug 4, 2019, 2:28:15 AM8/4/19
to Hadi Moshayedi, Racket Users
Hadi, that looks great so far!

There are some adornments you can still add, such as to indicate which
attributes are candidates for being keys (or are keys), but those can
just be added to existing text strings.

One important thing still to do is labeling the relations.  You might do
it with a name for each relation (which usually is read in one
direction), and/or with with names for the respective role each entity
plays in each relation.  One reason for this (just mentioning it for
racket-users) is that, in practice, it's not-unusual to end up with
relations for which the purpose is not obvious, and even multiple
relations among the same pair of entities (and in the case of multiple
relations, each expressing role cardinalities in your meta-model, which
one is which).

Another reason for naming associations, which might be more semantics
than you want to get into for your immediate purpose, is that there's
richer semantics one might use in analysis, which might end up conflated
in current implementation, *but* that can be useful to capture for
documentation, and maybe also sometimes useful as a cognitive prompt
while working through it.

For an old example, if you're modeling a system involving multiple
companies and their employees, you might start with Company and Employee
entities, and maybe label the many-to-many relation between them
Employment.  But, when you go place a Salary attribute, you see it could
be considered an attribute of the Employment named relationship between
a Company and a Person (optional role names: Employer and Employee), and
you realize that it's useful for other parts of your system to talk
about a Person as distinct from being an Employee (e.g., for
representing multiple employments of a person, and things about a person
distinct from any employment). And maybe, in your analysis model,
attributions of a relation is how it appears (if your ER meta-model
supports that), which preserves the roles, even though, in the
implementation, that ends up mapping to implementation the same as an
entity does (to, e.g., a table or object class).

Reply all
Reply to author
Forward
0 new messages