绘制森林树图中节点与其外部事物之间的连接

绘制森林树图中节点与其外部事物之间的连接

我无法将forest树形图内部的节点与其外部的任意文本连接起来。


梅威瑟:

\documentclass[12pt,paper=a4]{scrartcl}
\usepackage[linguistics]{forest}
\usetikzlibrary{positioning}

% cf. http://tex.stackexchange.com/a/1912/60686
\tikzstyle{na} = [shape=rectangle,inner sep=0pt,text depth=0pt]

\begin{document}

\begin{forest}
[A, name=A
    [B]
    [C
        [X, name=X]
        [Y]
    ]
]
\draw[-latex,dotted] (A) to[out=west,in=west] (X);
\end{forest}

\tikzstyle{every picture}+=[remember picture]
\tikz\node[na](lorem){Lorem}; ipsum \tikz\node[na](abc){dolor}; sit \tikz\node[na](amet){amet};.

\begin{tikzpicture}[overlay]
    \draw (X) to (abc);
    \draw[-latex] (lorem) to[out=south,in=south] (amet);
\end{tikzpicture}

\end{document}

不幸的是,上述代码的结果如下所示:

在此处输入图片描述

换句话说,tikz 似乎找不到节点X,所以线只是延伸到无处,而不是将X节点连接到abc节点。为了证明连接事物在任何一个图表或者在文本中,我也画了一堆箭头。

\tikzstyle{every picture}+=[remember picture]放置上面的线\begin{forest}会导致各种内容框和绘图都出现在不同的页面上。

答案1

\tikzmark在树内部使用的问题forest在于您正在嵌套tikzpicture环境,这有时有效,但永远不应依赖并且应始终避免(除非您真的知道自己在做什么并且乐于在它中断时保留所有的微小部分)。

幸运的是,tikzmark已经规定\subnode{}了此类情况。

  [A, name=A
    [B]
    [C
      [\subnode{x}{X}, name=X]
      [Y]
    ]
  ]

这解决了问题。

节点到节点 文本到文本 节点到文本

这里要记住的一点是,Forest 使用特殊的坐标系forest cs。但是,您只能在forest环境或\Forest宏中访问它。即使使用带星号的宏,似乎也是如此,\Forest*它允许您访问当前组之外的节点,例如从内部访问其他 forest环境或Forest[*]宏观。

完整代码:

\documentclass{article}
\usepackage[linguistics]{forest}
\usetikzlibrary{tikzmark,arrows.meta}
\begin{document}
\begin{forest}
  [A, name=A
    [B]
    [C
      [\subnode{x}{X}, name=X]
      [Y]
    ]
  ]
  \draw [-Latex,dotted] (A) to[out=west,in=west] (X);
\end{forest}

Lo\tikzmark{lorem}rem ipsum do\tikzmark{abc}lor sit am\tikzmark{amet}et.

\begin{tikzpicture}[remember picture, overlay]
    \draw [-Latex, red] (x) [out=-75, in=110]to ([yshift=1.5ex]{pic cs:abc});
    \draw [-Latex] ({pic cs:lorem}) to[out=south,in=south] ({pic cs:amet});
\end{tikzpicture}
\end{document}

答案2

好的,为了完整起见,这是我自己的改进cfr 的有用答案,考虑到对 Stefan Müller 之前关于同一主题的一个问题的评论。遗憾的是,那里提到的和这里采用的解决方法只是基本提及,但没有给出例子。

\documentclass{scrartcl}
\usepackage[linguistics]{forest}
\usetikzlibrary{positioning, tikzmark, arrows.meta}

% WORKAROUND:    
% Definition copied from /usr/share/texlive/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-common-pdf-via-dvi.def
% Compare https://tex.stackexchange.com/q/229500 and comments!
\makeatletter
\def\pgfsys@hboxsynced#1{%
  {%
    \pgfsys@beginscope%
    \setbox\pgf@hbox=\hbox{%
      \hskip\pgf@pt@x%
      \raise\pgf@pt@y\hbox{%
        \pgf@pt@x=0pt%
        \pgf@pt@y=0pt%
        \special{pdf: content q}%
        \pgflowlevelsynccm% 
        \pgfsys@invoke{q -1 0 0 -1 0 0 cm}%
        \special{pdf: content -1 0 0 -1 0 0 cm q}% translate to original coordinate system
        \pgfsys@invoke{0 J [] 0 d}% reset line cap and dash
        \wd#1=0pt%
        \ht#1=0pt%
        \dp#1=0pt%
        \box#1%
        \pgfsys@invoke{n Q Q Q}%
      }%
      \hss%
    }%
    \wd\pgf@hbox=0pt%
    \ht\pgf@hbox=0pt%
    \dp\pgf@hbox=0pt%
    \pgfsys@hbox\pgf@hbox%
    \pgfsys@endscope%
  }%
}
\makeatother

\begin{document}
\begin{forest}
  [A, name=A
    [B]
    [C
      [\subnode{x}{X}, name=X]
      [Y]
    ]
  ]
  \draw [-Latex,dotted] (A) to[out=west,in=west] (X);
\end{forest}

Lo\tikzmark{lorem}rem ipsum do\tikzmark{abc}lor sit am\tikzmark{amet}et.

\begin{tikzpicture}[remember picture, overlay]
    \draw [-Latex, red] (x) [out=-75, in=110]to ([yshift=1.5ex]{pic cs:abc});
    \draw [-Latex] ({pic cs:lorem}) to[out=south,in=south] ({pic cs:amet});
\end{tikzpicture}
\end{document}

这应该可以在 TeXLive 2016 下成功编译xelatex(以支持 Unicode):

编译 MWE 并定义解决方法

相关内容