I don't really get the question so I hope this is what you wanted. If you include a full document (such that we copy paste and see the problem on our systems) things are much more easier.
Here, you can change the default setting within a scope but your block
style had a node distance
which was resetting every time it is issued. I've made it 2mm such that we can see the difference easier.
\documentclass[tikz]{standalone}
\usetikzlibrary{arrows,shapes.geometric,positioning}
\begin{document}
\begin{tikzpicture}[decision/.style={diamond, draw, text width=4.5em, text badly centered, node distance=3.5cm, inner sep=0pt},
block/.style ={rectangle, draw, text width=6em, text centered, rounded corners, minimum height=4em, minimum height=2em},
cloud/.style ={draw, ellipse, minimum height=2em},
line/.style ={draw,-latex'},
node distance = 1cm,
auto]
\node [block] (1st) {1st};
\node [block, right= of 1st] (2nd1) {2nd1};
\begin{scope}[node distance=2mm and 10mm]%Here we change it for everything inside this scope
\node [block, above= of 2nd1] (2nd2) {2nd2};
\node [block, below= of 2nd1] (2nd3) {2nd3};
\node [block, right= of 2nd1] (3rd1) {3rd1};
\node [block, above= of 3rd1] (3rd2) {3rd2};
\node [block, above= of 3rd2] (3rd3) {3rd3};
\end{scope}
\node [block, below= of 3rd1] (3rd4) {3rd4};
\node [block, below= of 3rd4] (3rd5) {3rd5};
\path [line] (1st) -- (2nd1);
\path [line] (2nd1) -- (2nd2);
\path [line] (2nd1) -- (2nd3);
\path [line] (2nd2) -- (3rd3);
\path [line] (2nd1) -- (3rd1);
\path [line] (1st) -- (2nd1);
\end{tikzpicture}
\end{document}
Nesting TikZ pictures/nodes is always a tricky business. I try to avoid this.
A simply fix for your example (tabular
lines do not touch the shape’s border) could be to set the inner ysep
to zero. Unfortunately, this cannot be done for the second node part separately. You’ll end up with a very tight node.
I propose two solutions:
- A simple one that follows Table Frames beyond simple lines but uses a big
\Strut
;
- A complex TikZ nodes-filled solution
Simple
If you use this often, you might want to create a macro to which you only feed the tree text parts.
Code
\documentclass[tikz,convert=false]{standalone}
\newcommand*{\ml}[2][c]{\tabular[t]{@{}#1@{}} #2 \endtabular}
\makeatletter
\newcommand*{\Strut}[1][1em]{\vrule\@width\z@\@height#1\@depth\z@\relax}
\makeatother
\begin{document}
\begin{tikzpicture}
\node[rounded corners, draw, inner sep=+0pt] {%
\begin{tabular}{c|c}
\multicolumn{2}{c}{\textit{marriage}, 1850\Strut} \\\hline
\ml{\Strut John\\Smith} & \ml{\Strut Mary\\Jones}
\end{tabular}};
\end{tikzpicture}
\end{document}
Output
Complicated
This solution provides a three parts
key that takes three arguments:
- the text for the first top node,
- the text for the lower left node, and
- the text for the lower right node.
Every argument can be preceded with a set of optional argument in brackets [ … ]
(as done in the example).
The fit
library is used to fit a node around those three nodes (this is the one we actually want to draw).
Re-arranging the order how the nodes are placed or making certain changed at the default options of the nodes one can achieve slightly different alignment.
Code
\documentclass[tikz,convert=false]{standalone}
\usetikzlibrary{fit}
\tikzset{
three parts left node/.style={
every three parts node,
name=qrr@tikz@tp@l,
at=(qrr@tikz@tp@t.south),
anchor=north east,
outer sep=+0pt},
three parts right node/.style={
every three parts node,
name=qrr@tikz@tp@r,
at=(qrr@tikz@tp@t.south),
anchor=north west,
outer sep=+0pt},
three parts top node/.style={
every three parts node,
name=qrr@tikz@tp@t,
outer sep=+0pt},
three parts node/.style={
inner sep=-.5\pgflinewidth,
minimum size=+0pt,
fit=(qrr@tikz@tp@l)(qrr@tikz@tp@r)(qrr@tikz@tp@t)},
every three parts node/.style={align=center},
three parts node after/.style={
insert path={
([xshift=\pgflinewidth] qrr@tikz@tp@t.south west) edge[three parts node after edge 1/.try] ([xshift=-\pgflinewidth]qrr@tikz@tp@t.south east)
([yshift=-.5\pgflinewidth]qrr@tikz@tp@l.north east) edge[three parts node after edge 2/.try] ([yshift=\pgflinewidth] qrr@tikz@tp@r.south west)}},
}
\makeatletter
\tikzset{
three parts/.code args={#1#2#3}{%
\pgfutil@ifnextchar[%
{\expandafter\tikz@scan@next@command\qrr@tikz@split@nodeOpt{three parts top node}}
{\expandafter\tikz@scan@next@command\qrr@tikz@split@nodeOpt{three parts top node}[]}#1\egroup\pgf@stop
\pgfutil@ifnextchar[%
{\expandafter\tikz@scan@next@command\qrr@tikz@split@nodeOpt{three parts left node}}
{\expandafter\tikz@scan@next@command\qrr@tikz@split@nodeOpt{three parts left node}[]}#2\egroup\pgf@stop
\pgfutil@ifnextchar[%
{\expandafter\tikz@scan@next@command\qrr@tikz@split@nodeOpt{three parts right node}}
{\expandafter\tikz@scan@next@command\qrr@tikz@split@nodeOpt{three parts right node}[]}#3\egroup\pgf@stop
\tikz@scan@next@command node[three parts node/.try]{}[three parts node after]\pgf@stop
}
}
\def\qrr@tikz@split@nodeOpt#1[#2]{node[#2,#1]\bgroup}
\makeatother
\begin{document}
\begin{tikzpicture}[three parts node/.append style={draw,rounded corners}]
\path [three parts={[blue!50!red]\textit{marriage}, 1850}{[blue]John\\Smith}{[red]Mary\\Jones}];
\end{tikzpicture}
\end{document}
Output
Best Answer
I think this code, using
tcolorbox
andeqparbox
should help. Eqparbox defines tagged boxes, so that all boxes with the same tag eventually all have the width of the widest of them (requires two compilations):