使用 tikz-qtree 和 tikz 在树外添加节点并向其绘制箭头

使用 tikz-qtree 和 tikz 在树外添加节点并向其绘制箭头

我试着画一幅图来解释这句话

这首歌必须被唱出来

他将要唱的歌必须

这个想法是写下句子,并从下面的代码中得到树,显示支配关系,即哪个动词支配哪个其他动词。在 singen 的右侧,我想为 müssen 添加一个节点,在它的左侧为 haben 添加一个节点,在 haben 的左侧为 wird 添加一个节点。树中的动词应该用箭头连接到这些节点。这可能吗?我尝试了一些方法(参见代码),但新节点没有出现在与 singen 相同的基线上。

也许我必须以其他方式重新绘制所有内容?

    \documentclass{article}

\usepackage{tikz-qtree}

\begin{document}

\begin{tikzpicture}
\Tree [.wird
          [.haben
              [.muessen singen ] ] ] \node[anchor=east]{muessen}; 
\end{tikzpicture}

\end{document}

它看起来应该是这样的:

在此处输入图片描述

答案1

一个简单的想法:在 中排版你的句子matrix of nodes。这种 tikz 对象会自动为其每个组件分配一个名称。在下面的例子中,我将矩阵命名为M,因此第一行(也是唯一一行)的元素被命名为M-1-1M-1-2依此类推。这使得在 上添加更多单词M-1-7并建立连接变得容易:

\usetikzlibrary{matrix, positioning}
\begin{tikzpicture}[shorten >=1mm]
\matrix[name=M, matrix of nodes, inner sep=0pt, column sep=1ex]{
  dass & er & das & Lied & wird & haben & singen & m\"ussen \\
};

