Commit 3c9ce30f authored by Emden R. Gansner's avatar Emden R. Gansner

Fix twopi to allow root as a node attribute, and allow multiple usages

in order to specify the roots of separate components.
parent 7ae096d2
......@@ -1718,7 +1718,7 @@ of the layout programs.
<DT><A NAME=d:root HREF=#a:root><STRONG>root</STRONG></A>
<DD> This specifies nodes to be used as the center of the
layout and the root of the generated spanning tree. As a graph attribute,
this gives the name of the node. As a node attribute (circo only), it
this gives the name of the node. As a node attribute, it
specifies that the node should be used as a central node. In twopi,
this will actually be the central node. In circo, the block containing
the node will be central in the drawing of its connected component.
......@@ -1727,6 +1727,10 @@ of the layout programs.
<P>
If the root attribute is defined as the empty string, twopi will reset it
to name of the node picked as the root node.
<P>
For twopi, it is possible to have multiple roots, presumably one for each
component. If more than one node in a component is marked as the root, twopi
will pick one.
<DT><A NAME=d:rotate HREF=#a:rotate><STRONG>rotate</STRONG></A>
<DD> If 90, set drawing orientation to landscape.
......
......@@ -1129,7 +1129,7 @@ This is a synonym for the <A HREF=#d:dpi>dpi</A> attribute.
:root:GN:string/bool:<none>(graphs)/false(nodes); twopi,circo
This specifies nodes to be used as the center of the
layout and the root of the generated spanning tree. As a graph attribute,
this gives the name of the node. As a node attribute (circo only), it
this gives the name of the node. As a node attribute, it
specifies that the node should be used as a central node. In twopi,
this will actually be the central node. In circo, the block containing
the node will be central in the drawing of its connected component.
......@@ -1138,6 +1138,10 @@ twopi will pick a most central node, and circo will pick a random node.
<P>
If the root attribute is defined as the empty string, twopi will reset it
to name of the node picked as the root node.
<P>
For twopi, it is possible to have multiple roots, presumably one for each
component. If more than one node in a component is marked as the root, twopi
will pick one.
:rotate:G:int:0;
If 90, set drawing orientation to landscape.
:rotation:G:double:0; sfdp
......
......@@ -59,6 +59,17 @@ void twopi_init_graph(graph_t * g)
twopi_init_node_edge(g);
}
static Agnode_t* findRootNode (Agraph_t* sg, Agsym_t* rootattr)
{
Agnode_t* n;
for (n = agfstnode(sg); n; n = agnxtnode(sg,n)) {
if (mapbool(agxget(n,rootattr))) return n;
}
return NULL;
}
/* twopi_layout:
*/
void twopi_layout(Agraph_t * g)
......@@ -66,14 +77,15 @@ void twopi_layout(Agraph_t * g)
Agnode_t *ctr = 0;
char *s;
int setRoot = 0;
int setLocalRoot = 0;
pointf sc;
int doScale = 0;
int r;
Agsym_t* rootattr;
if (agnnodes(g) == 0) return;
twopi_init_graph(g);
s = agget(g, "root");
if ((s = agget(g, "root"))) {
if (*s) {
ctr = agfindnode(g, s);
......@@ -87,6 +99,9 @@ void twopi_layout(Agraph_t * g)
setRoot = 1;
}
}
if ((rootattr = agattr(g, AGNODE, "root", 0))) {
setLocalRoot = 1;
}
if ((s = agget(g, "scale")) && *s) {
if ((r = sscanf (s, "%lf,%lf",&sc.x,&sc.y))) {
......@@ -102,12 +117,19 @@ void twopi_layout(Agraph_t * g)
Agnode_t *n;
int ncc;
int i;
Agnode_t* lctr;
ccs = ccomps(g, &ncc, 0);
if (ncc == 1) {
c = circleLayout(g, ctr);
if (ctr)
lctr = ctr;
else if (!(lctr = findRootNode(g, rootattr)))
lctr = 0;
c = circleLayout(g, lctr);
if (setRoot && !ctr)
ctr = c;
if (setLocalRoot && !lctr)
agxset (c, rootattr, "1");
n = agfstnode(g);
free(ND_alg(n));
ND_alg(n) = NULL;
......@@ -121,13 +143,15 @@ void twopi_layout(Agraph_t * g)
for (i = 0; i < ncc; i++) {
sg = ccs[i];
if (ctr && agcontains(sg, ctr))
c = ctr;
else
c = 0;
lctr = ctr;
else if (!(lctr = findRootNode(sg, rootattr)))
lctr = 0;
nodeInduce(sg);
c = circleLayout(sg, c);
c = circleLayout(sg, lctr);
if (setRoot && !ctr)
ctr = c;
if (setLocalRoot && (!lctr || (lctr == ctr)))
agxset (c, rootattr, "1");
adjustNodes(sg);
}
n = agfstnode(g);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment