How to show arrows symmetrically for self-loops in a dot graph - dot

I am working with a DFA which I have described in the dot file format. One of the nodes in my DFA has two self-loops, which I originally described with the following way
digraph {
rankdir=LR;
a -> a [color=blue]
a -> a [color=green]
}
Which produces this output when I run dot graph.gv -Tpng
For symmetry reasons, I'd like to have the blue and the green arrows on opposite sides of the node. I can modify the headport and tailport of the green arrow to force it to start from the bottom of the node as follows:
digraph {
rankdir=LR;
a -> a [color=blue]
a:sw -> a:se [color=green]
}
Unfortunately, that produces an absolutely wonky output:
What's the correct way of getting the two arrows to be symmetrically opposite each other on the node?

I doubt you have a lot of control over the edge layout. But you can experiment with the headport attribute values. Here are some examples.
Example 1
digraph {
rankdir=LR;
a:n -> a [color=blue]
a:s -> a [color=green headport=center]
}
View in editor
Example 2
digraph {
rankdir=LR;
a:ne -> a [color=blue]
a:sw -> a [color=green headport=center]
}
View in editor
Other layouts
You can also experiment with different layouts. Here are some options for the circo layout.
Example 3
digraph {
rankdir=LR;
layout="circo"
a:n -> a:_ [color=blue headport=n]
a:s -> a:_ [color=green headport=s dir=back]
}
View in editor
Example 4
digraph {
rankdir=LR;
layout="circo"
a:nw -> a:w [color=blue headport=_]
a:se -> a:e [color=green headport=_]
}
View in editor

Related

How to get visible nodes with Visjs

I have this large network created with vis-network:
When clicking on the nodes I create clusters. For example if I click on the 2 green boxes the result is:
In this new view I have two regular nodes ("Program #3289" and "Task #7300") and two clusters ("Project #3415" and "Project #3416") that contain their children.
If I use dataset.get() it returns all my 106 initial nodes.
If I use network.body.nodes it returns all my 106 initial nodes + my two clusters.
What I want: a way to only get the visible nodes in my network. In that case, I should get only 2 regular nodes and 2 clusters.
Did I miss a function that permits to do it?
Thank you
I finally came up with the below solution:
var visibleNodes = [];
for (var nodeId in visNetwork.body.nodes) {
// we check if the node is inside a cluster
if (!visNetwork.clustering.clusteredNodes[nodeId]) {
visibleNodes.push(nodeId)
}
}

Graphviz Composite Structure Diagram

Is it possible to generate with Graphviz / dot a UML composite structure diagram like the one below?
By using (open) box arrowheads https://graphviz.gitlab.io/doc/info/arrows.html, this gets pretty close:
digraph boxed {
graph [splines=ortho nodesep =.75]
node [shape=box]
edge [dir=both arrowtail=obox arrowhead=obox]
{ rank=same
x1 -> x2 -> x3
}
x1:s -> y1:n
}

Graphviz / dot label overlap with edge

I have a label that barely touch the edge, but there were plenty of space round it, is there anyway to make it not touching the edge in Graphiz? This is minor issue, but I have to redraw in powerpoint if cannot resolve by coding as my collaborator is very unhappy about this.. (Or I may export to JPEG and make changing in paintbrush)...
And we have to do this in black and white only so changing color would not help :(
minimal example: (the whole diagram is much more complex, and I have to put A E B in the same rank)
digraph "md" {
rankdir=TB;
size="8,8";
node [fontname="Helvetica" fontsize=10 shape=box];
edge [fontname="Helvetica" fontsize=10];
center=1;
{rank=min "A"}
{rank=min "B"}
{rank=min "E"}
"A" -> "B" [label="0.55***", dir=both];
"E" -> "B" [label="0.22" labeldistance="2"];
}
For the records - making the example minimal
digraph {
{ rank=same A -> B -> C }
A -> C [label=AC]
}
gives
using xlabel instead of label may help (but seems to have side effects)
digraph {
{ rank=same A -> B -> C }
A -> C [xlabel=AC]
}
gives

graphviz dot to pdf: distance from graph to title

in graphviz dot, generating pdf output.
how do I increase the distance between the title and the graph?
digraph "test" {
graph [ label="need more distance to below" ];
A -> B;
}
advice appreciated.
Not preferable solution but Append "\n" at the end of label. If you need more space add more "\n".

how to optimize layout in graphviz to remove unecessary edges intersections (crossings)?

I am preparing the automaitc documentation of DB relations. The tool is graphviz. Problem I have is that the placement of nodes on the output image is not opptimal and there are many unecessary intersection of edges.
Is there any method to perform optimazation of the graph so the result will have minumum edges intersetction (crossing)?
digraph structs {
node [shape=Mrecord];
overlap="false";
splines="true";
layout=sfdp;
rankdir=LR;
ttype[label="::: ttype :::|<id>id|<table_name>table_name|<type_name>type_name|<synopsis>synopsis"];
tevents[label="::: tevents :::|<id>id|<id_tcases>id_tcases|<id_ttype>id_ttype|<synopsis>synopsis|<expiredate>expiredate|<open>open"];
toperationlog[label="::: toperationlog :::|<id>id|<executiondate>executiondate|<executiontime>executiontime|<query>query|<id_tusers>id_tusers"];
tdocuments[label="::: tdocuments :::|<id>id|<id_tcases>id_tcases|<id_ttype>id_ttype|<path>path|<creationdate>creationdate"];
tcustomers_cases[label="::: tcustomers_cases :::|<id_tcustomers>id_tcustomers|<id_tcases>id_tcases"];
tcases[label="::: tcases :::|<id>id|<creationdate>creationdate|<incomingdate>incomingdate|<clousuredate>clousuredate|<synopsis>synopsis|<notes>notes|<id_ttype>id_ttype|<id_tusers>id_tusers"];
tusers[label="::: tusers :::|<id>id|<username>username|<password>password|<firstname>firstname|<lastname>lastname|<role_id>role_id"];
tcustomers[label="::: tcustomers :::|<id>id|<firstname>firstname|<lastname>lastname|<email>email|<phone>phone|<mobile>mobile|<address>address"];
tevents:id_tcases -> tcases:id [arrowhead="none"];
tevents:id_ttype -> ttype:id [arrowhead="none"];
toperationlog:id_tusers -> tusers:id [arrowhead="none"];
tdocuments:id_tcases -> tcases:id [arrowhead="none"];
tdocuments:id_ttype -> ttype:id [arrowhead="none"];
tcustomers_cases:id_tcustomers -> tcustomers:id [arrowhead="none"];
tcustomers_cases:id_tcases -> tcases:id [arrowhead="none"];
tcases:id_ttype -> ttype:id [arrowhead="none"];
tcases:id_tusers -> tusers:id [arrowhead="none"];
}
Setting remincross to true will cause cross minimization to run a second time, which should improve the look of the graph by reducing the number of edge crosses.

Resources