我想用 tikz 渲染类似的东西:
周围的大框应该表现得像一个小页面:宽度是固定的,如果我们在里面添加足够小的框,高度应该会增加。目前,我使用以下(简化的)MWE 来产生:
\begin{tikzpicture}
\tikzstyle{bigbox} = [minimum height=2cm,draw,rounded corners, rectangle]
\tikzstyle{box} = [minimum height=0.8cm,draw,rounded corners, draw,rectangle]
\node[bigbox](outbox)%
{
\begin{minipage}{3cm}
\tikz{\node[box]{12};}
\tikz{\node[box]{12};}
\tikz{\node[box]{12};}
\tikz{\node[box]{12};}
\end{minipage}
};
\end{tikzpicture}
正如你所注意到的,我将 嵌套\tikz
在 里面tikzpicture
,这很糟糕,因为我刚刚在这篇帖子来自 Andrew Stacey。他建议使用中的“适合”选项\usetikzlibrary{fit}
,但在这种情况下我不知道该怎么做。
答案1
Mark 已经回答了关于在内部内容到位后对外部矩形进行排序的问题(考虑到约束条件,fit
和layer
方法似乎更合适)。我要解决的问题是让内部框使用“换行”功能自行定位。这不是一个完整的解决方案,但如果它看起来是正确的,那么我认为剩下的事情并不难做(但我想在做之前先检查一下)。
我对这个问题的评论(引用自真实的意大利工作 (Italian Job) 的思路是对的,但还不够。该positioning
库可以接受相当复杂的表达式 - 可以做类似的事情above={(\x > \y ? 3cm : -2cm)} of a.south
- 但事实证明,这些都是计算出来的前节点布局完毕,所有复杂的定位工作都由节点代码完成,而不是定位代码完成。
因此,我们必须将节点代码用于我们的邪恶目的。幸运的是,这相对容易(如果全部执行起来有点乏味)。节点通过指定锚点来定位。该锚点位于(0,0)
(定位库或只是 TikZ,设置了节点所在的(0,0)
位置)。因此,如果我们想将节点放置在稍微不同的地方,我们只需定义一个相当复杂的锚点。这需要定义一个新形状或使用 Martin Scharrer 的代码将新锚点添加到现有形状。我选择了前者,并定义了一个“可移动矩形”。这个矩形具有其north west
锚点可以依赖于参数的属性。嗯,实际上需要一点计算。这个计算能使用有关节点大小的信息,因为它是在布局节点时计算的。我的计算是:
\pgfmathparse{(\mrwidth > 1cm ? "(a.north east)" : "(a.south west)")}
\let\mrvector=\pgfmathresult
这将测试一个宏,\mrwidth
该宏恰好设置为节点的宽度(mr
=“可移动矩形”)(显然,可以对其进行调整以使高度也可用)。如果宽度很大,则返回(a.north east)
,如果很小,则返回(a.south west)
。结果保存为\mrvector
。此代码在节点计算north west
矩形的锚点时执行,锚点会根据结果进行移动。由于节点坐标是“绝对的”,因此结果是当前节点的西北锚点位于节点的东北或西南,a
具体取决于其宽度。如果坐标是这样的(0,2cm)
,这将表示一个相对的调整。
因此,我们的想法是进行一个稍微复杂一点的测试,看看节点的宽度是否会超出给定的宽度,如果是,则将节点锚定在下一行。这需要多做一点工作,但不会太多,因为通常会有多个节点参与计算。但这只是记账。
我将把完整代码放在这个答案的末尾。如果全部打包在一个漂亮的包中,语法将类似于:
\begin{document}
\begin{tikzpicture}
\node[box] (a) {A};
\node[box,moveable rectangle,anchor=north west,moveable] at (a.south east) (b) {B};
\node[box,moveable rectangle,anchor=north west,moveable] at (a.south east) (c) {ABCDEFG};
\end{tikzpicture}
\end{document}
结果:
如您所见,两个节点的规格完全相同,但一个节点位于a
节点旁边,另一个位于节点下方。
这是目前为止的代码。我目前只修改了锚点north west
。显然,其他的也需要修改。压力测试和我所做的一些假设可能会被证明是完全荒谬的……
\documentclass{article}
%\url{http://tex.stackexchange.com/q/40234/86}
\usepackage{tikz}
\makeatletter
\tikzset{
box/.style={
minimum height=0.8cm,
draw,
rounded corners,
rectangle
},
moveable rectangle/condition/.code={%
\pgfmathparse{(\mrwidth > 1cm ? "(a.north east)" : "(a.south west)")}
\let\mrvector=\pgfmathresult
},
moveable/.is if=mr@moveable,
}
\def\mrvector{(0,0)}
\newif\ifmr@moveable
\pgfdeclareshape{moveable rectangle}{%
\inheritsavedanchors[from=rectangle]%
\anchor{north west}{%
\ifmr@moveable
\northeast
\pgf@xa=\pgf@x
\southwest
\advance\pgf@xa by -\pgf@x
\edef\mrwidth{\the\pgf@xa}%
\pgfkeys{/tikz/moveable rectangle/condition}%
\tikz@scan@one@point\pgfutil@firstofone\mrvector
\pgf@xa=-\pgf@x
\pgf@ya=-\pgf@y
\northeast
\advance\pgf@ya by \pgf@y
\southwest
\advance\pgf@xa by \pgf@x
\pgf@x=\pgf@xa
\pgf@y=\pgf@ya
\else
\northeast
\pgf@ya=\pgf@y
\southwest
\pgf@y=\pgf@ya
\fi
}
\inheritbackgroundpath[from=rectangle]
}
\makeatother
\begin{document}
\begin{tikzpicture}
\node[box] (a) {A};
\node[box,moveable rectangle,anchor=north west,moveable] at (a.south east) (b) {B};
\node[box,moveable rectangle,anchor=north west,moveable] at (a.south east) (c) {ABCDEFG};
\end{tikzpicture}
\end{document}
答案2
以下内容比较粗略,也许使用矩阵会更好,但它是为了演示如何在背景中使用拟合框。
\documentclass[10pt]{article}
\usepackage{tikz}
\usetikzlibrary{backgrounds,fit}
\begin{document}
\begin{tikzpicture}[outer sep=0.05cm,node distance=0.8cm,]
\tikzstyle{bigbox} = [draw=blue!50, thick, fill=blue!10, rounded corners, rectangle]
\tikzstyle{box} = [minimum size=0.6cm, rounded corners,rectangle, fill=blue!50]
%
\node[box] (11) {1};
\node[box,right of=11] (12) {2};
\node[box,right of=12] (13) {3};
\node[box,below of=11] (21) {4};
\node[box,right of=21] (22) {5};
\node[box,right of=22] (23) {6};
%
\begin{pgfonlayer}{background}
\node[bigbox] [fit = (11) (23)] {};
\end{pgfonlayer}
%
\end{tikzpicture}
\end{document}
请注意,确保fit = (11) (22)
框包含左上角和右下角的框。对于更复杂的图表,您可以添加更多节点名称以适应。
使用 TikZ 可以更干净地获得类似的结果matrix
。另一个好处是不需要拟合,因为矩阵本身就采用了这种bigbox
风格。
\begin{tikzpicture}
\tikzstyle{bigbox} = [draw=blue!50, thick, fill=blue!10, rounded corners, rectangle]
\tikzstyle{box} = [minimum size=0.6cm, rounded corners,rectangle, fill=blue!50]
%
\matrix[row sep=2mm, column sep=2mm, inner sep=2mm, bigbox, every node/.style=box] {
\node {1}; & \node {2}; & \node {3};\\
\node {4}; & \node {5}; & \node {6};\\
};
%
\end{tikzpicture}
matrix
正如 percusse 所指出的,通过添加库可以进一步简化这一过程
\usetikzlibrary{matrix}
并使用matrix of nodes
矩阵的选项。
\begin{tikzpicture}
\tikzstyle{bigbox} = [draw=blue!50, thick, fill=blue!10, rounded corners, rectangle]
\tikzstyle{box} = [minimum size=0.6cm, rounded corners,rectangle, fill=blue!50]
%
\matrix[row sep=2mm, column sep=2mm, inner sep=2mm, bigbox, matrix of nodes, every node/.style=box] {
1 & 2 & 3\\
4 & 5 & 6\\
};
%
\end{tikzpicture}