tikz-qtree 및 tikz를 사용하여 트리 외부에 노드를 추가하고 노드에 화살표 그리기

tikz-qtree 및 tikz를 사용하여 트리 외부에 노드를 추가하고 노드에 화살표 그리기

문장을 설명하는 그림을 그리려고 노력해요

dass er das Lied wird haben singen müssen

그 사람은 노래를 부르게 될 거야

아이디어는 문장을 작성하고 어떤 동사가 다른 동사를 지배하는지에 대한 지배 관계를 보여주는 아래 코드의 트리를 갖는 것입니다. 나는 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-1됩니다 M-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.

체인 에는 Umlaut 또는 Eszett가 있는 항목에 대해 sentence부품 daß er das Lied, wird, haben, singen, 을 배치하기만 하면 됩니다.können안전한그것들 없이 이름을 지정하세요(다른 솔루션도 가능하지만 그렇게 하면 해당 노드에 액세스하기가 더 어려워집니다). 루프 \Name에서 a를 지정하지 않으면 텍스트가 단순히 사용됩니다.\foreach\Item

.3333em노드가 문장 내에서 배치되는 것처럼 수평 노드 거리가 설정됩니다. 이를 위해 inner xsep및 the outer xsep도 0으로 설정합니다. 문장과 겹치도록 다른 노드를 배치하여 이 동작을 확인할 수 있습니다.

\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기본 크기의 절반입니다. 또한 0으로 설정 됩니다 outer ysep(그려진 노드가 없습니다).

수직 체인의 노드는 join옵션(스타일 사용 every join)에 의해 자동으로 연결됩니다. 문장의 노드에 대한 연결도 두 번째 루프에서 이루어집니다.

특수 arc and line스타일을 사용하면 호의 크기가 가능한 가장 큰 반경을 갖는 1/4원 크기가 됩니다. 그러나 선택적 arc and line maximum값을 할당할 수 있습니다.

arc and line maximum매우 작은 값 6pt(예: 기본값 )으로 설정하면 모서리가 둥근 rounded corners기본 경로를 모방할 수 있습니다 . 도서관이나 그런 것들이 -|필요하지 않습니다 . 0으로 설정 하면 날카로운 모서리가 있는 기본 경로를 얻습니다. 위와 같이 우리는 그러한 계산이 필요하지 않습니다.calclet … 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}

여기에 이미지 설명을 입력하세요

관련 정보