Graphviz crossing edges - graphviz

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
}

Related

How do you remove margin/padding from a GraphViz node using an image?

I am using GraphViz with user defined shapes for nodes using the image tag. The images are png files, and contain lines to the edge of the image to link up with edges drawn by GraphViz. But if I try to make a rudimentary graph using neato with a defined layout, you can still see some margin or padding between the images and the graph edges that show up as small gaps in the lines. There is no border in the images themselves. (I also need to re-center some of the images.) How does one remove the gaps?
Here is my .dot, with several attempts inspired by other answers, but nothing seems to remove the gaps.
graph G {
pad = 0.0;
a [ label="", pos="0,0", shape=none, width=0, height=0, image="LnLft.png" ];
b [ label="", pos="100,0", shape=none, width=0, height=0, image="BrkClsHrz.png", penwidth=0 ];
h1 [ label="", pos="200,0", shape=none, width=0, height=0 ];
c [ label="", pos="200,-100", shape=plaintext, width=0, height=0, image="BrkClsVrt.png", penwidth=0 ];
d [ label="", pos="200,-200", shape=plaintext, width=0, height=0, image="BrkOpnVrt.png" ];
h2 [ label="", pos="200,-300", shape=none, width=0, height=0 ];
e [ label="", pos="100,-300", shape=none, width=0, height=0, image="BrkClsHrz.png", margin="0,0"];
f [ label="", pos="0,-300", shape=none, width=0, height=0, image="LnLft.png" ];
a -- b [len=1.5, penwidth=2];
b -- h1 [len=1.5, penwidth=2];
h1 -- c [len=1.5, penwidth=2];
c -- d [len=1.5, penwidth=2];
d -- h2 [len=1.5, penwidth=2];
h2 -- e [len=1.5, penwidth=2];
e -- f [len=1.5, penwidth=2];
}
And here is the output:

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:

In Graphviz, how to layout subgraphs in different orientations?

There is rankdir for the global graph which sets the orientation of the layout. What about subgraph or cluster - is there a way to have one subgraph in TD layout and another subgraph in BT?
How to achieve the graph in the attached image with following (incorrect) code?
digraph G {
subgraph cluster0 {
rankdir="TD";
A; B;
A -> B;
}
subgraph cluster1 {
rankdir="BT"; // this doesn't produce the desired output
C; D;
D -> C;
}
}
You cannot do that, rankdir is only allowed at top level (graph)
but in simple cases you can work around it by
to go in opposite direction:
C->D[dir=back]
to go in to the side:
{rank=same C D}

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:

Resources