使用 Tikz 设置元素的位置

使用 Tikz 设置元素的位置

最近我问了一个关于“在表格中正确插入图像“,我得到了很好的答案。我决定采用已接受的答案,但现在我又遇到了另一个问题。我以为这是一个小问题,但在回答者的指导下,我决定再问一个问题。

之前我问过像这样的表格(图片)并且一切都运行正常。

但我的目的,我并没有在这个问题中具体说明,是要“连续”地做到这一点。基本上,现在我想重复 6 次,但使用只有两行. 类似这样(灰色区域是为了帮助你区分):

在此处输入图片描述

不幸的是,我得到的结果是:

在此处输入图片描述

我的问题是:我是否需要手动设置这些“Foo”的位置,不断尝试(无数次)直到我得到正确的位置?难道没有更精确的方法吗?

代码(对于最后一个例子)如下:

\documentclass[12pt]{book}

\usepackage[utf8]{inputenc}
\usepackage[a4paper,landscape]{geometry}
\usepackage{graphicx}
\usepackage{array}
\usepackage{tikz}
\usetikzlibrary{calc,shapes}

\newcommand{\tikzmark}[1]{\tikz[overlay,remember picture] \node (#1) {};}

\newcommand{\DrawLines}[2]{%
  \begin{tikzpicture}[overlay,remember picture,shorten >=1pt,shorten <=2pt, thick]
    \draw[#1] (a.north) to (b.north west);
    \draw[#2] (a.north) to (c.north west);
    \draw[#1] (d.north) to (e.north west);
    \draw[#2] (d.north) to (f.north west);
    \draw[#1] (g.north) to (h.north west);
    \draw[#2] (g.north) to (i.north west);
    \draw[#1] (l.north) to (m.north west);
    \draw[#2] (l.north) to (n.north west);
    \draw[#1] (o.north) to (p.north west);
    \draw[#2] (o.north) to (q.north west);
    \draw[#1] (r.north) to (s.north west);
    \draw[#2] (r.north) to (t.north west);
  \end{tikzpicture}
}

\pagestyle{empty}
\begin{document}

\setlength{\extrarowheight}{5pt}
\raisebox{12pt}{Foo\tikzmark{a}}\hspace*{1.0cm}
\raisebox{24pt}{Foo\tikzmark{d}}\hspace*{1.0cm}
\raisebox{-10pt}{Foo\tikzmark{g}}\hspace*{1.0cm}
\raisebox{-48pt}{Foo\tikzmark{l}}\hspace*{1.0cm}
\raisebox{0pt}{Foo\tikzmark{o}}\hspace*{1.0cm}
\raisebox{-48pt}{Foo\tikzmark{r}}\hspace*{1.0cm}

    \begin{tabular}{ r l l l l l }
    & A & B & C & D \\ \cline {2-6}
    \tikzmark{b}1 & foo A1 & foo B1 & foo C1 & foo D1  \\
    \tikzmark{c}2 & foo A2 & foo B2 & foo C2 & foo D2  \\
    \tikzmark{e}1 & foo A1 & foo B1 & foo C1 & foo D1  \\
    \tikzmark{f}2 & foo A2 & foo B2 & foo C2 & foo D2  \\ 
    \tikzmark{h}1 & foo A1 & foo B1 & foo C1 & foo D1  \\
    \tikzmark{i}2 & foo A2 & foo B2 & foo C2 & foo D2  \\
    \tikzmark{m}1 & foo A1 & foo B1 & foo C1 & foo D1  \\
    \tikzmark{n}2 & foo A2 & foo B2 & foo C2 & foo D2  \\
    \tikzmark{p}1 & foo A1 & foo B1 & foo C1 & foo D1  \\
    \tikzmark{q}2 & foo A2 & foo B2 & foo C2 & foo D2  \\
    \tikzmark{s}1 & foo A1 & foo B1 & foo C1 & foo D1  \\
    \tikzmark{t}2 & foo A2 & foo B2 & foo C2 & foo D2  \\
\end{tabular}
\DrawLines{black}{black}
\end{document}

答案1

需要注意的是,所讨论文本的位置是不是与 TikZ 完全相关。

@AlanMunn 提供的解决方案multirow可能是放置Foo文本的一种更简单的方法,另一种方法是给列做一个单独的表foo

但是,既然我知道您实际上想要如何使用它,我还建议更改语法以\DrawLines 采用 4 个参数:

\DrawLines[<color>]{<left point>}{<right point 1>}{<right point 2>}

其中第一个参数现在是可选的(如果未指定,则默认为黑色)。其他三个参数指定起点和两个终点。使用此语法,当您添加更多行时,您无需调整宏\DrawLines,并且可以为每个点分别选择样式。

给 a 起的名字\tikxmark是任意的(句号会引起问题),所以我用Foo<letter>它标记foo点。你应该使用更有意义的名字。

默认行为是下面的第一种情况,其他情况只是为了说明一些选项:

在此处输入图片描述

代码:

\documentclass[12pt]{book}

\usepackage[utf8]{inputenc}
\usepackage[a4paper,landscape]{geometry}
\usepackage{graphicx}
\usepackage{array}
\usepackage{tikz}
\usetikzlibrary{calc,shapes}

\newcommand{\tikzmark}[1]{\tikz[overlay,remember picture] \node (#1) {};}

\newcommand{\DrawLines}[4][]{%
  \begin{tikzpicture}[overlay,remember picture,shorten >=1pt,shorten <=1pt, thick]
    \draw[black,#1] (#2.north) to (#3.north west);
    \draw[black,#1] (#2.north) to (#4.north west);
  \end{tikzpicture}
}

\pagestyle{empty}
\begin{document}

\setlength{\extrarowheight}{5pt}
\noindent
\begin{tabular}{ r}
    \\ \\
    Foo\tikzmark{Fooa}\\ \\
    Foo\tikzmark{Foob}\\ \\
    Foo\tikzmark{Fooc}\\ \\
    Foo\tikzmark{Food}\\ \\
    Foo\tikzmark{Fooe}\\ \\
    Foo\tikzmark{Foof}\\ \\
\end{tabular}
%
\hspace*{1.0cm}%
%
\begin{tabular}{ r l l l l l }
    & A & B & C & D \\ \cline {2-6}
    \tikzmark{a}1 & foo A1 & foo B1 & foo C1 & foo D1  \\ 
    \tikzmark{b}2 & foo A2 & foo B2 & foo C2 & foo D2  \\ 
    \tikzmark{c}1 & foo A1 & foo B1 & foo C1 & foo D1  \\
    \tikzmark{d}2 & foo A2 & foo B2 & foo C2 & foo D2  \\ 
    \tikzmark{e}1 & foo A1 & foo B1 & foo C1 & foo D1  \\
    \tikzmark{f}2 & foo A2 & foo B2 & foo C2 & foo D2  \\
    \tikzmark{g}1 & foo A1 & foo B1 & foo C1 & foo D1  \\
    \tikzmark{h}2 & foo A2 & foo B2 & foo C2 & foo D2  \\
    \tikzmark{i}1 & foo A1 & foo B1 & foo C1 & foo D1  \\
    \tikzmark{j}2 & foo A2 & foo B2 & foo C2 & foo D2  \\
    \tikzmark{k}1 & foo A1 & foo B1 & foo C1 & foo D1  \\
    \tikzmark{l}2 & foo A2 & foo B2 & foo C2 & foo D2  \\
\end{tabular}
%
\DrawLines{Fooa}{a}{b}% default behavior
\DrawLines[red,  thick         ]{Foob}{c}{d}
\DrawLines[blue, thick, ->     ]{Fooc}{e}{f}
\DrawLines[green, thick, -latex]{Food}{g}{h}
\DrawLines[brown, dashed       ]{Fooe}{i}{j}
\DrawLines[thick, dotted       ]{Foof}{k}{l}
\end{document}

答案2

我将使用该multirow包来放置跨越两行的初始文本。

\documentclass[12pt]{book}

\usepackage[utf8]{inputenc}
\usepackage[a4paper,landscape]{geometry}
\usepackage{graphicx}
\usepackage{array}
\usepackage{tikz}
\usetikzlibrary{calc,shapes}
\usepackage{multirow}
\newcommand{\tikzmark}[1]{\tikz[overlay,remember picture] \node (#1) {};}

\newcommand{\DrawLines}[2]{%
  \begin{tikzpicture}[overlay,remember picture,shorten >=1pt,shorten <=2pt, thick]
    \draw[#1] (a.north) to (b.north west);
    \draw[#2] (a.north) to (c.north west);
    \draw[#1] (d.north) to (e.north west);
    \draw[#2] (d.north) to (f.north west);
    \draw[#1] (g.north) to (h.north west);
    \draw[#2] (g.north) to (i.north west);
    \draw[#1] (l.north) to (m.north west);
    \draw[#2] (l.north) to (n.north west);
    \draw[#1] (o.north) to (p.north west);
    \draw[#2] (o.north) to (q.north west);
    \draw[#1] (r.north) to (s.north west);
    \draw[#2] (r.north) to (t.north west);
  \end{tikzpicture}
}

\pagestyle{empty}
\begin{document}

\begin{tabular}{p{.75in}lllll}

 &  &  A  &  B  &  C  &  D  \\
\multirow{2}{*}{foo\tikzmark{a}} &     \tikzmark{b}1  &  foo A1  &  foo B1  &  foo C1  &  foo D1  \\
 &     \tikzmark{c}2  &  foo A2  &  foo B2  &  foo C2  &  foo D2  \\
\multirow{2}{*}{foo\tikzmark{d}} &     \tikzmark{e}1  &  foo A1  &  foo B1  &  foo C1  &  foo D1  \\
 &     \tikzmark{f}2  &  foo A2  &  foo B2  &  foo C2  &  foo D2  \\
\multirow{2}{*}{foo\tikzmark{g}} &     \tikzmark{h}1  &  foo A1  &  foo B1  &  foo C1  &  foo D1  \\
 &     \tikzmark{i}2  &  foo A2  &  foo B2  &  foo C2  &  foo D2  \\
\multirow{2}{*}{foo\tikzmark{l}} &     \tikzmark{m}1  &  foo A1  &  foo B1  &  foo C1  &  foo D1  \\
 &    \tikzmark{n}2  &  foo A2  &  foo B2  &  foo C2  &  foo D2  \\
\multirow{2}{*}{foo\tikzmark{o}} &     \tikzmark{p}1  &  foo A1  &  foo B1  &  foo C1  &  foo D1  \\
 &     \tikzmark{q}2  &  foo A2  &  foo B2  &  foo C2  &  foo D2  \\
\multirow{2}{*}{foo\tikzmark{r}} &     \tikzmark{s}1  &  foo A1  &  foo B1  &  foo C1  &  foo D1  \\
 &     \tikzmark{t}2  &  foo A2  &  foo B2  &  foo C2  &  foo D2  \\

\end{tabular}

\DrawLines{black}{black}
\end{document}

代码输出

答案3

由于 Alan 和 Peter 已经很好地回答了这个问题,我可以提出我的矩阵解决方案,只是为了好玩(是的,再一次!:P)

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{matrix,calc}
\begin{document}    
\begin{tikzpicture}
\matrix[matrix of nodes] (footable) {
    & A & B & C & D \\
1 & foo A1 & foo B1 & foo C1 & foo D1  \\
2 & foo A2 & foo B2 & foo C2 & foo D2  \\
1 & foo A1 & foo B1 & foo C1 & foo D1  \\
2 & foo A2 & foo B2 & foo C2 & foo D2  \\ 
1 & foo A1 & foo B1 & foo C1 & foo D1  \\
2 & foo A2 & foo B2 & foo C2 & foo D2  \\
1 & foo A1 & foo B1 & foo C1 & foo D1  \\
2 & foo A2 & foo B2 & foo C2 & foo D2  \\
1 & foo A1 & foo B1 & foo C1 & foo D1  \\
2 & foo A2 & foo B2 & foo C2 & foo D2  \\
1 & foo A1 & foo B1 & foo C1 & foo D1  \\
2 & foo A2 & foo B2 & foo C2 & foo D2  \\
};
\draw (footable-2-1.north west) -- (footable-2-5.north east);
\foreach \x in {2,4,...,12}{
\pgfmathtruncatemacro{\xinc}{\x+1}
\node (Foo\x)  at ([xshift=-15mm]$(footable-\x-1.west)!0.5!(footable-\xinc-1.west)$) {Foo};%*
\draw (Foo\x.east) -- (footable-\x-1.west);
\draw (Foo\x.east) -- (footable-\xinc-1.west);
};
\end{tikzpicture}
\end{document}

在标有 的行处用 替换为更大的节点文本{Foo}。此外,您还可以在循环中包含 Peter 的漂亮风格选择,以进一步充实线条。{\Large Foo}%*foreach

在此处输入图片描述

相关内容