情况1

情况1

代码:

\[
\begin{tikzcd}[cells={nodes={draw=gray}}]
    \text{Math is excellent!} \ar[r, rightarrow] \ar[d, leftarrow]
        & \text{w} \ar[d, rightarrow]\\
    \text{w} \ar[u, rightarrow] \ar[r, leftarrow]
        & \text{Pythagoreans killed someone!}
\end{tikzcd}
\]

输出:

在此处输入图片描述

要求:我正在尝试实现这样的目标:

在此处输入图片描述

  1. 我知道情况 1 是不可能的,因为列(和行)是通过居中单元格形成的。

  2. 因此,我尝试实现似乎可以实现的案例 2。具体来说,我尝试这样做:

    • 使同一列中单元格的宽度相等。
    • 然后以某种方式在那个单元格上写字在特定地点。(左对齐在右上角,右对齐在左下角。)

笔记:我故意写“在特定地点”,而不仅仅是左对齐和右对齐的特殊情况。

可以这样做吗?(我想过使用\phantom。但在这种情况下,这显然会产生粗略的结果。)

我知道如何修改箭头锚点,所以这不是问题。

答案1

只是为了让你知道如何在普通的 Ti 中做到这一点Z,即使这不是你想要的:

四个节点和箭头

\documentclass[12pt]{article}
\usepackage{tikz}
\usetikzlibrary{positioning, arrows.meta}

\begin{document}

    \begin{tikzpicture}[
            node distance = 2cm and 5cm,
            every node/.style = {
                rectangle,
                draw,
                inner sep = 5pt,
                minimum size = 1cm},
            > = {Straight Barb}
            ]
        \node[left] (A) {Math is excellent!};
        \node[right, right= of A] (B) {w};
        \node[below = of A.east, anchor = east] (C) {w};
        \node[below = of B.west, anchor = west] (D) {Pythagoreans kill someone!};
        
        \path[->]
            (A) edge (B)
            (B.south) edge (D.north-|B)
            (D) edge (C)
            (C.north) edge (A.south-|C);
    \end{tikzpicture}

\end{document}

有更好的方法可以做到这一点(但更复杂),所以我只写了一个简单的代码。

答案2

这是一个tikz-cd解决方案。想法是使用\fcolorbox绘制文本周围的框,并\llap使用\rlap控制箭头的位置。框颜色由 全局控制\cdboxcolor,设置为灰色。

定义新命令\leftbox\rightbox并且\cdbox

\leftbox{<dim>}{<text>}放置<text>在一个向左移动的框中,因此tikzcd箭头瞄准时好像框有宽度<dim>而不是其实际宽度。\rightbox定义类似。\cdbox{<text>}不变。

在此处输入图片描述

\documentclass{article}

\usepackage{tikz-cd,amsmath}

