LaTeX/TikZ 森林节点后面的背景图像

LaTeX/TikZ 森林节点后面的背景图像

我使用 forest 包绘制祖先树。我想为节点添加类似纸莎草卷轴的背景。这是基本示例:

\documentclass[]{standalone}
\usepackage{pgfplots}
\usepackage{forest}
\begin{document}
\begin{forest}
        child anchor=south,
        parent anchor=north,
        grow'=north,
[Child
    [Father]
    [Mother]
]
\end{forest}
\end{document}

我已经能够添加图像,但它总是出现在文本之前,而我想实现以下效果:

具有背景图像的森林树木示例

我想知道是否有办法添加图像位于文本后面,最好缩放至文本大小。

答案1

以下是 SandyG 答案的改编,不需要标签:

\documentclass{article}
\usepackage{forest}

\forestset{scroll/.style 2 args={
    content={\includegraphics[width=4cm]{5FHPu.png}},
    tikz={\node[align=center,yshift=-2.5mm] at () {#1\\*\ #2};},
    edge path={\noexpand\path[\forestoption{edge}] ([yshift=-3mm]!u.parent anchor)--(.child anchor)\forestoption{edge label};}
}}

\begin{document}
\begin{forest}
for tree={
    child anchor=south,
    parent anchor=north,
    grow'=north,
}
[, scroll={Child}{1722}
    [, scroll={Father}{1702}]
    [, scroll={Mother}{1701}]
]
\end{forest}
\end{document}

代码输出

答案2

您可以使用 放置滚动图像content=,并将文本放置为label。我建议保持所有滚动尺寸相同。

在此处输入图片描述

\documentclass{article}
\usepackage{forest}

\forestset{scroll/.style={
    content={\includegraphics[width=2cm]{5FHPu.png}}, 
    label={[label distance=-6mm]below:#1},
    edge path={\noexpand\path[\forestoption{edge}] ([yshift=-3mm]!u.parent anchor)--(.child anchor)\forestoption{edge label};}
}}

\begin{document}
\begin{forest}
for tree={
    child anchor=south,
    parent anchor=north,
    grow'=north
}
[, scroll=Child
    [, scroll=Father]
    [, scroll=Mother]
]
\end{forest}
\end{document}

答案3

以下是Alan Munn 的回答它会自动处理长名称(或日期)。它提供了一种family tree用于序言的样式。节点内容应以以下格式提供

<name or first line>:<date or second line>

然后,代码让 Forest 计算最宽节点并将其与标准宽度进行比较。如果最宽节点太宽而无法适应标准宽度,则对树中的所有滚动进行调整。然而,我们并不希望背景中的图像简单地缩放,因为这会创建不必要的深节点。所以我们只缩放滚动图像的中间部分,并且只在水平方向上缩放。

为了避免代码重复,图像被分成三个修剪和剪切的部分。这些部分被保存到专用框中并缩放。这三个框提供了卷轴的三个部分:一个用于左侧,一个用于中间,一个用于右侧。在“标准”情况下,名称和日期适合这个标准化卷轴的中间,我们只使用这些框。但是,如果内容太宽,则首先拉伸卷轴的中间部分以适应额外的宽度。

结果如下:

内容后面有标准和拉伸卷轴的家谱

这些树的输入是

\begin{forest}
  family tree
  [Child:1722
    [Father:1702]
    [Mother:1701]
  ]
\end{forest}

对于“标准”情况

\begin{forest}
  family tree,
  [Child:1722
    [Father:1702
      [Paternal Grandfather:1680]
      [Paternal Grandmother:1682]
    ]
    [Mother:1701
      [Maternal Grandfather:1680]
      [Maternal Grandmother:1682]
    ]
  ]
\end{forest}

对于‘拉伸’。

由于节点的内容位于水平中心,而滚动图像略微不平衡,因此放置位置并不完美。(右端比左端宽一点。)然而,在实践中,这似乎看起来是正确的(其他答案也这样做了)。如果您想要更多或更少的“标准”情况的余地,您可以更改min scroll wd一棵或所有树。默认值为61pt。例如,

\begin{forest}
  family tree,
  min scroll wd'=30pt
  [Child:1722
    [Father:1702]
    [Mother:1701]
  ]
\end{forest}
\begin{forest}
  family tree,
  min scroll wd'=100pt
  [Child:1722
    [Father:1702]
    [Mother:1701]
  ]
\end{forest}

减少或增加内容周围的空间

完整代码:

\documentclass[11pt]{standalone}
% ateb: https://tex.stackexchange.com/a/711822/ addaswyd o ateb Alan Munn: https://tex.stackexchange.com/a/711581/ i gwestiwn lak20: https://tex.stackexchange.com/q/711483/
\usepackage[edges]{forest}
% width 2014.52136pt
\ExplSyntaxOn
\box_new:N \l_scroll_left_box
\box_new:N \l_scroll_right_box
\box_new:N \l_scroll_mid_box
\dim_new:N \l_scroll_mid_dim
\hbox_set:Nn \l_scroll_left_box { \includegraphics{5FHPu} }
\dim_set:Nn \l_tmpa_dim { \box_wd:N \l_scroll_left_box }
\box_set_eq:NN \l_scroll_right_box \l_scroll_left_box
\box_set_eq:NN \l_scroll_mid_box \l_scroll_left_box
\box_set_trim:Nnnnn \l_scroll_left_box {0pt} {0pt} {1565pt} {0pt}
\box_set_trim:Nnnnn \l_scroll_mid_box {450pt} {0pt} {475pt} {0pt}
\box_set_trim:Nnnnn \l_scroll_right_box {1540pt} {0pt} {0pt} {0pt}
\box_set_clipped:N \l_scroll_left_box
\box_set_clipped:N \l_scroll_mid_box
\box_set_clipped:N \l_scroll_right_box
\box_scale:Nnn \l_scroll_left_box {40mm/\l_tmpa_dim} {40mm/\l_tmpa_dim}
\box_scale:Nnn \l_scroll_right_box {40mm/\l_tmpa_dim} {40mm/\l_tmpa_dim}
\box_scale:Nnn \l_scroll_mid_box {40mm/\l_tmpa_dim} {40mm/\l_tmpa_dim}
\dim_set:Nn \l_scroll_mid_dim { \box_wd:N \l_scroll_mid_box }
\cs_new_protected:Nn \scroll_assemble:n
{
  \box_use:N \l_scroll_left_box
  \box_scale:Nnn \l_scroll_mid_box { #1 / \l_scroll_mid_dim } { 1 }
  \box_use:N \l_scroll_mid_box
  \box_use:N \l_scroll_right_box
}
\cs_new_eq:NN \doscroll \scroll_assemble:n
\ExplSyntaxOff
\forestset{%
  declare boolean={scroll}{0},
  declare dimen register={scroll wd},
  declare dimen register={min scroll wd},
  declare toks={person name}{},
  declare toks={person date}{},
  scroll wd'=0pt,
  min scroll wd'=61pt,
  family tree/.style={%
    forked edges,
    for tree={%
      scroll,
      child anchor=parent,
      parent anchor=children,
      grow'=north,
      align=center,
      edge+={shorten <=-15pt,rounded corners},
    },
    before typesetting nodes={
      for tree={
        split option={content}{:}{person name,person date},
        content/.process={ OOw2 {person name}{person date}{##1\\*~##2} },
      },
    },
    before packing={
      scroll wd/.max={>OOw2+d{max x}{min x}{##1-##2}}{tree},
      if={ > RR> {scroll wd}{min scroll wd} }{
      }{
         scroll wd/.register=min scroll wd,
      },
      where scroll={
        tikz+/.process={Ow{content}{\node [align=center,anchor=south] at (.base) {##1};}},
        content={%
          \doscroll {\foresteregister{scroll wd}}%
        },
        inner sep=0pt,
        typeset node,
      }{},
    },
  },
  do scroll/.style 2 args={
    content={\includegraphics[width=4cm]{5FHPu.png}},
    tikz={\node[align=center,yshift=-2.5mm] at () {#1\\*\ #2};},
    edge path'={%
      ([yshift=-3mm]!u.parent anchor)--(.child anchor)},
  },
}

\begin{document}
\begin{forest}
  family tree
  [Child:1722
    [Father:1702]
    [Mother:1701]
  ]
\end{forest}
\begin{forest}
  family tree,
  [Child:1722
    [Father:1702
      [Paternal Grandfather:1680]
      [Paternal Grandmother:1682]
    ]
    [Mother:1701
      [Maternal Grandfather:1680]
      [Maternal Grandmother:1682]
    ]
  ]
\end{forest}

\begin{forest}
  family tree,
  min scroll wd'=30pt
  [Child:1722
    [Father:1702]
    [Mother:1701]
  ]
\end{forest}
\begin{forest}
  family tree,
  min scroll wd'=100pt
  [Child:1722
    [Father:1702]
    [Mother:1701]
  ]
\end{forest}
\end{document}

答案4

我不完全明白发生了什么,但以下是有效的:

\documentclass{article}
\usepackage{forest}

\makeatother
\newcommand{\Person}[2]{%
    \begin{center}%
        \vskip-38pt%
        {{#1}} \\%
        { *\  #2 }% 
    \end{center}%
}%
\begin{document}

\begin{forest}
    for tree={
            edge path={
                \noexpand\path[\forestoption{edge}]
                ([yshift=0.6pt]!u.parent anchor) --
                ([yshift=-0.9pt].child anchor)\forestoption{edge label};
            },
        text width=(4cm),
        child anchor=south,
        parent anchor=north,
        grow'=north,
        }
[{\makebox[\textwidth]{\centering\includegraphics[width=4cm]{5FHPu.png}}}\\%
\Person{Child}{1990}
    [{\makebox[\textwidth]{\centering\includegraphics[width=4cm]{5FHPu.png}}}\\%
    \Person{Father}{1950}
    ]
    [{\makebox[\textwidth]{\centering\includegraphics[width=4cm]{5FHPu.png}}}\\%
    \Person{Mother}{1960}
    ]
]
\end{forest} 
\end{document}

纸莎草纸上写有名字的家谱

我觉得特别令人费解的是使用 \vskip 的效果。它是 \'s 在 Person 环境中工作所必需的;而且,它在节点中似乎毫无用处。

相关内容