\node [anchor=base, above=2em of M-1-7.base]  (mussen) {m\"ussen};
\node [anchor=base, above=2em of mussen.base] (haben)  {haben};
\node [anchor=base, above=2em of haben.base]  (wird)   {wird};
\draw[->] (wird)   to[out=180,in=90] (M-1-5);
\draw[->] (haben)  to[out=180,in=90] (M-1-6);
\draw[->] (mussen) to[out=0,in=90]   (M-1-8);
\draw (wird) --(haben) -- (mussen) -- (M-1-7);
\end{tikzpicture}

结果

答案2

嗯,树看起来不对劲。链条怎么样?

我们安装两条链:

  1. 链条sentence向右走sentence going base right,,
  2. 鏈子verbs上行,verbs going above

在链条上,sentence我们只需放置零件daß er das Lied,,,,,对于带有变音符号或 Eszett 的物品,我们分配wird一个habensingenkönnen安全的名称而不使用它们(可能还有其他解决方案,但这些解决方案会使访问这些节点变得更加困难)。如果我们不在循环\Name中指定,则将简单地使用文本。\foreach\Item

水平节点距离的.3333em设置使得节点的放置方式与句子中的放置方式相同,为此我们还将 和 设置inner xsep为零outer xsep。您可以通过放置另一个节点使其与句子重叠来检查此行为:

\node[anchor=text] at (sentence-begin.text) {da\ss\space er das Lied wird haben singen k\"onnen};

node distance的垂直部分1.5\baselineskip是随机选择的,是inner ysep默认大小的一半。outer ysep也设置为零(我们没有绘制任何节点)。

垂直链的节点由join选项(使用样式every join)自动连接。与句子中节点的连接也在第二个循环中进行。

特殊arc and line样式确保圆弧具有四分之一圆的大小,且半径尽可能大。arc and line maximum不过,可以分配一个可选值。

如果我们将其设置arc and line maximum为一个非常小的值,比如说6pt(默认值rounded corners),我们可以模拟-|具有上述圆角的基本路径。不需要calc库和let … in其他东西。
设置arc and line maximum为零,我们得到-|具有尖角的基本路径。像上面一样,我们不需要calc那些计算。

就我个人而言,我更喜欢半径较小的蓝色变体rounded corners

代码

\documentclass[tikz,convert=false]{standalone}
\usetikzlibrary{chains,calc}
\tikzset{
  /pgf/arc and line maximum/.initial=+1000pt,
  arc and line/.style={
    to path={
      let
        \p{@end}=(\tikztotarget.north),
        \p{@aux1}=($(\tikztostart)-(\p{@end})$),
        \p{@start}=(node cs: name=\tikztostart, anchor={\x{@aux1} < 0pt ? +0 : +180}),
        \n{@aux2}={min(\pgfkeysvalueof{/pgf/arc and line maximum},abs(\x{@start}-\x{@end}),abs(\y{@start}-\y{@end})-.1pt))}
      in
      { [rounded corners=\n{@aux2}] -| (\tikztotarget) }
    }},
  special curve 0/.style={draw,->,arc and line},
  special curve 1/.style={
    special curve 0,
    arc and line maximum=+6pt},
  special curve 2/.style={
    special curve 0,
    arc and line maximum=+0pt},
  every sentence and verb node/.style={
    inner ysep=+.1667em,
    outer ysep=+0pt},
  sentence node/.style={
    every sentence and verb node,
    inner xsep=+0pt,
    outer xsep=+0pt,
    on chain=#1},
  sentence node/.default=sentence,
  verb node/.style={
    every sentence and verb node,
    on grid,
    text depth=+0pt,
    join,
    on chain=#1},
  verb node/.default=verbs
}
\begin{document}
\begin{tikzpicture}[
  node distance=1.5\baselineskip and width(" ")*1pt,
  start chain=sentence going base right,
  start chain=verbs going above,
  every join/.style={draw}
]
\foreach \Item/\Name in {da\ss\space er das Lied/dass,wird,haben,singen,k\"onnen/konnen}
  \node [sentence node, alias=s-\Name] {\Item};
\chainin[on chain=verbs] (s-singen);
\foreach \Item/\Name in {k\"onnen/konnen,haben,wird} {
  \node [verb node, alias=v-\Name] {\Item}
    edge[special curve 2,green] (s-\Name)
    edge[special curve 1,blue]  (s-\Name)
    edge[special curve 0]       (s-\Name);
}
\end{tikzpicture}
\end{document}

输出

在此处输入图片描述

答案3

如果您\usetikzlibrary{positioning},您可以根据其他节点定义节点。因此,如果您在树内定义节点,则可以将树外的节点相对于树内的节点定位。这意味着您必须手动调整间距,但它确实提供了一个解决方案。这是一个适合您的 MWE:

更新: 正如@Qrrbrbirlbel 在评论中指出的那样,'singen' 中的 'g' 会破坏节点相对于彼此的垂直对齐。下面已通过使用base leftbase right将节点彼此对齐来修复此问题。

\documentclass{article}

\usepackage{qtree}
\usepackage{tikz}
\usepackage{tikz-qtree,tikz-qtree-compat}
\tikzset{every tree node/.style={align=center, anchor=north}}
\usetikzlibrary{positioning}

\begin{document}

\begin{tikzpicture}

\Tree [.\node(1){wird};
          [.\node(2){haben};
              [.\node(3){m\"{u}ssen}; \node(4){singen}; ] ] ]

\node(5)[base left=1.9cm of 4]{dass er das Lied};
\node(6)[base left=1.1cm of 4]{wird};
\node(7)[base left=.1cm of 4]{haben};
\node(8)[base right=.1cm of 4]{m\"{u}ssen};
\draw[->] (1)..controls +(west:1) and +(north:1)..(6);
\draw[->] (2)..controls +(west:1) and +(north:1)..(7);
\draw[->] (3)..controls +(east:1) and +(north:1)..(8);

\end{tikzpicture}

\end{document}

在此处输入图片描述

相关内容