Recommend better way to show data graphically

[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