解决方案“复杂”

解决方案“复杂”

我正在尝试制作一个 tikz 图,其中我可以将带有长文本的节点一个接一个地放置,这样我就可以指定要居中的部分(然后拖动这些部分之外的内容)并使用垂直箭头连接居中部分的中心。

这有点混乱,所以举个例子,我想要这样的东西:

\begin{tikzpicture}
\node (a) at (0,1) {really long stuff \centerthis{blahh} other stuff};
\node (b) at (0,0) {more stuff \centerthis{blah blah blah} possibly other stuff};
\draw[->] (a) -- (b);
\end{tikzpicture}

自动生成以下代码:

            really long stuff (blahh) other stuff
                                 |
                                 |
                                 v
               more stuff (blah blah blah) possibly other stuff

因此 的中心(blahh)位于 (0,1) 并且 的中心(blah blah blah)位于 (0,0)。

我在解决方案中寻找的主要内容是

  • 我想避免任何距离或尺寸的手动调整。
  • 我希望所有内容都出现在同一个基线上。例如,我尝试制作 6 个节点,分别用于左上、左下、中间和右,当其中一个节点有下降项而其他的则没有,这看起来不对劲。也许有办法解决这个问题?

抱歉,我没有更多可以提供,但我就是被困在这个问题上了。当然,上面我使用的假设代码只是一个想法,如果你看到其他解决方案(我相信有很多),也请发布它。

答案1

如果你能用 6 个节点(几乎)正确对齐

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning}
\begin{document}
\begin{tikzpicture}[every node/.style={outer sep=0,inner sep=0,text depth=0.3ex},
                    node distance=0.3em]
\node (a) at (0,1) {Blaaaahh};
\node[left=of a.west] {really long stuff};
\node[right=of a.east] {other stuff};

\node[below= 1 cmof a] (b) {blah blah blah};
\node[left=of b.west] {asymmetric};
\node[right=of b.east] {lipsum stuff};
\draw[-latex] (a) -- (b);
\end{tikzpicture}
\end{document}

在此处输入图片描述

否则,\tikzmark答案可能就在眼前。

答案2

解决方案“复杂”

此解决方案计算两个节点必须移动的量xshift,以使中心部分的中间部分位于该at (x,y)点上。然后,
这些xshift量再次用于要绘制的箭头。

该解决方案使用calc包装。

该解决方案提供:

  • Style CenterLCRa/b接受三个参数:
    1. 文本的左侧部分,
    2. 文本的中心部分(仅用于 的定义\LCR,见下文)和
    3. 文本的正确部分。
  • \LCR使用样式CenterLCRa/后设置的宏b。它仅包含节点的文本,因此无需再次输入。
  • LCR在(新)中心之间绘制线的路径样式。
  • 内部:长度\WidthOfLeft\WidthOfRight\xShiftA/ B、宏\tikzCenterLCRa/b和 TikZ 样式centerLCRa/b

代码

\documentclass[tikz,border=2pt]{standalone}
\usepackage{tikz,calc}
\newlength{\WidthOfLeft}
\newlength{\WidthOfRight}
\newlength{\xShiftA}
\newlength{\xShiftB}

\newcommand{\tikzCenterLCRa}[3]{% #1 = L, #2 = C, #3 = R
    \setlength{\WidthOfLeft}{\widthof{#1}}%
    \setlength{\WidthOfRight}{\widthof{#3}}%
    \setlength{\xShiftA}{-.5\WidthOfLeft+.5\WidthOfRight}
    \global\xShiftA=\xShiftA\relax%
    \def\LCR{#1#2#3}
}
\newcommand{\tikzCenterLCRb}[3]{% #1 = L, #2 = C, #3 = R
    \setlength{\WidthOfLeft}{\widthof{#1}}%
    \setlength{\WidthOfRight}{\widthof{#3}}%
    \setlength{\xShiftB}{-.5\WidthOfLeft+.5\WidthOfRight}
    \global\xShiftB=\xShiftB\relax
    \def\LCR{#1#2#3}
}
\tikzset{
    centerLCRa/.code n args={3}{\tikzCenterLCRa{#1}{#2}{#3}},
    CenterLCRa/.style n args={3}{
        centerLCRa={#1}{#2}{#3},
        xshift=\the\xShiftA
    },
    centerLCRb/.code n args={3}{\tikzCenterLCRb{#1}{#2}{#3}},
    CenterLCRb/.style n args={3}{
        centerLCRb={#1}{#2}{#3},
        xshift=\the\xShiftB
    },
    LCR/.style={
        to path={
            ([xshift=-\the\xShiftA]\tikztostart) -- ([xshift=-\the\xShiftB]\tikztotarget) \tikztonodes
        }
    }
}

\begin{document}
\begin{tikzpicture}[every node/.style=draw]
\node[CenterLCRa={really long stuff }{xxx}{ other stuff}]             (a) at (0,1) {\LCR};
\node[CenterLCRb={more stuff }{blah xxx blah}{ possibly other stuff}] (b) at (0,0) {\LCR};
\draw[->] (a.south) to[LCR] (b.north);
\end{tikzpicture}
\end{document}

输出

经过大量计算的输出

“肮脏”的解决方案

节点大于其内容

该解决方案的缺点是使用的框比其内容更大,因此最终的节点将比平常更宽(边界框,draw机制)。

代码

\documentclass[tikz,border=2pt]{standalone}
\usepackage{calc}
\newlength{\WidthOfLeft}
\newlength{\WidthOfRight}
\newcommand{\centerLCR}[3]{%
    \settowidth{\WidthOfLeft}{#1}%
    \settowidth{\WidthOfRight}{#3}%
    \ifdim\WidthOfLeft<\WidthOfRight\relax%
        \setlength{\WidthOfLeft}{\WidthOfRight}%
    \fi%
    \makebox[\WidthOfLeft][r]{#1}#2\makebox[\WidthOfLeft][l]{#3}%
}
\begin{document}
\begin{tikzpicture}
\node (a) at (0,1) {\centerLCR{really long stuff }{blahh}{ other stuff}};
\node (b) at (0,0) {\centerLCR{more stuff }{blah blah blah}{ possibly other stuff}};
\draw[->] (a) -- (b);
\end{tikzpicture}
\begin{tikzpicture}[every node/.style=draw]
\node (a) at (0,1) {\centerLCR{really long stuff }{blahh}{ other stuff}};
\node (b) at (0,0) {\centerLCR{more stuff }{blah blah blah}{ possibly other stuff}};
\draw[->] (a) -- (b);
\end{tikzpicture}
\end{document}

输出

不带绘制的输出
带抽奖的输出

节点小于其内容

如果盒子使用较小的宽度,即

\ifdim\WidthOfLeft>\WidthOfRight\relax% > instead of <

那么边界框就更糟糕了。(请参见输出中截断的“她的东西”。)
如果这些节点周围有更多东西,这不会成为问题。

输出

不带绘制的子输出
带 draw 的子输出

相关内容