Dot more layout control

I know dot is not primarily a typesetting layout package, but I like it for the nice language and the nice drawings for some diagrams. I want to have better layout control. I understand rank=same, and it is very helpful, but I do not just want row control or column control (depending on rankdir), I really want more of both.

right now, I am struggling how to convince a basic tree diagram in LR rankdir to flip parts of the graph.

grok

I am using C for column and R for row. I want to flip C2 and C3 not to go from bottom to top, but from top-to-bottom. the code I have been using is

digraph G {
	rankdir="LR";

	boxme [shape="box"]

	start -> C1R1 ;
	start -> C1R2 ;

	C1R1 -> boxme ;
	C1R1 -> C2R1 ;

	boxme -> C2R2 ;
	boxme -> C2R3 ;

	subgraph cluster_0 {
		label= "surrounded";
		color=blue;
		style=rounded; style=dashed;  ## only last one takes
		node [ style=filled, color=green ];
		C3R1 -> C3R2 -> C3R3 -> C3R4 [style=invis];
		{ rank = same; C3R1; C3R2; C3R3; C3R4; };
	}

	C2R1 -> C3R1 ;
	C2R1 -> C3R2 ;

	C2R2 -> C3R3 ;
	C2R2 -> C3R4 ;

	C2R3 -> C3R5 ;
	C2R3 -> C3R6 ;

	{ rank = same; C1R1; C1R2; }
	{ rank = same; C2R1; C2R2; C2R3; }

# why does the following remove the surrounded box? (and algorithm crosses arrows)
#	{ rank = same; C3R1; C3R2; C3R3; C3R4; C3R5; C3R6; }
}

there is also the very strange layout (needlessly crossing arrows) when I uncomment out the final statement, and the dotted box no longer works.

by trial and error, I have figured out that the order in which statements appear can sometimes change the internaly dot layout algorithm, but I don’t understand how this works, either.

is dot entirely the wrong tool for what I want to do? or can it be coaxed appropriately with more layout control?

advice appreciated.

/iaw

  1. Attribute declarations are not additive, they replace earlier definitions. You want style=“rounded,dashed”

  2. To try to keep nodes in the sequence you want, use something like this (invisible edges):
    { rank = same; C3R1 -> C3R2 -> C3R3 -> C3R4 [style=invis] };

  3. The underlying problem with the last rank (column) is a bug in dot related to rankdir=LR (setting rankdir causes odd node ordering (#1953) · Issues · graphviz / graphviz · GitLab)
    Here is your graph tweaked. Correct w/ std rankdir, funky result w/ rankdir=LR:

     digraph G {
     //	rankdir="LR";
     	boxme [shape="box"]
    
     	start -> C1R1 ;
     	start -> C1R2 ;
     	C1R1 -> boxme ;
     	C1R1 -> C2R1 ;
     	boxme -> C2R2 ;
     	boxme -> C2R3 ;
     	subgraph cluster_0 {
     		graph [label= "surrounded"; color=blue; style="rounded,dashed" ] 
     		node [ style=filled, color=green ];
     		{ rank = same;  C3R1 -> C3R2 -> C3R3 -> C3R4  [style=invis]} 
     	}
     	C2R1 -> C3R1 ;
     	C2R1 -> C3R2 ;
     	C2R2 -> C3R3 ;
     	C2R2 -> C3R4 ;
     	C2R3 -> C3R5 ;
     	C2R3 -> C3R6 ;
     	{ rank = same; C1R1 -> C1R2   [style=invis] }
     	{ rank = same; C2R1 -> C2R2 -> C2R3  [style=invis]  }
     	{ rank = same; C3R5 -> C3R6  [style=invis] }
     }
    


1 Like

thank you. very kind of you. this case seems even worse than the specific bug, with crossing arrows (which presumably are penalized more).

is there a variation to the dot tool that relies relatively less on automatic layout and more on manual layout? if dot had this, I could work around the bug by pushing up C3R1 … (but presumably, the order not being followed is the bug here.)

My only suggestion for now is to run dot -Tdot yourfile.gv >yourfile.dot This will give a text version of your file with positioning. You can edit this file - manually or programmatically - to reposition (swap) the nodes where you want them. (Edit the pos values) Don’t worry about the edges.
Then run that thru neato neato -n -Tpng yourfile.dot >yourfile.png The -n option will keep the (new) node positions but will redraw the edges. (See this FAQ | Graphviz)