Graphviz connect nested subgraphs - syntax

Problem
Similarly to this question (GraphViz - How to connect subgraphs?) I would like to connect some sub-graphs. Only this time I need to connect nested sub-graphs... Graphviz seems unhappy with my syntax.
Source
digraph G {
compound=true
subgraph cluster_family1 {
graph [ label="Family1"; ]
subgraph cluster_genus1 {
graph [ label="Genus1"; ]
species_1
species_2
}
subgraph cluster_genus2 {
graph [ label="Genus2"; ]
species_3
species_4
}
}
subgraph cluster_family2 {
graph [ label="Family2"; ]
subgraph cluster_genus2 {
graph [ label="Genus3"; ]
species_5
species_6
}
}
species_2 -> species_3 [ lhead=cluster_genus1 ] # TODO: Fix this line!!
}
The resulting diagram does not have the desired subgraph arrow pointing that I was hoping for. Instead I get the error:
dot -Tsvg source.dot -o output.svg
Warning: Two clusters named cluster_genus2 - the second will be ignored
Warning: species_2 -> species_3: head not inside head cluster cluster_genus1

Two bugs:
duplicate cluster names: (cluster_genus2)
confused heads & tails of your edge
You may want other tweaks, e.g if you want species_1 before species_2
digraph G {
compound=true
subgraph cluster_family1 {
graph [ label="Family1"; ]
subgraph cluster_genus1 {
graph [ label="Genus1"; ]
species_1
species_2
}
subgraph cluster_genus2 {
graph [ label="Genus2"; ]
species_3
species_4
}
}
subgraph cluster_family2 {
graph [ label="Family2"; ]
subgraph cluster_genus3 { // fixed duplicate name
graph [ label="Genus3"; ]
species_5
species_6
}
}
species_2 -> species_3 [ ltail=cluster_genus1 ] # changed head to tail??
}
Giving:

Related

Graphiz - how to order subgraphs from top to bottom

I'm creating a switch topology with subgraphs.
How is below possible to re-organize so Bridge1 is on the top, Bridge2 is below, etc...
Thanks in advance!
I
It looks like your post is mostly code; please add some more details.
It looks like your post is mostly code; please add some more details.
It looks like your post is mostly code; please add some more details.
It looks like your post is mostly code; please add some more details.
It looks like your post is mostly code; please add some more details.
It looks like your post is mostly code; please add some more details.
It looks like your post is mostly code; please add some more details.
digraph G {
node [shape=box,style=filled];
newrank=True;
rankdir=TB;
subgraph cluster_1 {
label="Bridge1\n8001.5254aabbcce6";
rank=same;
rstp_1_1[label="port1\nD\n20000"];
rstp_1_2[label="port2\nR\n20000"];
rstp_1_3[label="port3\nD\n20000"];
rstp_1_4[label="port4\nD\n20000"];
}
subgraph cluster_2 {
label="Bridge2\n8001.5254aabbcca6";
rank=same;
rstp_2_1[label="port1\nD\n20000"];
rstp_2_2[label="port2\nD\n20000"];
rstp_2_3[label="port3\nD\n20000"];
rstp_2_4[label="port4\nR\n20000"];
}
subgraph cluster_3 {
label="Bridge3\n8001.5254aabbcc6c";
rank=same;
bgcolor=red;
rstp_3_1[label="port1\nD\n0"];
rstp_3_2[label="port2\nD\n0"];
rstp_3_3[label="port3\nD\n0"];
rstp_3_4[label="port4\nD\n0"];
}
subgraph cluster_4 {
label="Bridge4\n8001.5254aabbccba";
rank=same;
rstp_4_1[label="port1\nD\n20000"];
rstp_4_2[label="port2\nD\n20000"];
rstp_4_3[label="port3\nR\n20000"];
rstp_4_4[label="port4\nD\n20000"];
}
subgraph cluster_5 {
label="Bridge5\n8001.5254aabbccb2";
rank=same;
rstp_5_1[label="port1\nD\n20000"];
rstp_5_2[label="port2\nD\n20000"];
rstp_5_3[label="port3\nR\n20000"];
rstp_5_4[label="port4\nD\n20000"];
}
rstp_1_2 -> rstp_5_2 [arrowhead=none];
rstp_2_3 -> rstp_5_3 [arrowhead=none];
rstp_2_4 -> rstp_3_4 [arrowhead=none];
rstp_3_3 -> rstp_4_3 [arrowhead=none];
rstp_4_4 -> rstp_5_4 [arrowhead=none];
}
I have added below after rankdir=TB and it did the job:
rstp_1_1->rstp_2_1 [style=invis];
rstp_2_1->rstp_3_1 [style=invis];
rstp_3_1->rstp_4_1 [style=invis];
rstp_4_1->rstp_5_1 [style=invis];
rstp_5_1->rstp_6_1 [style=invis];
rstp_6_1->rstp_7_1 [style=invis];
rstp_7_1->rstp_8_1 [style=invis];
rstp_8_1->rstp_9_1 [style=invis];
rstp_9_1->rstp_10_1 [style=invis];

