Parallel flowcharts: conjoined nodes, arrow routing and alignment

Transitioning from GraphViz to TikZ is hurting my brain...

My task is to generate flowcharts of the following variety:

In particular, I need a method to position nodes that share borders (preferably independent of their width and height) while adhering to a grid. Extra credit for explanations of how to draw brackets that indicate node grouping, as well as how to draw orthogonal arrows whose endpoints do not coincide (preferably without specifying exact coordinates or angles) or that align with specific columns, such as the load -> add arrow.

-
thank you for the embed, @percusse –  bug Oct 2 '12 at 22:35
My pleasure. Welcome to TeX.SE –  percusse Oct 3 '12 at 0:29

There were three main requests:

1. A method to position nodes that share borders. One possibility here is to use the key node distance and the positioning library. An example:

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning}

\begin{document}

\begin{tikzpicture}[every node/.style={draw}]
\node (a) {A};
\node[right=of a] (b) {B};
\node[right=of b] (c) {C};
\begin{scope}[yshift=-1cm,node distance=-\pgflinewidth,every node/.append style={fill=blue!20}]
\node (a) {A};
\node[right=of a] (b) {B};
\node[right=of b] (c) {C};
\end{scope}
\end{tikzpicture}

\end{document}


2. How to draw orthogonal arrows whose endpoints do not coincide (preferably without specifying exact coordinates or angles) or that align with specific columns. The main tool here is the implicit syntax for the perpendicular coordinate system. The expression ( p |- q ) or ( q -| p ). For example, (0,1 |- 2,3) and (2,3 -| 0,1) both produce the same as (0,3); the following example shows this syntax in action:

\documentclass{standalone}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}
\node at (0,0) (a) {A};
\node at (2,2) (b) {B};
\node at (4,-1) (c) {C};
\node at (4,-2) (d) {D};

\draw[red] (a) |- (b);
\draw[blue] (a) -| (b);
\draw[green] (c) -- (a|-c) -- (a|-d) -- (d);
\end{tikzpicture}

\end{document}


3. How to draw brackets that indicate node grouping. The idea here is to use decorations; particularly, the brace decoration offered by the decorations.pathreplacing library. A little example:

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations.pathreplacing}

\begin{document}

\begin{tikzpicture}
\node (a) {A};
\node at (2,2) (b) {B};
\node at (4,0) (c) {C};
\draw[decorate,decoration=brace] (a) -- (b);
\draw[decorate,decoration=brace] (b) -- (c);
\draw[decorate,decoration={brace,mirror}] (a) -- (c);
\end{tikzpicture}

\end{document}


Combining these ideas and defining some styles for the nodes, the original diagram can be produced. The complete code:

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{calc,positioning,arrows,decorations.pathreplacing}

\definecolor{myblue}{RGB}{170,223,249}
\begin{document}

\begin{tikzpicture}[
>={stealth'},
every node/.style={node distance=-\pgflinewidth},
exx/.style={rectangle,draw,fill=gray!30,text width=0.9cm,align=center,font=\ttfamily},
sblue/.style={rectangle,rounded corners,draw,fill=myblue,text width=1.25cm,
align=center,text height=9pt,text depth=3pt,font=\sffamily},
mtext/.style={text width=4cm,align=left,text height=9pt,text depth=3pt,font=\ttfamily}
]

% the upper eax,..., edx nodes
\node[exx] (eax) {\%eax};
\node[exx,right= of eax] (ebx) {\%ebx};
\node[exx,right= of ebx] (ecx) {\%ecx};
\node[exx,right= of ecx] (edx) {\%edx};

% the vertical blue nodes
\node[sblue,below = of sadd] (sdata) {s\_data};
\node[sblue,below = of add] (sub) {sub};
\node[sblue,below = of sub] (jne) {jne};

% some vertical nodes to place text to the right of the blue nodes
\node[mtext,below = of tsadd] (tsdata) {};
\node[mtext,below = -9pt of tsadd] {movl \%eax,(\%ecx)};
\node[mtext,below = of tload] (tadd) {addl \$1,\%eax}; \node[mtext,below = of tadd] (tsub) {subl \$1,\%edx};
\node[mtext,below = of tsub] (tjne) {jne loop};

% the lower eax,..., edx nodes
\node[exx,below left = 10pt of jne] (edx1) {\%edx};
\node[exx,left= of edx1] (ecx1) {\%ecx};
\node[exx,left= of ecx1] (ebx1) {\%ebx};
\node[exx,left= of ebx1] (eax1) {\%eax};

% the straight lines with arrow tips
\draw[->] (eax) |- (sdata);
\draw[->] (ebx) -- (ebx1);
\draw[->] (ecx) -- (ecx1);
\draw[->] (edx) |- (sub.170);
\draw[->] (sub.190) -| (edx1);

% the curved arrows
\draw[->] (sub.0) to[out=-30,in=30] (jne.0);

% the brace
\draw[decorate,decoration=brace] ( $(sadd.north)!.35!(tsadd.north)$ ) -- ( $(sdata.south)!.35!(tsdata.south)$ );

\end{tikzpicture}

\end{document}


-
This is all rather self explanatory, and finally clarifies the (|-) intersection syntax for me. Thanks. However, I had really hoped to avoid using bare angles and offsets such as sub.170 and below right = 20pt of edx, but I suppose I'm asking too much of TikZ. Every diagram I make seems to be a cycle of tiny tweaks ad nauseum...(as I noticed too in your edits) –  bug Oct 3 '12 at 0:31
Also, is it simple to overlap node borders (not creating a split node)? If not, I don't want to bother. –  bug Oct 3 '12 at 0:37
@bug setting node distance to 0pt (without the on grid option) you can make the borders overlap. –  Gonzalo Medina Oct 3 '12 at 0:42
I meant that the borders appear to be merely adjacent, giving the appearance of a border twice as thick. Is there a way to move the nodes closer by the width of one borderline? –  bug Oct 3 '12 at 0:52
@bug node distace=\pgflinewidth should work. –  Gonzalo Medina Oct 3 '12 at 0:53