self loop edges too short and ugly in graphviz - graphviz

I drawed a picture using graphviz. Please see FSM.
I think It is ugly because self loop edges are so short.
The attribute "minlen" of edges doesn't work for me.
And I tried several ports of the node, but it all shows a mess except my current implementation. Do you have a clever idea for me ?
Code is here:
digraph finite_state_machine {
rankdir=LR;
size="8,2"
fontname="Verdana"
node [shape = doublecircle]; Idle;
node [shape = circle,nodesep = "2.0"];
Working:s -> Working:s [ label = "response[j]?" ,minlen = 50000];
Idle -> Working [ label = "boot" ];
Working:n -> Working:n [ label = "sendtx[i]!",minlen = 50000 ];
Working:e -> Working:e [ label = "qry!" ,minlen = 50000];
}

Adding nodesep=1; makes loops larger, although not nicer. So this would help:
digraph finite_state_machine {
rankdir=LR;
size="8,2"
fontname="Verdana"
node [shape = doublecircle]; Idle;
node [shape = circle,nodesep = "2.0"];
Working:s -> Working:s [ label = "response[j]?" ,minlen = 50000];
Idle -> Working [ label = "boot" ];
Working:n -> Working:n [ label = "sendtx[i]!" ];
Working:e -> Working:e [ label = "qry!"];
nodesep=1;
}
Will produce something like:
Dot Output

Related

Align nodes in a Graphviz directed graph

I have the following Graphviz code:
digraph {
Technique [shape = box];
Path [shape = box];
KnowledgeObservation [shape = box, label = "Knowledge\nObservation"];
ManagementIntervention [shape = box, label = "Management\nIntervention"];
ResultsModification [shape = box, label = "Results\nModification"];
SharedCode [label = "Shared Code"];
MediatedRelationship [label = "Mediated Relationship"];
Art -> Technique;
Therapy -> Path;
{Technique Path} -> KnowledgeObservation -> ManagementIntervention -> ResultsModification;
{MediatedRelationship SharedCode} -> {KnowledgeObservation ResultsModification}
subgraph {
rank = same
Technique -> Path [dir = none]
}
subgraph {
rank = same
SharedCode
ManagementIntervention
MediatedRelationship
}
}
It currently produces the following output:
How can I vertically align "Management Intervention" with both "Knowledge Observation" and "Results Modification"?
"Shared Code" should be moved to the left of "Management Intervention".
"Mediated Relationship" should be moved to the right of "Management Intervention".
"Shared Code", "Management Intervention" and "Mediated Relationship" should stay horizontally aligned.
How can I accomplish this?
This can be achieved without subgraphs; the most important modification is the line
{ rank = same; SharedCode -> ManagementIntervention -> MediatedRelationship[ style = invis ] }
which keeps the three nodes not only on the right level, but also within the desired order.
Altogether, this code here
digraph
{
// node definition
Art Therapy;
Technique[ shape = box ];
Path[ shape = box ];
KnowledgeObservation[ shape = box, label = "Knowledge\nObservation" ];
ManagementIntervention[ shape = box, label = "Management\nIntervention" ];
ResultsModification[ shape = box, label = "Results\nModification" ];
SharedCode[ label = "Shared Code" ];
MediatedRelationship[ label = "Mediated Relationship" ];
// edges
Art -> Technique;
Therapy -> Path;
{ rank = same; Technique -> Path [dir = none] }
{ Technique Path} -> KnowledgeObservation -> ManagementIntervention -> ResultsModification;
{ rank = same; SharedCode -> ManagementIntervention -> MediatedRelationship[ style = invis ] }
{ MediatedRelationship SharedCode } -> { KnowledgeObservation ResultsModification }
}
gives you
which is, in my understanding, what you are looking for.
Still I would recommend to replace the last line of code with these three
KnowledgeObservation -> { SharedCode MediatedRelationship }[ dir = back ];
SharedCode -> ResultsModification;
MediatedRelationship -> ResultsModification;
Reason is that once your graph gets more complicated, graphviz will recognize and maintain the hierarchical relationships, rather than interpreting ambiguous instructions in surprising ways.
How can I vertically align "Management Intervention" with both "Knowledge Observation" and "Results Modification"?
This can be achieved with increasing the weight of the edge. Edges with higher weight tend to be straighter and shorter than with the lower.
"Mediated Relationship" should be moved to the right of "Management Intervention".
You can control this with the order in which the nodes are defined. If you define "Management Intervention" before the "Shared Code", it (MI) will be drawn first, i. e., to the left of the SI.
"Shared Code", "Management Intervention" and "Mediated Relationship" should stay horizontally aligned.
You did it right, using the rank=same subgraph attribute. Though I would put the subgraph already in the moment of node definitions. This will shorten the source size and limit the rank specification to the place where the nodes are defined, which is good for readability (everything stated in one place).
Your modified example:
digraph {
Technique [shape = box];
Path [shape = box];
KnowledgeObservation [shape = box, label = "Knowledge\nObservation"];
ResultsModification [shape = box, label = "Results\nModification"];
subgraph {
rank=same
ManagementIntervention [shape = box, label = "Management\nIntervention"];
MediatedRelationship [label = "Mediated Relationship"];
SharedCode [label = "Shared Code"];
}
Art -> Technique;
Therapy -> Path;
{Technique Path} -> KnowledgeObservation
KnowledgeObservation -> ManagementIntervention -> ResultsModification [weight=3]
{MediatedRelationship SharedCode} -> {KnowledgeObservation ResultsModification}
subgraph {
rank = same
Technique -> Path [dir = none]
}
}
Result:

Center alignment of clusters when connecting them

I have a two clusters that are connected but I can't seem to align the left most cluster (with node nd_6) with the center of the other node (cluster_circ). Here is an example:
digraph d1 {
# configs
rankdir = "LR";
compound=true;
node [shape = plaintext];
edge [arrowhead = "vee"];
nd_1 [group = g1]
nd_2 [group = g1]
# cluster for circular pattern
subgraph cluster_circ {
color=none;
node [shape = plaintext];
nd_3 [group = g1]
{rank=same nd_4[group = g2]; nd_5[group = g3]};
nd_3 -> nd_4:nw;
nd_4 -> nd_5:ne;
nd_5 -> nd_3:se;
}
# right-most cluster
subgraph cluster_r {
color=none;
node [shape = plaintext];
nd_6 [group = g1];
}
# edge connections
nd_1 -> nd_2;
nd_2 -> nd_3;
# connect clusters
nd_5 -> nd_6 [ltail=cluster_circ lhead=cluster_r]
}
Producing the following result:
What I am trying to achieve is to place the node nd_6 and its respective edge connecting to cluster_circ aligned with nd_3.
Thanks!
You need to do two things to achieve your goal:
match your compass points
have an invisible edge from nd_4 that that moves nd_6 up.
Both items are explained in the comments of the source code below. In the course of editing, I have removed a lot of stuff that were not material in the context, for easier reading.
digraph d1
{
// configs // comment characters changed to "standard"
rankdir = "LR";
node [ shape = plaintext ];
edge [ arrowhead = "vee" ];
// nodes
nd_1 nd_2 nd_3;
{ rank=same; nd_4 nd_5 }
nd_6
// edges / connections
nd_1 -> nd_2 -> nd_3;
nd_3 -> nd_4:nw; // matching :s and :n keeps the center:
nd_4:se -> nd_5:ne; // balance nd_4:n with nd_4:s
nd_3 -> nd_5:sw[ dir = back ]; // balance nd_5:n with nd_5:s
nd_4 -> nd_6[ style = invis ]; // this gives you a counterweight
nd_5 -> nd_6; // to nd_5 and thus "centers" nd_6
}
yields
E D I T to show the alternative with an empty node.
This is the result I like best, I have inserted some lines where you could play around with alternative settings. To the best of my knowledge, groups or subgraphs don't help, as edges only go between nodes, not between clusters.
digraph d1
{
// configs // comment characters changed to "standard"
rankdir = "LR";
node [ shape = plaintext ];
edge [ arrowhead = "vee" ];
// nodes
nd_1 nd_2 nd_3;
x[ shape = point, height = 0 ]; // "empty" node
// x[ shape = point, height = .25, color = white ]; // alternative
{ rank = same; nd_4 nd_5 }
// { rank = same; nd_4 x nd_5 } // try also with x in the same rank
nd_6
// edges / connections
nd_1 -> nd_2 -> nd_3;
nd_3 -> nd_4:nw;
nd_4:e -> x:n[ dir = none ]; // route edge via x
x:s -> nd_5:e; // you can try other compass points
nd_3 -> nd_5:sw[ dir = back ]; // balance nd_4:n with nd_5:s
x -> nd_6; // connect the empty node in the middle
}
which produces

