Graphviz issue with nodes and edges across subgraphs

Hi Graphviz forum,

I have been using GraphViz recently to generate some directed graphs for a project I am working on.

The structure of the graphs is basically a set of nested subgraphs, with edges between nodes within the subgraphs.

However, I am having trouble in certain cases as a node belongs to one subgraph, but when I create an edge from another subgraph, the graphviz generator sometimes thinks that the node does not exist in the other subgraph and therefore creates a new node in the subgraph where I declared an edge where it should have linked back to the other subgraph node.

e.g. in this case it sometimes creates node2 within subgraph1, when it is actually in subgraph2.

I did the obvious thing moving subgraph2 before subgraph1, but the process seems to be non-deterministic in that sometimes it produces the desired output, but sometimes not.

subgraph0 {
node1;
}
subgraph1 {
node1 -> node2
}
subgraph 2 {
node2;
}

Is there anyway I can force it not to create nodes through the edge declaration unless it has checked elsewhere in the graph first that the node exists?

Regards,
Simon.

Without using clusters, there

Without using clusters, there should be no visible effect, so I assume you are actually using cluster subgraphs. Somewhere in the documentation we mention that if an edge belongs to a cluster, its nodes must also belong to that cluster. And a node can only belong to a single innermost cluster (it can be in lots of higher-level clusters), so dot will put it into a single cluster, probably the one with the edge. (I'm not sure where the "non-determinism" might enter, but if the entire graph was examined, the result would be deterministic.)

The short answer is to move the edge outside of the cluster it is in. If this doesn't work, or you have other concerns, let us know and post a complete graph causing the problerm. Thanks.

The most important fact is

The most important fact is what erg stated, a node can belong to at most subgraph.

What I do is to define any node before it is used in any edge (by reordering). That way it looks as it should and does not get the default layout. I have only seen deterministic behavior with "dot" layout tool, "neato" is non-deterministic.

This is your modified sample input (edge below all its node definitions, ≤1 subgraphs per node, subgraphs prefixed with "cluster_" to show borders):

// http://graphviz.org/content/graphviz-issue-nodes-and-edges-across-subgraphs
//
digraph subgraphs {
  rankdir=LR

  subgraph cluster_0 {
    label="sub 0"
    node1;
  }

  subgraph cluster_2 {
    label="sub 2"
    node2;
  }

  node1 -> node2
}

This is your modified sample output ("Save" button, copied .svg output into this posting with "graphviz" as "Input format", HTML tags needed for formatting, "Preview" here recommended) : 

subgraphs cluster_0 sub 0 cluster_2 sub 2 node1 node1 node2 node2 node1->node2

 

You can play with it (modify and click "Draw"), and finally click "Share" button and copy in the generated URL from address bar here in order to show any other problem you have like this link: modified sample

 

 

 

Hermann <GraphvizFiddle/> <Viz.js_form10/>

 

 

 

That works - thank you!

Dear erg / HermannSW,

 

 

Thank you for taking the time to respond. Yes I am using cluster subgraphs.

The suggestion put forward by HermannSW of declaring the nodes in subgraphs first then edges separately later works great!

Thank you !

I also found today that I could get it to work by prefixing the cluster name to the node in the edge but the solution given by HermannSW I think is much better! Thank you again so much it has really helped me as I was getting a bit lost with some quite complicated nested graphs.

e.g. this is how I got it to work eventually ...

subgraph cluster0 {

node0;

}

subgraph cluster1 {

node1 --> cluster0:node0

}

I am now confused. The code

I am now confused. The code snippet

subgraph cluster0 {

node0;

}

subgraph cluster1 {

node1 --> cluster0:node0

}

is not legal DOT. This piece defines three nodes, not two. The expression for the head node of the edge means the edge should go from node1 to node cluster0, entering at port node0, which should cause a warning. (And, of course, you want ->,  not -->.)

Recent comments