How to generate nodes with customized shape? - graphviz

HERE is a very good example that illustrates how to generate complex graphs using graphviz.
The dot file is listed here.
digraph G {
compound=true;
ranksep=1.25;
label="From Past to Future...";
node [shape=plaintext, fontsize=16];
bgcolor=white;
edge [arrowsize=1, color=black];
/* Nodes */
subgraph cluster_Computers {label="Computers"; labelloc="b"; Computers_icon};
Computers_icon [label="", shape=box, style=invis, shapefile="Computers.png"];
subgraph cluster_Semantic_Web {label="Semantic Web"; labelloc="b"; Semantic_Web_icon};
Semantic_Web_icon [label="", shape=box, style=invis, shapefile="Semantic_Web.png"];
subgraph cluster_Cryptography {label="Cryptography"; labelloc="b"; Cryptography_icon};
Cryptography_icon [label="", shape=box, style=invis, shapefile="Cryptography.png"];
subgraph cluster_Automata {label="Automata"; labelloc="b"; Automata_icon};
Automata_icon [label="", shape=box, style=invis, shapefile="Automata.png"];
subgraph cluster_AI {label="A.I."; labelloc="b"; AI_icon};
AI_icon [label="", shape=box, style=invis, shapefile="AI.png"];
subgraph cluster_Chaos {label="Chaos / Fractals"; labelloc="b"; Chaos_icon};
Chaos_icon [label="", shape=box, style=invis, shapefile="Chaos.png"];
subgraph cluster_XML {label="XML / RDF / URI"; labelloc="b"; XML_icon};
XML_icon [label="", shape=box, style=invis, shapefile="XML.png"];
subgraph cluster_Ontology {label="Ontology / Clustering"; labelloc="b"; Ontology_icon};
Ontology_icon [label="", shape=box, style=invis, shapefile="Ontology.png"];
subgraph cluster_Biology {label="Biology / Neurons"; labelloc="b"; Biology_icon};
Biology_icon [label="", shape=box, style=invis, shapefile="Biology.png"];
subgraph cluster_Agents {label="Agents / Security"; labelloc="b"; Agents_icon};
Agents_icon [label="", shape=box, style=invis, shapefile="Agents.png"];
subgraph cluster_Small_World {label="The Small World Project"; labelloc="b"; Small_World_icon};
Small_World_icon [label="", shape=box, style=invis, shapefile="Small_World.png"];
subgraph cluster_Social_Networks {label="Social Networks"; labelloc="b"; Social_Networks_icon};
Social_Networks_icon [label="", shape=box, style=invis, shapefile="Social_Networks.png"];
subgraph cluster_Search_Engines {label="Search Engines"; labelloc="b"; Search_Engines_icon};
Search_Engines_icon [label="", shape=box, style=invis, shapefile="Search_Engines.png"];
subgraph cluster_Turing {label="A. Turing"; labelloc="b"; Turing_icon};
Turing_icon [label="", shape=box, style=invis, shapefile="Turing.png"];
subgraph cluster_Rejewski {label="M. Rejewski"; labelloc="b"; Rejewski_icon};
Rejewski_icon [label="", shape=box, style=invis, shapefile="Rejewski.png"];
subgraph cluster_Dertouzos {label="M. Dertouzos"; labelloc="b"; Dertouzos_icon};
Dertouzos_icon [label="", shape=box, style=invis, shapefile="Dertouzos.png"];
subgraph cluster_Berners_Lee {label="T. Berners-Lee"; labelloc="b"; Berners_Lee_icon};
Berners_Lee_icon [label="", shape=box, style=invis, shapefile="Berners_Lee.png"];
/* Relationships */
Computers_icon -> Semantic_Web_icon;
Semantic_Web_icon -> Computers_icon;
Cryptography_icon -> Semantic_Web_icon;
Cryptography_icon -> Computers_icon;
Automata_icon -> Computers_icon;
AI_icon -> Automata_icon;
Automata_icon -> AI_icon;
Chaos_icon -> Computers_icon;
Chaos_icon -> AI_icon;
AI_icon -> Chaos_icon;
Computers_icon -> Chaos_icon;
XML_icon -> Semantic_Web_icon;
XML_icon -> Computers_icon;
Computers_icon -> XML_icon;
Ontology_icon -> Semantic_Web_icon;
Biology_icon -> AI_icon;
Biology_icon -> Chaos_icon;
Chaos_icon -> Biology_icon;
Chaos_icon -> Semantic_Web_icon;
Agents_icon -> Semantic_Web_icon;
Semantic_Web_icon -> Agents_icon;
Agents_icon -> AI_icon;
AI_icon -> Agents_icon;
Small_World_icon -> Chaos_icon;
Small_World_icon -> Agents_icon;
Small_World_icon -> Biology_icon;
Biology_icon -> Small_World_icon;
Social_Networks_icon -> Small_World_icon;
Social_Networks_icon -> Biology_icon;
Search_Engines_icon -> Semantic_Web_icon;
Computers_icon -> Search_Engines_icon;
Turing_icon -> Cryptography_icon;
Turing_icon -> Computers_icon;
Turing_icon -> Automata_icon;
Rejewski_icon -> Turing_icon;
Rejewski_icon -> Cryptography_icon;
Dertouzos_icon -> Computers_icon;
Dertouzos_icon -> Berners_Lee_icon;
Berners_Lee_icon -> Semantic_Web_icon;
{ rank=same; Rejewski_icon; Turing_icon; Dertouzos_icon; Berners_Lee_icon };
{ rank=same; Biology_icon; AI_icon; Social_Networks_icon };
}
I run dot -Tpng -ofrom-past-to-future.png from-past-to-future.dot with warnings
C:\dot>dot -Tpng -ofrom-past-to-future.png from-past-to-future.dot
Warning: AI_icon was already in a rankset, deleted from cluster G
Warning: Biology_icon was already in a rankset, deleted from cluster G
Warning: Social_Networks_icon was already in a rankset, deleted from cluster G
Warning: Turing_icon was already in a rankset, deleted from cluster G
Warning: Rejewski_icon was already in a rankset, deleted from cluster G
Warning: Dertouzos_icon was already in a rankset, deleted from cluster G
Warning: Berners_Lee_icon was already in a rankset, deleted from cluster G
I tried to modify the dot file but could not get the same png image as the original post.
How to approach it?

