Graphviz: route line from the left side of the node - graphviz

I am trying to create flow chart as shown in the image #2 (with the red lines) but I am not able to position the lines from the left side of the onset node to the left side of the sampling node. If :w or :s is added to the node, line is broken and goes from the inside of the node. Is it possible to route the lines like that and put the text to the side so it doesn't collide with the line?
digraph G {
graph [splines=ortho];//, nodesep=0.8]
node [shape=record]
sampling [
label = "Sampling";
shape = rect;
];
onset [
label = "Onset\ndetection";
shape = diamond;
];
collect [
label = "Collect 1024 samples";
shape = rect;
];
xcorr [
label = "Compute\ncross correlation";
shape = rect;
];
display [
label = "Display data";
shape = rect;
];
sampling->onset;
onset->sampling [label = "No"];
onset->collect [label = "Yes"];
collect->xcorr;
xcorr->display;
xcorr->sampling [ label = "Return"; ];
{
rank = same;
collect; xcorr;
}
}

Related

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

self loop edges too short and ugly in 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

How to adjust outer labels for nodes

I want to plot graph with some outer labels.
I found that there some helpful attributes - xlabel,taillabel,headlabel but the result still looks weird.
MCVE
digraph {
forcelabels=true;
node [shape=point,style=filled;label="",height=0.2];
y3[color=black;xlabel=<"y3 (2)">];x3[color=gray;xlabel=<"x3 [0.25]">];
y2[color=black;xlabel=<"y2 (3)">];x2[color=gray;xlabel=<"x2 [0.3]">];
y1[color=black;xlabel=<"y1 (2)">];x1[color=gray;xlabel=<"x1 [0.1]">];
y5[color=black;xlabel=<"y5 (4)">];x5[color=gray;xlabel=<"x5 [0.15]">];
x4[color=gray;xlabel=<"x4 [0.2]">];
y3->y2[dir=none;taillabel = 0.75];
y2->y1[dir=none;taillabel = 0.45];
y1->y5[dir=none;taillabel = 0.35];
y3->x3[dir=none];
y2->x2[dir=none];
y1->x1[dir=none];
y5->x5[dir=none];
y5->x4[dir=none];
}
it looks like
As you can see, conformity between labels and nodes not always obvious.
So, the Q is - is there any way to change location of labels ?
This may not be the answer to your question as it still does not look great and takes a lot of manual adjustment, but I post it anyway: I spent quite some time fiddling around, and there may be some ideas that could be helpful for your actual context:
digraph
{
forcelabels = TRUE;
splines = FALSE;
// nodes
node[ shape = point, style = filled, color = gray, label = "", height = 0.2 ];
x3[ xlabel = <"x3 [0.25]"> ];
x2[ xlabel = <"x2 [0.3]"> ];
x1[ xlabel = <"x1 [0.1]"> ];
x5[ xlabel = <"x5 [0.15]"> ];
x4;
node[ color = black ];
y3, y2, y1, y5;
node[ shape = plaintext, fillcolor = white ];
y_3[ label = "y3 (2)" ];
y_2[ label = "y2 (3)" ];
y_1[ label = "y1 (2)" ];
y_5[ label = "y5 (4)" ];
// edges
edge[ dir = none ];
y3:se -> y2[ label = " 0.75" ];
y2:se -> y1[ label = " 0.45" ];
y1:se -> y5[ label = " 0.35" ];
y3 -> x3;
y2 -> x2;
y1 -> x1;
y5 -> x5;
y5 -> x4[ headlabel = <"x4 [0.2]"> ];
edge[ style = invis ];
{ rank = same; y3 -> y_3 }
{ rank = same; y2 -> y_2 }
{ rank = same; y1 -> y_1 }
{ rank = same; y5 -> y_5 }
}
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]

head and tail labels overlap the arrow

In the following code, the head and tail labels overlap the arrow, which I do not want. What do I have to do?
digraph G {
node [shape = "record"];
edge [
arrowhead = "normal"
headlabel = "0..*"
taillabel = "longlabel"
];
N1 [ label="N1"];
N2 [label = "N2" ];
N1->N2;
}
You can't really control the position of head and tail-labels as it is possible for the edge label (using labelangle, labeldistance, etc.)
However, as a hack, you could add whitespace to the head/tail-label and that way force the center of the label to be on the left or right of the label text:
headlabel = " 0..*"
taillabel = "longlabel "

Resources