Recommend better way to show data graphically

I want to show data from a database graphically.
I need directed graph (I mean graph with arrows).
I want to trace each relationsip from one node to another.
I also want to make it compact (it tends to be huge, this sample it not full).
I don’t care about nested levels or indentation of each level.

Here is a simple result of what I’ve done (see attachments).
I don’t like how it is shown now because I can’t trace each arrow (they are stick together).
What can I do to make it better?
A small code sample would be also desirable.

I create it this way:
“C:\Program Files\Graphviz\bin\dot.exe” -Tsvg -O -Kdot “C:\graph\input.graphviz”

Here is a code sample:

Here is a result.
I failed to load it to your forum so uploaded its content here (just rename extension to svg or generate the code itself):
https://pastebin.com/skWAX8vT

First note that there 16 nodes with more that 10 edges, one has 45 edges. Perfectly legal, of course, but it starts to get messy.

Better is in the eye of the beholder, but here are

  • changes to your input
  • a longer set of commands
  • and an output that compares results from four of the layout engines (dot, neato, fdp, and twopi)

The changes, all go at the beginning of your input file

strict // no multi-edges
digraph G {
rankdir=LR;         // try both ways,  only used by dot
ranksep=2.4         // spread out ranks,  only used by dot & twopi
overlap=false       // only used by neato and fdp
node [shape=rect]   // somewhat smaller footprint than ellipse

Note that strict only seems to be described in this document: https://www.graphviz.org/pdf/dotguide.pdf (see p28)

The command set:

unflatten -f -l4  myfile.gv | dot | edgepaint | neato  -n2 -Tsvg >myfile.svg

unflatten will try to break-up long rows/columns and is described here: https://www.graphviz.org/pdf/unflatten.1.pdf
edgepaint changes the colors of edges to make them easier to follow and is described here: https://www.graphviz.org/pdf/edgepaint.1.pdf
neato -n2 take the result of the earlier programs & generate the final image file and is described here: FAQ | Graphviz

Output of the four layout engines smooshed into one file (sorry, save it to disk & the display/zoom/magnify):

1 Like

Yes, if the network is very dense, maybe use a heat map (matrix) or other representation, instead of a graph layout.

It’s covered in the online documentation, DOT Language | Graphviz

Note that the neato and fdp graphs were not “tuned”. I expect that both could be made “better” (eye of the beholder).
Neato in particular has lots of potential attributes to adjust.

It’s one of those frou frou language features that we made because it seemed cool, and it does get rid of multi edges but it’s a little strange. I think that when attributes are set on repeated instances of the same edge in a strict graph, the last setting wins, but maybe it would make more sense to sum or concatenate values somehow (we don’t have have types so that’s a further complication).

Thanks for your replies!

  1. Is there any way to prevent edges to overlap nodes?
    Better let the edges intersect other edges, but not nodes.
    I don’t like this:
    0000000728

  2. Is there a way to make the edge not a straight line, but with a 90-degree bend (sorry, I don’t know how to explain), the second example in this image.
    It might help with my previous question.
    0000000730

  3. Is there any way to create an edge between clusters itself instead its nodes ?
    I want to group many nodes to one cluster and create an edge between the cluster itself with another nodes or another clusters to replace many edges leading to one node to one edge.
    I would like to write this and get this:

0000000731

I tried this way but failed:

digraph {

  subgraph cluster01 {
    a1 -> b1
  }
  
  subgraph cluster02 {
    c1 -> d1
  }
  
  "cluster01" -> "cluster02"
}

[comment - these are great questions - not only are they clearly stated, they address common problems. My answers will be “best I can do”, but no guarantees, especially to Q1.]

Q1. In general, there is no way to guarantee that edges don’t overlap nodes. But there are many ways to reduce the probability of this problem

  • Layout engine choice - The dot engine attempts to minimize this problem and it provides attributes like nodesep and ranksep that further help. Neato is the engine with second-most attributes that might help. Each engine approaches layout differently and is capable of producing a “best” result or a “worst” result, depending on the underlying graph, the attributes assigned in the input, and the “eye of the beholder”.

  • graph-level

    • splines=true is most likely to produce “best” (non-overlapped) results, splines=ortho is my second choice, but it is buggy (no ports allowed) and often produces odd results, polyline & curved next, and forget splines=false
    • use attributes like nodesep and ranksep to spread things (nodes) out to allow enough room (“floor space”) to place the edges
    • use consolidate=true to consolidate edges
  • node attributes -

    • use width, height, fontsize and linebreaks within text to keep nodes smaller and more square to prevent “walls” (my term) of nodes across the page that make it difficult to squeeze in the edges.

    I am sure there are many other attributes that can help

Q2. Try

  • splines=ortho (buggy but can produce some fine results),
  • do-it-yourself - many users use invisible nodes to create their own orthogonal edges
  • I just announced a program that can create “simple” orthogonal edges (A program to "fix" simple edges - #3 by steveroush), but it is not capable of producing edges for a complex graph

Q3. You can produce edges between clusters and/or edges (for dot only, as I remember). You need add compound=true and then use the lhead and/or ltail attributes (see https://www.graphviz.org/pdf/dotguide.pdf)
Here is an example, and whoops there seems to be a new bug - I will report the bug later today,

digraph G {
  compound=true

  subgraph clusterA {
    a1 -> a2 -> a3
  }
  subgraph clusterB {
    b1 -> b2
    b1 -> b3
    b1 -> c2
  }
  a1 -> b2 [lhead=clusterB]
  c2 -> a3 [ltail=clusterB]
  b3 -> a3 [ltail=clusterB, lhead=clusterA]
}

Correct result:
compoundOK

Actual result:
compoundOKbug

2 Likes

I would like to propose the svg export approach. This produces an svg that becomes interactive.

I added the javascript that is added by this tool: Excel to Graphviz to your original svg and when clicking on nodes you toggle highlighting all the edges that are connecting to them. Even for lines that are untracable in the clutter of lines, you can follow them after they are highlighted. Given the interactivity no need to rebuild the graph for each item separately, just click on the nodes for which you want the edges to be highlighted.

Result :

1 Like

Wow, looks much better!
I didn’t know about this tool.
Need some time to explore it.