Here's a modified script which works with current versions of graphviz. Please note that you'll need to have all the images in the same directory as the script.
Changes I made:
Cleaned up redundant attribute declarations (label="", labelloc, etc.)
Used the image attribute instead of the old shapefile
Removed shape=box and style=invis from the nodes
Added penwidth=0 to get rid of the cluster border
Put the graph label at the bottom (should always be at the bottom)
Commented out the rank constraints. The same nodes cannot be part of different subgraphs.
This will not reproduce exactly the same graph, of course. Recreating the rank constraints will need some more creativity, mainly because each node is packed into its own cluster in order to attach a label to it... very hacky. You may try the same without clusters, but with the new xlabel attribute.
I added a second version, in which I uncommented the rank=same subgraphs and placed them before the definition of the clusters. Graphviz will then create an output, but without any labels for those nodes.
Here's the script:
digraph G {
compound=true;
ranksep=1.25;
node [shape=plaintext, fontsize=16, label=""];
bgcolor=white;
edge [arrowsize=1, color=black];
graph[penwidth=0, labelloc="b"];
/* Nodes */
//{ rank=same; Rejewski_icon; Turing_icon; Dertouzos_icon; Berners_Lee_icon };
//{ rank=same; Biology_icon; AI_icon; Social_Networks_icon };
subgraph cluster_Computers {label="Computers"; Computers_icon[image="Computers.png"];};
subgraph cluster_Semantic_Web {label="Semantic Web"; Semantic_Web_icon[image="Semantic_Web.png"];};
subgraph cluster_Cryptography {label="Cryptography"; Cryptography_icon[image="Cryptography.png"];};
subgraph cluster_Automata {label="Automata"; Automata_icon[image="Automata.png"];};
subgraph cluster_AI {label="A.I."; AI_icon[image="AI.png"];};
subgraph cluster_Chaos {label="Chaos / Fractals"; Chaos_icon[image="Chaos.png"];};
subgraph cluster_XML {label="XML / RDF / URI"; XML_icon[image="XML.png"];};
subgraph cluster_Ontology {label="Ontology / Clustering"; Ontology_icon[image="Ontology.png"];};
subgraph cluster_Biology {label="Biology / Neurons"; Biology_icon[image="Biology.png"];};
subgraph cluster_Agents {label="Agents / Security"; Agents_icon[image="Agents.png"];};
subgraph cluster_Small_World {label="The Small World Project"; Small_World_icon[image="Small_World.png"];};
subgraph cluster_Social_Networks {label="Social Networks"; Social_Networks_icon[image="Social_Networks.png"];};
subgraph cluster_Search_Engines {label="Search Engines"; Search_Engines_icon[image="Search_Engines.png"];};
subgraph cluster_Turing {label="A. Turing"; Turing_icon[image="Turing.png"];};
subgraph cluster_Rejewski {label="M. Rejewski"; Rejewski_icon[image="Rejewski.png"];};
subgraph cluster_Dertouzos {label="M. Dertouzos"; Dertouzos_icon[image="Dertouzos.png"];};
subgraph cluster_Berners_Lee {label="T. Berners-Lee"; Berners_Lee_icon[image="Berners_Lee.png"];};
/* Relationships */
Agents_icon -> {AI_icon Semantic_Web_icon};
AI_icon -> {Agents_icon Automata_icon Chaos_icon};
Automata_icon -> {AI_icon Computers_icon};
Berners_Lee_icon -> Semantic_Web_icon;
Biology_icon -> {AI_icon Chaos_icon Small_World_icon};
Chaos_icon -> {AI_icon Biology_icon Computers_icon Semantic_Web_icon};
Computers_icon -> {Chaos_icon Search_Engines_icon Semantic_Web_icon XML_icon};
Cryptography_icon -> {Computers_icon Semantic_Web_icon};
Dertouzos_icon -> {Berners_Lee_icon Computers_icon};
Ontology_icon -> Semantic_Web_icon;
Rejewski_icon -> {Cryptography_icon Turing_icon};
Search_Engines_icon -> Semantic_Web_icon;
Semantic_Web_icon -> {Agents_icon Computers_icon};
Small_World_icon -> {Agents_icon Biology_icon Chaos_icon};
Social_Networks_icon -> {Biology_icon Small_World_icon};
Turing_icon -> {Automata_icon Computers_icon Cryptography_icon};
XML_icon -> {Computers_icon Semantic_Web_icon};
fontsize=28;
label="From Past to Future...";
}
And that's what it looks like:
Second variant, with rank=same subgraphs uncommented:

