我正在尝试实现以下目标:
+---------------------+ +---------------+
| A | | B |
+---------------------+ +---------------+
+---------+
########1######## | C | #####2#####
+---------+
+---+ +---------+ +---------+ +---+ +---+
| D | | E | | F | | G | | H |
+---+ +---------+ +---------+ +---+ +---+
+---+
##3## | I | ###########4########### ##5##
+---+
+---------+ +---------------------+ +---+
| J | | K | | L |
+---------+ +---------------------+ +---+
在这里,标签应该代表空白区域。我看过这个答案,但该解决方案并不完全符合我的需要。
为了指定我的图表,我想要做的是逐行、从左到右设计它;按顺序列出我想要绘制的所有块/空白处。
为了正确重叠,我想为每个块/空白空间指定与其共享垂直空间的上一行中的哪些块。我怎么做?或者更好的是,我如何获得期望的最终结果?
如果添加一行,要求共享窄块的垂直空间,从而导致块被拉伸,那就太好了。以上面的例子为例;如果C
本身很窄,让它与和共享垂直空间A
会使B
它变得稍微宽一些。同样,由于#4
共享了部分E
垂直空间,E
必须变得更宽以容纳I
和的一部分#4
。最后,由于H
和#5
共享L
相同的垂直空间,它们应该同样宽。
也许,按照以下思路来思考这个行/列分解推特引导模型可以帮助进一步形象化这个问题。
更新(2013-12-11):
我尝试按照建议使用 TikZ 矩阵。因此我不得不查找如何实现跨列。这是使用该技术的 MWE:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning,calc,matrix,fit}
\makeatletter
\newdimen\multi@col@width
\newdimen\multi@col@margin
\newcount\multi@col@count
\multi@col@width=0pt
\tikzset{
multicol/.code={%
\global\multi@col@count=#1\relax
\global\let\orig@pgfmatrixendcode=\pgfmatrixendcode
\global\let\orig@pgfmatrixemptycode=\pgfmatrixemptycode
\def\pgfmatrixendcode##1{\orig@pgfmatrixendcode%
##1%
\pgfutil@tempdima=\pgf@picmaxx
\global\multi@col@margin=\pgf@picminx
\advance\pgfutil@tempdima by -\pgf@picminx
\divide\pgfutil@tempdima by #1\relax
\global\multi@col@width=\pgfutil@tempdima
\pgf@picmaxx=.5\multi@col@width
\pgf@picminx=-.5\multi@col@width
\global\pgf@picmaxx=\pgf@picmaxx
\global\pgf@picminx=\pgf@picminx
\gdef\multi@adjust@position{%
\setbox\pgf@matrix@cell=\hbox\bgroup
\hfil\hskip-1.5\multi@col@margin
\hfil\hskip-.5\multi@col@width
\box\pgf@matrix@cell
\egroup
}%
\gdef\multi@temp{\aftergroup\multi@adjust@position}%
\aftergroup\multi@temp
}
\gdef\pgfmatrixemptycode{%
\orig@pgfmatrixemptycode
\global\advance\multi@col@count by -1\relax
\global\pgf@picmaxx=.5\multi@col@width
\global\pgf@picminx=-.5\multi@col@width
\ifnum\multi@col@count=1\relax
\global\let\pgfmatrixemptycode=\orig@pgfmatrixemptycode
\fi
}
}
}
\makeatother
\begin{document}
\begin{tikzpicture}{
\matrix[matrix of nodes, nodes={draw}, draw=black] (Layers) {
%row 1
|[multicol=4]| A &&&&|[multicol=3]| B && \\
%row 2
|[multicol=3]| &&&|[multicol=2]| C &&|[multicol=2]| & \\
%row 3
D &|[multicol=2]| E &&|[multicol=2]| F && G & H \\
%row 4
& I &|[multicol=4]| &&& \\
%row 5
|[multicol=2]| J &&|[multicol=4]| K &&&& L \\
};
}
\end{tikzpicture}
\end{document}
然而,结果有些不令人满意(不需要的方框出现在一些空格和字母周围的方框不够宽):
尽管目前取得的结果并不令人满意,但我还是尝试将其改编成更具视觉吸引力的版本(只需替换\begin{tikzpicture}...\end{tikzpicture}
MWE 中的部分):
\begin{tikzpicture}[
base/.style={
rounded corners,
font={\sffamily\bfseries},
align=center,
},
block/.style={
base,
draw=lime,
fill=blue,
font={\sffamily\bfseries\color{white}},
},]{
\matrix[draw=black] (Layers) {
%row 1
|[multicol=4]|
\node[block] (a) {A};
&&&&|[multicol=3]|
\node[block] (b) {B};
&& \\
%row 2
|[multicol=3]| &&&|[multicol=2]|
\node[block] (c) {C};
&&|[multicol=2]| & \\
%row 3
\node[block] (d) {D};
&|[multicol=2]|
\node[block] (e) {E};
&&|[multicol=2]|
\node[block] (f) {F};
&&
\node[block] (g) {G};
&
\node[block] (h) {H};
\\
%row 4
&
\node[block] (i) {I};
&|[multicol=4]| &&& \\
%row 5
|[multicol=2]|
\node[block] (j) {J};
&&|[multicol=4]|
\node[block] (k) {K};
&&&&
\node[block] (l) {L};
\\
};
}
\end{tikzpicture}
结果如下:
很明显,大多数盒子都没有正确拉伸到预期尺寸。我该如何解决这个问题?
答案1
我以 12 厘米的块和 4 毫米的松动为基础,然后对块进行调整,以使事物更好地排列。
\documentclass{article}
\newlength{\cellH}% cell height
\setlength{\cellH}{.8cm}
\newlength{\cellW}% cell width (1 unit)
\setlength{\cellW}{.8cm}
\newlength{\cellM}% (cell height - character height)/2
\settoheight{\cellM}{ABCDEFGHIJKL12345}
\addtolength{\cellM}{-\cellH}
\setlength{\cellM}{-0.5\cellM}
\newcommand{\cell}[2]% #1 = width, #2 = text
{\framebox[#1\cellW][c]{\raisebox{\cellM}[\cellH]{#2}}}
\newcommand{\blank}[2]% #1 = width, #2 = text
{\makebox[#1\cellW][c]{\raisebox{\cellM}[\cellH]{#2}}}
\begin{document}
\centering{\parbox{12.4\cellW}{%
\cell{7.65}{A} \cell{4.65}{B}
\blank{6}{1} \cell{3}{C} \blank{3}{2}
\cell{2}{D} \cell{3}{E} \cell{3}{F} \cell{2}{G} \cell{2}{H}
\blank{2}{3} \cell{2}{I} \blank{6.1}{4} \blank{2}{5}
\cell{4.1}{J} \cell{6.1}{K} \cell{2}{L}
\rule{12\cellW}{0pt}% right justify last line (I miss \hshrink)
}}
\结束{文档}
这是使用 Tikz 的版本。使用“右上方”将 (x,y) 位置放在左下角,而不是中心。
\documentclass{article}
\usepackage{tikz}
\newlength{\cellH}% cell height
\setlength{\cellH}{.8cm}
\newlength{\cellW}% cell width (1 unit)
\setlength{\cellW}{.8cm}
\newcommand{\cell}[3]% #1 = border, #2 = width, #3 = text
{node[draw=#1,minimum width=#2\cellW]{#3}}
\pgfsetxvec{\pgfpoint{\cellW}{0cm}}% x coordinate
\pgfsetyvec{\pgfpoint{0cm}{\cellH}}% y coordinate
\begin{document}
\begin{center}
\begin{tikzpicture}
\path[every node/.style={minimum height=\cellH, above right}]
(0,4.4) \cell{black}{7.65}{A}
(7.75,4.4) \cell{black}{4.65}{B}
(0,3.3) \cell{white}{6}{1}
(6.2,3.3) \cell{black}{3}{C}
(9.4,3.3) \cell{white}{3}{2}
(0,2.2) \cell{black}{2}{D}
(2.1,2.2) \cell{black}{3}{E}
(5.2,2.2) \cell{black}{3}{F}
(8.3,2.2) \cell{black}{2}{G}
(10.4,2.2) \cell{black}{2}{H}
(0,1.1) \cell{white}{2}{3}
(2.1,1.1) \cell{black}{2}{I}
(4.2,1.1) \cell{white}{6.1}{4}
(10.4,1.1) \cell{white}{2}{5}
(0,0) \cell{black}{4.1}{J}
(4.2,0) \cell{black}{6.1}{K}
(10.4,0) \cell{black}{2}{L};
\end{tikzpicture}
\end{center}
\end{document}
答案2
我不是 100% 满意@John Kormylo的回答,所以我继续寻找解决方案。
这个答案经过@Qrrbrbirlbel参考名为“node-families”的 TikZ 库(下载这里) 为样式\node
s 引入了新的键:特别Minimum Width=someAlias
是确保具有该属性的所有节点都具有相同的最小宽度(并且如果其他样式选项相同,则实际上具有相同的总宽度)。
这是我的解决方案(MWE):
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning,node-families,calc,matrix,fit}
\begin{document}
\begin{center}
\begin{tikzpicture}[node distance=3pt,
base/.style={
rounded corners,
font={\sffamily\bfseries},
align=center,
},
block/.style={
base,
draw=black,
fill=orange,
font={\small\sffamily\bfseries\color{white}},
inner sep=3pt,
},
overlap/.style={
minimum width=1.5em,
%draw=red, %enable to aid during construction
},
group/.style={
inner sep=0,
%draw=black, %enable to aid during construction
},]{
{%row3
\node[block, Minimum Height=row3] (d) {D};
\node[block, right=of d, Minimum Height=row3, Minimum Width=e_iIOverlapRGroup] (e) {E};
\node[block, right=of e, Minimum Height=row3, Minimum Width=cOverlapGroup_c_f] (f) {F};
\node[block, right=of f, Minimum Height=row3] (g) {G};
\node[block, right=of g, Minimum Height=row3, Minimum Width=h_l] (h) {H};
}
{%row2
\node[block, above=of f, Minimum Height=row2, Minimum Width=cOverlapGroup_c_f] (c) {C};
}
{%row1
%helper nodes
\node[overlay, above=of c.north west, anchor=south west, Minimum Height=row1] (cOverlapL) {};
\node[overlay, right=of cOverlapL, Minimum Height=row1] (cOverlapR) {};
\node[group, fit=(cOverlapL)(cOverlapR), above=of c, Minimum Height=row1, Minimum Width=cOverlapGroup_c_f] (cOverlapGroup) {};
%block nodes
\node[block, left=of cOverlapGroup.center, xshift=1.5pt, Minimum Height=row1, Minimum Width=a_aDGroup] (a) {A};
\node[block, right=of a, Minimum Height=row1, Minimum Width=b_bAGroup] (b) {B};
%more helper nodes
\node[group, fit=(a)(d), Minimum Width=a_aDGroup] (aDGroup) {};
\node[group, fit=(b)(h), Minimum Width=b_bAGroup] (bHGroup) {};
}
{%row4
%block nodes
\node[block, below=of e.south west, anchor=north west, Minimum Height=row4] (i) {I};
%helper nodes
\node[overlap, right=of i, Minimum Height=row4] (iOverlapR) {};
\node[group, fit=(i)(iOverlapR), below=of e, Minimum Height=row4, Minimum Width=e_iIOverlapRGroup] (iIOverlapRGroup) {};
\node[group, fit=(d)(i), Minimum Width=dIGroup_j] (dIGroup) {};
\node[group, fit=(iOverlapR)(g), Minimum Width=iOverlapRGGroup_k] (iOverlapRGGroup) {};
}
{%row5
\node[block, below=of dIGroup, Minimum Height=row5, Minimum Width=dIGroup_j] (j) {J};
\node[block, right=of j, Minimum Height=row5, Minimum Width=iOverlapRGGroup_k] (k) {K};
\node[block, right=of k, Minimum Height=row5, Minimum Width=h_l] (l) {L};
}
}
\end{tikzpicture}
\end{center}
\end{document}
不过,正如@Qrrbrbirlbel 所描述的那样,使用这些属性需要您编译文档几次。对我来说,这不是问题,因为我的文档无论如何都必须编译几次才能正确获取所有(交叉)引用、附录等。
下面,您可以看到我的示例正确运行所需的三次运行:
第 1 次运行:
第二次运行:
第三次运行: