Search code examples
graphvizdot

How to make GraphViz ladder diagram flows straight


The graphviz code below generates a ladder diagram, but flow3 is curved. This only happens when the edge crosses a vertical line. How can I make flow3 straight and horizontal? I tried experimenting with the splines attribute with no success. How can the code be changed to force a straight line through other objects?

enter image description here

digraph ladder { ranksep=".1"; nodesep=".1";

# Define the defaults
  node [shape=point fontsize=10]
  edge [dir=none fontsize=10]

# Column labels
  a [shape=none]
  b [shape=none]
  c [shape=none]
  d [shape=none]

# Draw the 4 column headings, no line
  { rank=same; edge[style=invis] a -> b -> c -> d   }

# Draw the columns
  a -> a1 [style=invis]
  b -> b1 [style=invis]
  c -> c1 [style=invis]
  d -> d1 [style=invis]
  a1 -> a2 -> a3 -> a4 [weight=1000 label="   "]
  b1 -> b2 -> b3 -> b4 [weight=1000 label="   "]
  c1 -> c2 -> c3 -> c4 [weight=1000 label="   "]
  d1 -> d2 -> d3 -> d4 [weight=1000 label="   "]

# Now each step in the ladder
  { rank=same; a1 -> b1 [dir=forward label="Flow1"]  }
  { rank=same; b2 -> c2 [dir=forward label="Flow2"]  }
  { rank=same; b3 -> d3 [dir=forward label="Flow3"]  }
  { rank=same; c4 -> d4 [dir=back label="Flow4"]  }
}

EDIT with updates per comments.

Running GraphViz version 2.38.0.

The splines attribute changes the results slightly. Only the first line of code is changed, like this:

digraph ladder { ranksep=".1"; nodesep=".1"; splines=false;

With this result when splines are disabled:

enter image description here


Solution

  • Here is another possible solution. Also a hack. It involves splitting the curved flow into multiple smaller straight flows.

    Change this:

      { rank=same; b3 -> d3 [dir=forward label="Flow3"]  }
    

    To This:

      {
        rank=same;
        b3 -> c3 [dir=none]
        c3 -> d3 [dir=forward label="Flow3"]
      }
    

    Also made some other unrelated improvements to make the nodes invisible and the vertical edges dotted. So the complete code is this:

    digraph ladder { ranksep=".1"; nodesep=".1";
    
    # Define the defaults
      node [shape=point fontsize=10]
      edge [dir=none fontsize=10]
    
    # Column labels
      a [shape=none]
      b [shape=none]
      c [shape=none]
      d [shape=none]
    
    # Draw the 4 column headings, no line
      { rank=same; edge[style=invis] a -> b -> c -> d   }
    
    # Draw the columns
      node [style=invis]
      a -> a1 [style=invis]
      b -> b1 [style=invis]
      c -> c1 [style=invis]
      d -> d1 [style=invis]
      a1 -> a2 -> a3 -> a4 [style=dotted weight=1000 label="   "]
      b1 -> b2 -> b3 -> b4 [style=dotted weight=1000 label="   "]
      c1 -> c2 -> c3 -> c4 [style=dotted weight=1000 label="   "]
      d1 -> d2 -> d3 -> d4 [style=dotted weight=1000 label="   "]
    
    # Now each step in the ladder
      { rank=same; a1 -> b1 [dir=forward label="Flow1"]  }
      { rank=same; b2 -> c2 [dir=forward label="Flow2"]  }
      {
        rank=same;
        b3 -> c3 [dir=none]
        c3 -> d3 [dir=forward label="Flow3"]
      }
      { rank=same; c4 -> d4 [dir=back label="Flow4"]  }
    }
    

    And the resulting ladder diagram is this:

    enter image description here