Related

DOT graph from superstate to substate

I'd like to generate the DOT code to draw the equivalent state machine diagram shown.
I going to be created programmatically, I've got the transitions between states and superstates done. ButI need a bit of help with this:
This gives me an initial transition, but the State1 should be the cluster:
digraph {
compound=true;
node [shape=Mrecord]
rankdir="LR"
subgraph clusterOpen
{
label = "State1"
State2
}
State1 -> State2 [style="solid"];
node [shape = point label="" ] i ->State1
}
Normally Graphviz programs try hard to avoid placing nodes on top of other nodes. But you can place nodes anywhere you like if you explicitly provide a pos attribute for each node (see https://graphviz.org/faq/#FaqDotWithNodeCoords).
The program that creates your input files should calculate a pos attribute for each node. (Remember that pos coordinates are in points, while node sizes are in inches!). You can probably skip calculating the splines for the edges and just let neato do that.
This program:
digraph {
graph [bb="0,0,482.8,337"];
node [label="\N"];
State1 [height=4.0139,
label="{State 1|\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n}",
pos="162,144.5",
shape=Mrecord,
width=4.5];
State2 [height=1.3333,
label="{State 2|\n\n\n\n}",
// pos="403,144.5",
pos="220,88",
shape=Mrecord,
width=1.6944];
xp3 [height=0.05,
label="",
// pos="429,331",
pos="0,194",
shape=point,
// style=dotted,
style=invis,
width=0.05];
r1 [height=0.16667,
label="",
// pos="455,331",
pos="154,194",
shape=square,
width=0.16667];
xp4 [height=0.05,
label="",
// pos="481,331",
pos="0,88",
shape=point,
// style=dotted,
style=invis,
width=0.05];
xp1 [height=0.16,
label="",
pos="162,331",
shape=point,
width=0.16];
xp1 -> State1:n [pos="e,162,288.5 162,325.23 162,319.09 162,308.89 162,298.63",
style=dashed];
xp2 [height=0.16,
label="",
// pos="403,331",
pos="220,194",
shape=point,
width=0.16];
xp2 -> State2:n [pos="e,403,192.5 403,325.19 403,307.39 403,251.8 403,202.57"];
// manually added:
xp3 -> r1 [label="Trigger 1" dir=none ]
xp4 -> State2 [label="Trigger 2" ]
}
Run with this command line:
neato -n -Tpng stateDiagram.dot >stateDiagram.png
Produces this graph:

How to make node relative order fixed in graphviz?

I'm trying to draw a neural network in graphviz. Here is what my picture currently looks like:
As you can see, the order of the labels of the nodes don't appear correctly. For instance, I want $a_0^(2)$ sticks to the top of layer 2 and I want to arrange the rest of nodes in the same layer with numerical increasing order (i.e $a_1^(2)$, $a_2^(2)$, ...)
How can I do this? Much thanks!
Here is my code:
digraph G {
rankdir=LR;
splines=line;
nodesep=".05";
edge [comment="Wildcard node added automatic in EG."];
node [label=""];
subgraph cluster_0 {
color=white;
label="layer 1 (input layer)";
edge [comment="Wildcard node added automatic in EG."];
node [color=chartreuse,
style=filled,
shape=circle];
x0 [color=yellow,
fillcolor=yellow,
label=<x<sub>0</sub>>];
x1 [fillcolor=chartreuse,
label=<x<sub>1</sub>>];
x2 [fillcolor=chartreuse,
label=<x<sub>2</sub>>];
x3 [fillcolor=chartreuse,
label=<x<sub>3</sub>>];
}
subgraph cluster_1 {
color=white;
label="layer 2 (hidden layer)";
edge [comment="Wildcard node added automatic in EG."];
node [color=dodgerblue,
style=filled,
shape=circle];
a02 [color=yellow,
label=<a<sub>0</sub><sup>(2)</sup>>,
pos="0,0",
fillcolor=yellow];
a12 [label=<a<sub>1</sub><sup>(2)</sup>>,
pos="0,-1",
fillcolor=dodgerblue];
a22 [label=<a<sub>2</sub><sup>(2)</sup>>,
pos="0,-2",
fillcolor=dodgerblue];
a32 [label=<a<sub>3</sub><sup>(2)</sup>>,
pos="0,-3",
fillcolor=dodgerblue];
a42 [label=<a<sub>4</sub><sup>(2)</sup>>,
pos="0,-4",
fillcolor=dodgerblue];
a52 [label=<a<sub>5</sub><sup>(2)</sup>>,
pos="0,-5",
fillcolor=dodgerblue];
}
subgraph cluster_2 {
color=white;
label="layer 3 (hidden layer)";
edge [comment="Wildcard node added automatic in EG."];
node [color=dodgerblue,
style=filled,
shape=circle];
a03 [color=yellow,
fillcolor=yellow,
label=<a<sub>0</sub><sup>(3)</sup>>];
a13 [fillcolor=dodgerblue,
label=<a<sub>1</sub><sup>(3)</sup>>];
a23 [fillcolor=dodgerblue,
label=<a<sub>2</sub><sup>(3)</sup>>];
a33 [fillcolor=dodgerblue,
label=<a<sub>3</sub><sup>(3)</sup>>];
a43 [fillcolor=dodgerblue,
label=<a<sub>4</sub><sup>(3)</sup>>];
a53 [fillcolor=dodgerblue,
label=<a<sub>5</sub><sup>(3)</sup>>];
}
subgraph cluster_3 {
color=white;
label="layer 4 (output layer)";
edge [comment="Wildcard node added automatic in EG."];
node [color=coral1,
style=filled,
shape=circle];
O1 [fillcolor=coral1,
label=<a<sub>1</sub><sup>(4)</sup>>];
O2 [fillcolor=coral1,
label=<a<sub>2</sub><sup>(4)</sup>>];
O3 [fillcolor=coral1,
label=<a<sub>3</sub><sup>(4)</sup>>];
O4 [fillcolor=coral1,
label=<a<sub>4</sub><sup>(4)</sup>>];
}
x0 -> a12;
x0 -> a22;
x0 -> a32;
x0 -> a42;
x0 -> a52;
x1 -> a12;
x1 -> a22;
x1 -> a32;
x1 -> a42;
x1 -> a52;
x2 -> a12;
x2 -> a22;
x2 -> a32;
x2 -> a42;
x2 -> a52;
x3 -> a12;
x3 -> a22;
x3 -> a32;
x3 -> a42;
x3 -> a52;
a02 -> a13;
a02 -> a23;
a02 -> a33;
a02 -> a43;
a02 -> a53;
a12 -> a13;
a12 -> a23;
a12 -> a33;
a12 -> a43;
a12 -> a53;
a22 -> a13;
a22 -> a23;
a22 -> a33;
a22 -> a43;
a22 -> a53;
a32 -> a13;
a32 -> a23;
a32 -> a33;
a32 -> a43;
a32 -> a53;
a42 -> a13;
a42 -> a23;
a42 -> a33;
a42 -> a43;
a42 -> a53;
a52 -> a13;
a52 -> a23;
a52 -> a33;
a52 -> a43;
a52 -> a53;
a03 -> O1;
a13 -> O1;
a23 -> O1;
a33 -> O1;
a43 -> O1;
a53 -> O1;
a03 -> O2;
a13 -> O2;
a23 -> O2;
a33 -> O2;
a43 -> O2;
a53 -> O2;
a03 -> O3;
a13 -> O3;
a23 -> O3;
a33 -> O3;
a43 -> O3;
a53 -> O3;
a03 -> O4;
a13 -> O4;
a23 -> O4;
a33 -> O4;
a43 -> O4;
a53 -> O4;
}
I don't think changing the labels is a good solution.
If the ordering of the nodes within each layer is important, I suggest adding invisible edges within each layer, forcing the order of the nodes.
Something like this:
digraph G {
rankdir = LR;
splines=false;
edge[style=invis];
ranksep= 1.4;
{
rank=same;
x0->x1->x2->x3;
}
{
rank=same;
a0->a1->a2->a3->a4;
}
{
rank=same;
b0->b1->b2->b3->b4;
}
{
rank=same;
c0->c1->c2->c3;
}
edge[style=solid, tailport=e, headport=w];
{x0; x1; x2; x3} -> {a0;a1;a2;a3;a4};
{a0;a1;a2;a3;a4} -> {b0;b1;b2;b3;b4};
{b0;b1;b2;b3;b4} -> {c0,c1,c2,c3};
}
So, I use some dirty tricks to get the following picture:
I connect all the nodes together with the following code like the following:
x0 -> a02 [style=invisible, dir=none];
I relabel the nodes text according to each nodes position displayed in the picture (this is the really dirty one)
So, my complete code is available at here.
Please let me know if there is any better solution to this issue.

Can I have different font style/sizes in the same graphviz record?

I have the following simple graph and I want to have only the text GetArea() in italics. Is this possible?
digraph {
rankdir = BT;
node [shape=record];
cPolygon [label="{cPolygon|GetArea()}"];
{rank=same; cSquare cTriangle}
cSquare -> cPolygon;
cTriangle -> cPolygon;
}
I think you should use HTML like labels:
digraph {
rankdir = BT;
node [shape=record];
cPolygon [label=<<table border="0"><tr><td>cPolygon</td></tr><tr><td><i>GetArea()</i></td></tr></table>>];
{rank=same; cSquare cTriangle}
cSquare -> cPolygon;
cTriangle -> cPolygon;
}
yields
edit
a horizontal row:
...
cPolygon [label=<<table border="0"><tr><td>cPolygon</td></tr><hr/><tr><td><i>GetArea()</i></td></tr></table>>];
...

V-model with graphviz

I want to draw a V-Modell for software development. I want to use graphviz to keep it more maintainable than in Visio.
How can I get the typical V-structure in Graphviz?
I think I need horizontal and vertical alignment.
I tried to work with dummy-nodes but the layout is still poor.
This code works for me. It has a bit of a workaround in it to create the V shape. I use an invisible node and invisible edges to create a wedge between the 2 sides of the V-model.
digraph Vmodel {
// Transparent background
graph [bgcolor=none]
// Node style
node [
shape=record
style="rounded, filled"
width=2.5
height=0.8
fillcolor=white
];
// Create the nodes
user_req_models [label="User\nRequirements\nModels"]
sys_req_models [label="System\nRequirements\Models"]
arch_models [label="Architectural\Models"]
comp_design_models [label="Component\Design\Models"]
unit_design_models [label="Unit\nDesign\nModels"]
units [label="Units\n(SW, HW and Data)"]
components [label="Components\n(SW, HW and Data)"]
subsystems [label="Subsystems"]
integrated_system [label="Integrated System"]
operational_system [label="Operational System"]
// Create a hidden node to form a V-shaped wedge
hidden [style="invis"]
// Create the basic layout of the V model
user_req_models->sys_req_models
sys_req_models->arch_models
arch_models->comp_design_models
comp_design_models->unit_design_models
unit_design_models->units
units->components
components->subsystems
subsystems->integrated_system
integrated_system->operational_system
// Create the dashed edges
user_req_models->operational_system [style="dashed", constraint=false]
sys_req_models->integrated_system [style="dashed", constraint=false]
arch_models->subsystems [style="dashed", constraint=false]
comp_design_models->components [style="dashed", constraint=false]
// Create a wedge between the two parts
hidden->user_req_models [style="invis"]
hidden->sys_req_models [style="invis"]
hidden->arch_models [style="invis"]
hidden->comp_design_models [style="invis"]
hidden->operational_system [style="invis"]
hidden->integrated_system [style="invis"]
hidden->subsystems [style="invis"]
hidden->components [style="invis"]
hidden->unit_design_models [style="invis"]
hidden->units [style="invis"]
// Ranking on the same level
{rank=same; user_req_models, operational_system}
{rank=same; sys_req_models, integrated_system}
{rank=same; arch_models, subsystems}
{rank=same; comp_design_models, components}
{rank=same; unit_design_models, units}
}
I have used the following graph for requirements and tests specified in DO-178C.
digraph V_Cycle {
ranksep=0.3;
graph [fontname = "Handlee"];
node [fontname = "Handlee"];
edge [fontname = "Handlee"];
bgcolor=transparent;
/* ==== NODES === */
// Create hidden nodes to lower derived req
hid_sys_hl [style="invis"];
hid_hl_ll [style="invis"];
hid_ll_code [style="invis"];
hid_sr_hsi[style="invis"];
hid_req_tests[style="invis"];
// Requirements
node [color="#FFB71B", shape=note];
sys_req[label="System Requirements"];
hlr[label="High-Level\nSW Requirements"];
d_hlr[label="Derived\nHigh-Level Req.", style="dashed"];
llr[label="Low-Level\nSW Requirements"];
d_llr[label="Derived\nLow-Level Req.", style="dashed"];
// Code
node [color="#FFB71B", shape=component];
code;
// Tests
node [color="#000000", shape=box];
hsi_tests[label="Hardware/Software\nIntegration Tests"];
si_tests[label="Software\nIntegration Tests"];
ll_tests[label="Low-Level\n(Unit) Tests"];
/* ==== EDEGES === */
// Hidden to create intermediate level for derived req
hlr:sw -> hid_hl_ll:ne -> llr:sw[style="invis"];
llr:sw -> hid_ll_code:ne -> code:w[style="invis"];
{rank=same; d_hlr, hid_hl_ll}
{rank=same; d_llr, hid_ll_code}
// Requirements
edge[splines="ortho"];
sys_req:s -> hlr:w[weight=10];
hlr:s -> llr:w[weight=10];
hlr:s -> d_hlr:w[splines="spline",style="dashed", weight=5];
llr:s -> code:w[weight=10];
llr:s -> d_llr:w[splines="spline",style="dashed", weight=5];
// Tests
hsi_tests:s -> si_tests:e[dir="back", weight=10];
si_tests:s -> ll_tests:e[dir="back", weight=10];
// REQ & CODE -- TESTS
edge[splines="spline",color="#C89211", dir="back"];
{rank=same; hid_sys_hl, hid_sr_hsi}
hid_sys_hl -> hid_sr_hsi -> hsi_tests[style="invis"];
{rank=same; d_hlr, hid_req_tests}
llr -> d_hlr -> hid_req_tests -> ll_tests[style="invis"];
{rank=same; sys_req, hsi_tests}
sys_req -> hsi_tests;
{rank=same; hlr, si_tests}
hlr -> si_tests;
d_hlr:ne -> si_tests:sw;
{rank=same; llr, ll_tests}
llr -> ll_tests;
d_llr:ne -> ll_tests:s;
}
When using https://sketchviz.com/, the rendering is the following:

Graphviz crossing edges

I am trying to avoid the crossing of the lines between 20->40 and 30->70. Does anyone know how to do this? I am using single points to straighten out the edges but I would have expected the rendering engine to avoid these edges to overlap. Here is my dot code:
digraph {
graph [splines="ortho", nodesep = "1", overlap = false];
node [shape=rectangle, color=lightgrey, style=filled ];
10
20
30
40
50
60
70
80
90
node[shape=none, width=0, height=0 label=""];
edge[dir=none];
{rank=same;
p1->10
10->p2
}
p1->20
p2->30
{rank=same;
p3->40
40->p4
}
p3->50
p4->60
{rank=same;
p5->70
70->p6
}
p5->80
p6->90
20->40
30->70
}
I wanted to post an image, but stackoverflow does not allow me to do this... You can see what I mean when you copy the code into: http://stamm-wilbrandt.de/GraphvizFiddle/
I really appreciate your help on this!
You could give graphviz a hint by adding an invisible edge between p4 an dp5:
{
rank=same;
p3 -> 40;
40 -> p4;
p4 -> p5 [style=invis]; // new invisible edge
p5 -> 70;
70 -> p6;
}
If you are not able to add invisible edges (dynamic graph generation), make sure nodes which are part of a subgraph do appear first within the subgraph, and therefore avoid upfront node definitions.
In this example, I removed the node definitions in the beginning of the script and inlined the style of the elbow-joint nodes.
Here's the GraphvizFiddle
digraph {
graph [splines="ortho", nodesep = "1", overlap = false];
node [shape=rectangle, color=lightgrey, style=filled ];
//node[shape=none, width=0, height=0, label=""];
edge[dir=none];
{
rank=same;
p1[shape=none, width=0, height=0, label=""];
p2[shape=none, width=0, height=0, label=""];
p1->10
10->p2
}
p1->20
p2->30
{
rank=same;
p3[shape=none, width=0, height=0, label=""];
p4[shape=none, width=0, height=0, label=""];
p3->40
40->p4
}
p3->50
p4->60
{
rank=same;
p5[shape=none, width=0, height=0, label=""];
p6[shape=none, width=0, height=0, label=""];
p5->70
70->p6
}
p5->80
p6->90
20->40
30->70
}

Resources