How can I make dot (graphviz) layout unconnected nodes vertically instead of horizontally?

I use pyreverse to create class diagrams from python code and this results in graphs like this:
as can be seen, some classes are not related. I would like to have the subgraphs laid out below each other so that I can include the image in a document.
Is there a simple way to modify a dot file so that disconnected parts of a graph are placed below each other?
Connect the disconnected parts with invisible edges:
digraph so
{
node[ shape = box ];
A[ label = "Message" ];
B[ label = "MetaMessage" ];
C[ label = "TrainingMessage" ];
D[ label = "MessageBundle" ];
A -> { B C };
{ B C } -> D[ style = invis ];
}
yields

Graphviz forcing nodes to stack vertically despite rankdir=LR

I am new to Graphviz and trying to layout some nodes from left to right with something like the following:
digraph g {
graph [ rankdir = "LR" ];
node [ fontsize = "16", fontname="Arial" ];
nodesep = 1.0;
ranksep = 4.0;
"node0" [
label = "<f0>OBJECT0| <f1> Id | <f2> Name"
shape = "record" ];
"node1" [
label = "<f0>OBJECT1| <f1> Id | <f2> Name"
shape = "record" ];
"node2" [
label = "<f0>OBJECT2| <f1> Id | <f2> Name"
shape = "record" ];
"node4" [
label = "<f0>OBJECT3| <f1> Id | <f2> Name"
shape = "record" ];
** I also have some connectors in here across the nodes **
}
This works ok for very basic nodes, but if I have say 100 rows within a node (representing a database table and fields) the nodes are stacked vertically and nothing I do seems to influence the damn things to revert back to a horizontal layout.
Any suggestions on how I might force the issue would be most appreciated - this one has me completely stuck!
Cheers
CH
Resolved - needed to add the line node0 -> node1 -> node2 -> node3 -> node4 [style=invis]

Why does Graphviz/Dot act so weirdly to this particular code?

I am using GraphViz 2.28 (the current stable version) on Windows 7, and Graphviz/Dot crashes for the following code.
digraph G {
ranksep = 1.0; size = "10,10";
{
node [shape = plaintext, fontsize = 20];
GAWM1 -> GAWM2 -> 0;
}
node [shape = box];
{rank = same;0;wx1;wx2;rx1;}
wx1 -> wx2;
wx2 -> rx1;
wx1 -> rx1[color = blue];
subgraph struct
{
node [shape = record];
rx11 [shape = record, label = "rx1 | [x=[wx2]]"];
}
{rank = same; GAWM1; "rx11";}
// W'WR Order:
wx2 -> wx1[style = dashed, color = red, label = "1"]; }
Things become weird when I perform some experiments on this example:
It works well when only the last statement "wx2 -> wx1[style = dashed, color = red, label = "1"];" is removed;
It works well when only the eighth line "{rank = same;0;wx1;wx2;rx1;}" is removed;
It also works well when only the label (that is ", label = "1"") in the last statement is removed.
I have reported the problem to Graphviz Issue Tracker, without reply yet. Could you help to find out the reason?
Thank you.
The following variation of your script does not crash:
digraph G {
ranksep = 1.0; size = "10,10";
{
node [shape = plaintext, fontsize = 20];
GAWM1 -> GAWM2 -> 0;
}
node [shape = box];
{rank = same;0;wx1;wx2;rx1;}
wx1 -> wx2;
wx2 -> rx1;
wx1 -> rx1[color = blue];
subgraph struct
{
node [shape = record];
rx11 [shape = record, label = "rx1 | [x=[wx2]]"];
}
{rank = same; GAWM1; "rx11";}
// W'WR Order:
//wx2 -> wx1[style = dashed, color = red, label = "1"];
wx2 -> wx1 [style=dashed, color=red];
}
Looks like a bug with the label of the short edge between wx1 and wx2.

Resources