graphviz - Enforcing horizontal node ordering in a .dot tree -


i trying recreate example diagram binary search tree graphviz. how should in end:

enter image description here

this first attempt:

digraph g {     nodesep=0.3;     ranksep=0.2;     margin=0.1;     node [shape=circle];     edge [arrowsize=0.8];     6 -> 4;     6 -> 11;     4 -> 2;     4 -> 5;     2 -> 1;     2 -> 3;     11 -> 8;     11 -> 14;     8 -> 7;     8 -> 10;     10 -> 9;     14 -> 13;     14 -> 16;     13 -> 12;     16 -> 15;     16 -> 17; } 

but unfortunately graphviz doesn't care horizontal positions of tree, get:

enter image description here

how can add constraints horizontal positions of vertices reflects total ordering?

you follow usual approach of adding invisible nodes , invisible edges, , playing edge weight etc. proposed on graphviz faq balanced trees. in simple cases, enough.

but there better solution: graphviz comes tool called gvpr (graph pattern scanning , processing language) allows to

copy input graphs output, possibly transforming structure , attributes, creating new graphs, or printing arbitrary information

and since emden r. gansner did work creating script layout nicely binary trees, heres how to (all credit goes erg):

save following gvpr script file called tree.gv :

begin {   double tw[node_t];    // width of tree rooted @ node   double nw[node_t];    // width of node   double xoff[node_t];  // x offset of root left side of tree   double sp = 36;       // space between left , right subtrees   double wd, w, w1, w2;    double x, y, z;   edge_t e1, e2;   node_t n; } beg_g {   $.bb = "";   $tvtype=tv_postfwd;   // visit root after children visited } n {   sscanf ($.width, "%f", &w);   w *= 72;  // convert inches points   nw[$] = w;   if ($.outdegree == 0) {     tw[$] = w;     xoff[$] = w/2.0;   }   else if ($.outdegree == 1) {     e1 = fstout($);     w1 = tw[e1.head];         tw[$] = w1 + (sp+w)/2.0;     if (e1.side == "left")       xoff[$] = tw[$] - w/2.0;     else       xoff[$] = w/2.0;   }   else {     e1 = fstout($);     w1 = tw[e1.head];         e2 = nxtout(e1);     w2 = tw[e2.head];         wd = w1 + w2 + sp;     if (w > wd)       wd = w;     tw[$] = wd;     xoff[$] = w1 + sp/2.0;   } } beg_g {   $tvtype=tv_fwd;   // visit root first, children } n {   if ($.indegree == 0) {     sscanf ($.pos, "%f,%f", &x, &y);     $.pos = sprintf("0,%f", y);   }   if ($.outdegree == 0) return;   sscanf ($.pos, "%f,%f", &x, &y);   wd = tw[$];   e1 = fstout($);   n = e1.head;   sscanf (n.pos, "%f,%f", &z, &y);   if ($.outdegree == 1) {     if (e1.side == "left")       n.pos = sprintf("%f,%f",  x - tw[n] - sp/2.0 + xoff[n], y);     else       n.pos = sprintf("%f,%f", x + sp/2.0 + xoff[n], y);   }   else {     n.pos = sprintf("%f,%f", x - tw[n] - sp/2.0 + xoff[n], y);     e2 = nxtout(e1);     n = e2.head;     sscanf (n.pos, "%f,%f", &z, &y);     n.pos = sprintf("%f,%f", x + sp/2.0 + xoff[n], y);   } } 

assuming dot file containing graph called binarytree.gv, may execute following line:

dot binarytree.gv | gvpr -c -ftree.gv | neato -n -tpng -o binarytree.png 

the result is:

binary tree nicely layouted graphiv , gvpr script emden r. gansner

by switching around line or 2 in script, you'll have single child nodes go left instead of right side.


Comments

Popular posts from this blog

django - How can I change user group without delete record -

java - Need to add SOAP security token -

java - EclipseLink JPA Object is not a known entity type -