\newcommand{\cdboxcolor}{gray}
\newcommand{\leftbox}[2]{\hspace{#1}\llap{\fcolorbox{\cdboxcolor}{white}{#2}}}
\newcommand{\rightbox}[2]{\rlap{\fcolorbox{\cdboxcolor}{white}{#2}}\hspace{#1}}
\newcommand{\cdbox}[1]{\fcolorbox{\cdboxcolor}{white}{#1}}

\begin{document}

\[
\begin{tikzcd}[cells={nodes={inner sep=0pt}}]
    \leftbox{1cm}{Math is excellent!} \ar[r, rightarrow] \ar[d, leftarrow]
        & \cdbox{w} \ar[d, rightarrow]\\
    \cdbox{w} \ar[u, rightarrow] \ar[r, leftarrow]
        & \rightbox{1cm}{Pythagoreans killed someone!}
\end{tikzcd}
\]

\end{document}

答案3

我不太清楚你的意思

笔记:我故意写“在特定地点”,而不仅仅是左对齐和右对齐的特殊情况。

还有哪些类型的排列?

情况1

情况 1 其实是最简单的。

  1. 我知道情况 1 是不可能的,因为列(和行)是通过居中单元格形成的。

不是。它们通过坐标系对齐。 行对齐方式= 0,列对齐X= 0。不过,也存在一些陷阱。

由于每个节点默认放置在 (0, 0),因此您可以更改其锚点。默认情况下,a 中的所有节点都放置在其锚点处。matrix of math nodesbase

这意味着列水平居中,行按基线对齐。通过将其更改为base west或 ,base east我们可以强制左对齐或右对齐。

在第二张图中,我添加了一些xshift改变“在特定位置”位置的元素。

我正在使用我的ext.paths.ortho库,它提供了方便的样式,遵循问题和回答“Tikz:从 nodeA.south 到 nodeB.north 的纯垂直箭头”。快捷键*|代表only vertical second|*代表only vertical first

代码

\documentclass[varwidth]{standalone}
\usepackage{tikz-cd}
\tikzset{strut without depth/.style={text depth=+0pt, text height=+\ht\strutbox}}
\tikzcdset{
  column align/.is choice,
  @column align/.style n args={2}{column align/#1/.style={anchor={#2}}},
  @column align/.list={{left}{base west},{right}{base east},{center}{base}},
  colspec/.style={
    /utils/exec=\def\pgfmathresult{0},
    /utils/temp/.code={%
      \edef\pgfmathresult{\pgfinteval{\pgfmathresult+1}}%
      \pgfkeysalso{/tikz/column \pgfmathresult/.append style={
                     /tikz/commutative diagrams/column align/##1}}},
    /utils/temp/.list={#1}}}

\usetikzlibrary{ext.paths.ortho}
\begin{document}
\[
\begin{tikzcd}[
  cells={strut without depth, nodes={draw=gray}},
  math mode=false,
  /tikz/ortho/install shortcuts,
  colspec={right, left},
]
  Math is excellent!           \ar[r, rightarrow]
                               \ar[d, *|, leftarrow]
& w                            \ar[d, |*, rightarrow] \\
  w                            \ar[r, leftarrow]
& Pythagoreans killed someone!
\end{tikzcd}
\]
\[
\begin{tikzcd}[
  cells={strut without depth, nodes={draw=gray}},
  math mode=false,
  /tikz/ortho/install shortcuts,
  colspec={right, left},
]
  Math is excellent!           \ar[r, rightarrow]
                               \ar[d, *|, leftarrow]
& |[xshift=1cm]|   w           \ar[d, |*, rightarrow] \\
  |[xshift=-.5cm]| w           \ar[r, leftarrow]
& Pythagoreans killed someone!
\end{tikzcd}
\]
\end{document}

输出

在此处输入图片描述

案例 2

再次,通过纯粹的左、右和居中对齐,这是可能的。

这基本上与情况 1 相同,只是在实际内容周围有一个拟合节点,它使用我的ext.node-families图书馆

我添加了第三列和居中列来强调为什么from'和/或to'有必要在较小的节点和较大的节点之间切换。

我们甚至可以反转该切换(通过用 a 命名内部节点'而不用 a 命名绘制的节点)。

这使用自定义fit键(也只扫描一个节点),因为 TikZ-CD 使用特殊asymmetrical rectangle形状。对于除左/右/中心之外的其他对齐方式,即如上所示,需要xshift调整键。fit

我们也可以像我所做的那样我的答案为了 ”让两个节点占据一个节点的空间“您可以随意放置一个子节点,让它像一个真正的节点一样运行。

代码

\documentclass[varwidth]{standalone}
\usepackage{tikz-cd}
\tikzcdset{
  @column align/.style n args={4}{
    column align/#1/.style={
      anchor={#2}, /tikz/commutative diagrams/@make box of column/.style={
        anchor={#3}, at={(\tikzlastnode.#4)}}}},
  column align/.is choice,
  @column align/.list={
    {left}  {base west}{real west}  {real west},
    {right} {base east}{real east}  {real east},
    {center}{base}     {real center}{real center}},
  colspec/.style={
    /utils/exec=\def\pgfmathresult{0},
    /utils/temp/.code={%
      \edef\pgfmathresult{\pgfinteval{\pgfmathresult+1}}%
      \pgfkeysalso{/tikz/column \pgfmathresult/.append style={
                     /tikz/commutative diagrams/column align/##1}}},
    /utils/temp/.list={#1}},
  make box of column/.style={
    inner sep=+0pt, outer sep=+0pt, minimum size=+0pt,
    commutative diagrams/fit=\tikzlastnode,name=\tikzlastnode',
    node family/width=\tikzmatrixname-\the\pgfmatrixcurrentcolumn,
    commutative diagrams/@make box of column,
    append after command={(\tikzlastnode.south west) edge[
      commutative diagrams/column box/.try,to path={
        ([xshift=+.5\pgflinewidth,yshift=+.5\pgflinewidth]\tikztostart)
        rectangle([xshift=+-.5\pgflinewidth,yshift=+-.5\pgflinewidth]%
          \tikztotarget)}](\tikzlastnode.north east)}},
  make column box/.style={
    append after command={
      [every node/.code=]node[commutative diagrams/make box of column]{}}}}
\makeatletter
\tikzcdset{
  fit/.code={% tikz-cd uses an asymmetrical rectangle …
    \pgf@process{\pgfpointdiff{\pgfpointanchor{\tikz@pp@name{#1}}{west}}
                              {\pgfpointanchor{\tikz@pp@name{#1}}{east}}}%
    \pgfkeysalso{/tikz/text width/.expanded=+\the\pgf@x}%
    \pgf@process{\pgfpointdiff{\pgfpointanchor{\tikz@pp@name{#1}}{base}}
                              {\pgfpointanchor{\tikz@pp@name{#1}}{north}}}%
    \pgfkeysalso{/tikz/text height/.expanded=+\the\pgf@y}%
    \pgf@process{\pgfpointdiff{\pgfpointanchor{\tikz@pp@name{#1}}{south}}
                              {\pgfpointanchor{\tikz@pp@name{#1}}{base}}}%
    \pgfkeysalso{/tikz/text depth/.expanded=+\the\pgf@y}},
  from'/.code=\edef\tikzcd@ar@start{\tikzcd@ar@start'},
  to'/.code=\edef\tikzcd@ar@target{\tikzcd@ar@target'}}
\makeatother
\usetikzlibrary{ext.paths.ortho,ext.node-families,fit}
\begin{document}
\[
\begin{tikzcd}[
  cells={
    text depth=+0pt, text height=+.7em,% \strut without depth
    nodes={commutative diagrams/make column box}},
  math mode=false,
  /tikz/ortho/install shortcuts,
  colspec={right, left, center}
]
  Math is excellent!
    \ar[r, rightarrow]
    \ar[d, *|, leftarrow]
& w \ar[d, |*, rightarrow] \rar[from', to']
& Foo \\
  w \ar[r, leftarrow]
& Pythagoreans killed someone!
& Baaaaaaaaaar
\end{tikzcd}
\]
\end{document}

输出

在此处输入图片描述

答案4

谁告诉你案例 1 是不可能的?
当然,它是可能的,有tikz-cd,没有黑客攻击!
您可以 1) 使用\tikztostart(起点) 和\tikztotarget(终点);或 2) 命名一个节点;然后在to path或中使用它们from

这里有些例子:

\documentclass{article}
\usepackage{amsmath}
\usepackage{tikz-cd}

\begin{document}
Solution with node names and \verb|from|/\verb|to|:
\[
\begin{tikzcd}[
    cells={nodes={draw=gray}},
    /tikz/column 1/.append style={nodes={anchor=base east}},
    /tikz/column 2/.append style={nodes={anchor=base west}}
    ]
    |[alias=mathis]|\text{Math is excellent!}\ar[r]\ar[d, leftarrow, from={mathis.south -| secondw}] &
      |[alias=firstw]|\text{w}\ar[d, to={Pytha.north -| firstw}]\\
    |[alias=secondw]|\text{w}\ar[r, leftarrow] &   
      |[alias=Pytha]|\text{Pythagoreans killed someone!}
\end{tikzcd}
\]

Solution with node names and \verb|to path|:
\[
\begin{tikzcd}[
    cells={nodes={draw=gray}},
    /tikz/column 1/.append style={nodes={anchor=base east}},
    /tikz/column 2/.append style={nodes={anchor=base west}}
    ]
    |[alias=mathis]|\text{Math is excellent!}\ar[r]\ar[d, leftarrow, to path={(mathis.south -| secondw) -- (secondw)}] &
      |[alias=firstw]|\text{w}\ar[d, to path={ -- (Pytha.north -| firstw)}]\\
    |[alias=secondw]|\text{w}\ar[r, leftarrow] & 
      |[alias=Pytha]|\text{Pythagoreans killed someone!}
\end{tikzcd}
\]

Solution with \verb|\tikztostart|, \verb|\tikztotarget| and \verb|to path|:
\[
\begin{tikzcd}[
    cells={nodes={draw=gray}},
    /tikz/column 1/.append style={nodes={anchor=base east}},
    /tikz/column 2/.append style={nodes={anchor=base west}}
    ]
    \text{Math is excellent!}\ar[r]\ar[d, leftarrow, to path={(\tikztostart.south -| \tikztotarget) -- (\tikztotarget)}] &
      \text{w}\ar[d, to path={-- (\tikztotarget.north -| \tikztostart)}]\\
    \text{w}\ar[r, leftarrow] & \text{Pythagoreans killed someone!}
    \end{tikzcd}
\]

Mixed:
\[
\begin{tikzcd}[
    cells={nodes={draw=gray}},
    /tikz/column 1/.append style={nodes={anchor=base east}},
    /tikz/column 2/.append style={nodes={anchor=base west}}
    ]
    |[alias=first]|\text{Math is excellent!}\ar[r]\ar[d, leftarrow, from={first.south -| second}] &
      \text{w}\ar[d, to path={-- (\tikztotarget.north -| \tikztostart)}]\\
    |[alias=second]|\text{w}\ar[r, leftarrow] & \text{Pythagoreans killed someone!}
\end{tikzcd}
\]
\end{document}

在此处输入图片描述

请参阅此处第 2.4 节以获取更多信息:https://tug.org/TUGboat/tb43-1/tb133duck-tikz-cd.pdf

相关内容