使用 TikZ,我想要创建一个带有圆角的嵌套矩形分割,如下所示:
预期结果 http://www.liacs.nl/~schraage/tikzsplit2.png
与这个问题最相似的问题是嵌套矩形然而,提出的将两个独立节点组合在一个虚拟节点中的解决方案似乎相当复杂,并且不具备常规分割节点的优点,例如边距处理、圆角或节点部分定义。
我能想到的最接近的答案是:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{shapes}
\begin{document}
\begin{tikzpicture}
\node (A) [rectangle split,rectangle split parts=2,draw,text centered,rounded corners]{
\textit{marriage}, 1850
\nodepart{second}
\begin{tabular}{c|c}
John & Mary \\
Smith & Jones\\
\end{tabular}
};
\end{tikzpicture}
\end{document}
但是表格环境不会延伸到节点的边界: 部分解决方案
我想要的是这样的:
\node (A) [rectangle split,rectangle split parts=2,draw,text centered,rounded corners]{
\textit{marriage}, 1850
\nodepart{second}[rectangle split,rectangle split parts=2,rectangle split horizontal]
John\\Smith
\nodepart{second}
Mary\\Jones
};
或任何其他方便的嵌套语法。
其他解决方案(例如,matrix
或者简单的fit
)也受到赞赏。
答案1
嵌套 TikZ 图片/节点始终是一件棘手的事情。我尽量避免这种情况。
tabular
针对您的示例(线条不接触形状的边框)的简单修复方法是将设置inner ysep
为零。不幸的是,这不能单独针对第二个节点部分完成。您最终会得到一个非常紧密的节点。
我提出两种解决方案:
- 接下来是一个简单的表格框架超越简单的线条但使用了一个大的
\Strut
; - 复杂的 TikZ 节点填充解决方案
简单的
如果您经常使用它,您可能需要创建一个宏,仅向其提供树文本部分。
代码
\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}
输出
复杂的
该解决方案提供了一个three parts
接受三个参数的键:
- 第一个顶部节点的文本,
- 左下角节点的文本,以及
- 右下角节点的文本。
每个参数前面都可以加上一组用括号括起来的可选参数[ … ]
(如示例中所示)。
该fit
库用于在这三个节点周围放置一个节点(这是我们真正想要绘制的节点)。
重新排列节点的放置顺序或对节点的默认选项进行某些更改可以实现略有不同的对齐。
代码
\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@[email protected]),
anchor=north east,
outer sep=+0pt},
three parts right node/.style={
every three parts node,
name=qrr@tikz@tp@r,
at=(qrr@tikz@[email protected]),
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@[email protected] west) edge[three parts node after edge 1/.try] ([xshift=-\pgflinewidth]qrr@tikz@[email protected] east)
([yshift=-.5\pgflinewidth]qrr@tikz@[email protected] east) edge[three parts node after edge 2/.try] ([yshift=\pgflinewidth] qrr@tikz@[email protected] 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}