GraphQL on clause with enum type

I have a question regarding GraphQL because I do not know if it is possible or not.
I have a simple scheme like this:
enum Range{
D,
D_1,
D_7
}
type Data {
id: Int!
levels(range: [Range!]):[LevelEntry]
}
type LevelEntry{
range: Range!
levelData: LevelData
}
type LevelData {
range: Range!
users: Int
name: String
stairs: Int
money: Float
}
Basically I want to do a query so I can retrieve different attributes for the different entries on the levelData property of levels array which can be filtered by some levels range.
For instance:
data {
"id": 1,
"levels": [
{
"range": D,
"levelData": {
"range": D,
"users": 1
}
},
{
"range": D_1,
"levelData": {
"range": D_1,
"users": 1,
"name": "somename"
}
}
]
This means i want for D "range, users" properties and for D_1 "range,users,name" properties
I have done an example of query but I do not know if this is possible:
query data(range: [D,D_1]){
id,
levels {
range
... on D {
range,
users
}
... on D_1 {
range,
users,
name
}
}
}
Is it possible? If it is how can i do it?

Graphviz: Invert two nodes position inside a cluster

I am trying to inverse the position of two nodes (producción & funciones) that are inside a cluster (cluster_fp). Instead of producción on top and funciones at bottom, I need funciones on top and producción at bottom. How can I achieve that? They are in a cluster just because I thought it is the right approach, but probably it isn't. Because my reputation, I can't post images directly, so I leave the links to i.stack.imgur.com.
Code:
digraph tríada {
rankdir=LR;
edge [arrowhead=none];
label="* socialmente reconocido";
labeljust=left;
subgraph cluster_sinonimia_oa {
style=dashed;
label="sinonimia obra-texto";
subgraph cluster_texto {
style=striped;
label=texto;
selección [shape=rect];
}
obra [shape=rect, style=striped];
supuesto [label="supuesto\nexistencial", shape=plain];
}
subgraph cluster_autor {
style=striped;
label="autor*";
máquinas [shape=hexagon];
subgraph cluster_fp {
label="";
style=invis;
funciones [label="atribución o\napropiación", shape=plain];
producción [shape=plain];
}
subgraph cluster_sinonimia_nepa {
style=dashed;
label="sinonimia nombre-entidad-persona-autor";
personas [shape=hexagon];
entidad [shape=rect];
real [shape=diamond];
ficticia [shape=diamond];
nula [shape=diamond];
denotación [shape=plain];
nombre [shape=rect];
}
}
{personas máquinas} -> real [arrowhead=normal];
{real ficticia nula} -> entidad [arrowhead=normal];
nombre -> funciones -> obra -> supuesto -> selección -> producción -> entidad -> denotación -> nombre;
}
Live on dreampuf.github.io
Thanks!
Based on lots of experiments, the problem seems to be that dot's algorithm "weights" a multi-node edge more than a two-node edge.
Here is a much-edited input file that produces your desired output:
digraph tríada {
rankdir=LR;
edge [arrowhead=none];
label="* socialmente reconocido";
labeljust=left;
subgraph cluster_autor {
style=striped;
label="autor*";
subgraph cluster_sinonimia_nepa {
style=dashed;
label="sinonimia nombre-entidad-persona-autor";
personas [shape=hexagon];
entidad [shape=rect];
real [shape=diamond];
ficticia [shape=diamond];
nula [shape=diamond];
denotación [shape=plain];
nombre [shape=rect];
node [label="" shape=point width=.01]
// bogus1 & bogus2 are needed to flip/swap/invert the funciones & producción nodes
bogus1 bogus2
}
subgraph cluster_fp {
label="";
style=invis;
funciones [label="atribución o\napropiación", shape=plain];
producción [shape=plain];
}
máquinas [shape=hexagon];
{personas máquinas} -> real [arrowhead=normal];
{real ficticia nula} -> entidad [arrowhead=normal];
entidad -> denotación -> nombre
}
subgraph cluster_sinonimia_oa {
style=dashed;
label="sinonimia obra-texto";
subgraph cluster_texto {
style=striped;
label=texto;
selección [shape=rect];
}
obra [shape=rect, style=striped];
supuesto [label="supuesto\nexistencial", shape=plain];
}
nombre -> funciones -> obra -> supuesto -> selección
producción -> selección
entidad -> bogus1 [headclip=false ]
bogus1 -> bogus2 [tailclip=false, headclip=false]
bogus2 -> producción [tailclip=false]
}
(Yes, most of the edits were unnecessary)

Non deterministic results in Graphviz (dot)

How can I force graphviz to always generate the same layout?
Given a graph:
digraph {
subgraph clusterA {
subgraph clusterB {
"B.001"
"B.002"
"B.003"
"B.004"
}
subgraph clusterC {
"C.001"
"C.002"
"C.003"
}
}
subgraph clusterD {
subgraph clusterE {
"E.001"
}
subgraph clusterF {
"F.001"
"F.002"
"F.003"
}
subgraph clusterG {
"G.001"
"G.002"
}
}
subgraph clusterH {
"H.001"
}
"G.002" -> "F.003"
"F.001" -> "C.003"
"G.002" -> "F.002"
"G.002" -> "D.001"
}
When I pass it to dot it sometimes generates results with layout like this one:
and sometimes like this one:
Obviously the first one looks much better and I would like graphviz to stick to this one.
I tried to pass my graph through fdp and unflatten, but it doesn't change anything.
I tried a lot different render-solutions online and cli. I can't see another output then your second one. But if you prefer the first one, just switch the order of ClusterB and ClusterC.
digraph {
rankdir=TB
subgraph clusterA {
subgraph clusterC {
"C.001"
"C.002"
"C.003"
}
subgraph clusterB {
"B.001"
"B.002"
"B.003"
"B.004"
}
}
subgraph clusterD {
subgraph clusterE {
"E.001"
}
subgraph clusterF {
"F.001"
"F.002"
"F.003"
}
subgraph clusterG {
"G.001"
"G.002"
}
}
subgraph clusterH {
"H.001"
}
"G.002" -> "F.003"
"F.001" -> "C.003"
"G.002" -> "F.002"
"G.002" -> "D.001"
}

OrientDB import edges only using ETL tool

I already used the OETL to insert all my Vertex to the graph.
Now I have a file that outlines the edges at the following way:
node_1,rel_type,node_2
11000001,relation_A,10208879
11000001,relation_A,10198662
11000001,relation_B,10159927
11000001,relation_C,10165779
How can I import it using the OrientDB OETL tool?
I tried the following:
"transformers": [
{ "csv": {} },
{ "command" : {
"command" : "create edge ${rel_type} from (select flatten(#rid) from V where node_id= ${node_1}) to (select flatten(#rid) from V where node_id = ${node_2})",
"output" : "edge"
}
}
],
But this failed to work since it can't parse the values from the csv.
You must use the $input variable.
"transformers": [{
"csv": {
"separator": ","
}
},
{
"command" : {
"command" : "create edge ${input.rel_type} from (select from V where node_id= ${input.node_1}) to (select from V where node_id = ${input.node_2})",
"output" : "edge"
}
}
],
It works for me.
Hope it helps.

Resources