使用节点系列库时如何防止 tikz 自定义节点填充覆盖文本

使用节点系列库时如何防止 tikz 自定义节点填充覆盖文本

使用 tikz 扩展库组合定位加节点家族经过qrrbrbirlbel绘制流程图。使用节点系列将 2 个并行节点的大小设置为相等。此问题是,如果对节点使用自定义填充颜色,则填充会出现在文本前面。确定问题来自节点系列库。尝试使用 texlive 和 MiKTeX 2019,结果没有任何差异。

这是因为 tikz/pgf 更新导致库失败吗?库作者提供的示例似乎无需任何修改就可以正确编译。

节点系列和文本被节点填充覆盖的示例:

\documentclass[tikz,border=10pt]{standalone}
\usetikzlibrary{shapes.geometric,backgrounds,fit,calc,positioning-plus,node-families}

\tikzset{
  basic box/.style = {
    shape = rectangle,
    align = center,
    draw  = #1,
    fill  = #1!25,
    rounded corners},
  header node/.style = {
    Minimum Width = header nodes,
    font          = \strut\Large\ttfamily,
    text depth    = +0pt,
    fill          = white,
    draw},
  header/.style = {%
    inner ysep = +1.5em,
    append after command = {
      \pgfextra{\let\TikZlastnode\tikzlastnode}
      node [header node] (header-\TikZlastnode) at (\TikZlastnode.north) {#1}
      node [span = (\TikZlastnode)(header-\TikZlastnode)]
        at (fit bounding box) (h-\TikZlastnode) {}
    }
  },
  hv/.style = {to path = {-|(\tikztotarget)\tikztonodes}},
  vh/.style = {to path = {|-(\tikztotarget)\tikztonodes}},
  fat blue line/.style = {ultra thick, blue}
}

\begin{document}

\begin{tikzpicture}[node distance = 1.2cm, thick, nodes = {align = center},>=latex]
  \node[Minimum Width = loop, shape = ellipse, fill = red] (imp-sol) {ellipsoid box};
  \node[Minimum Width = loop, fill = yellow, below = of imp-sol] (rec-box)
    {rectangular box, and very wiiiiiiiiiiiiiiide\\2nd line};
  \node[shift = (left:.5*x_node_dist)] at
    ($(imp-sol.west|-imp-sol.south)!.5!(rec-box.north west)$) (for-1)
    {formula 1};
  \node[shift = (right:.5*x_node_dist)] at
    ($(imp-sol.east|-imp-sol.south)!.5!(rec-box.north east)$) (for-2)
    {formula 2};
  \begin{scope}[on background layer]
    \node[fit = (for-1)(for-2)(imp-sol)(rec-box), basic box = blue,
      header = DMFT loop] (dmft-l) {};
  \end{scope}
  \path[very thick, blue, hv] (rec-box) edge[->] (for-1) edge[<-] (for-2)
                              (imp-sol) edge[->] (for-2) edge[<-] (for-1);
\end{tikzpicture}

\end{document}

在此处输入图片描述

没有节点系列的示例:

\documentclass[tikz,border=10pt]{standalone}
\usetikzlibrary{shapes.geometric,backgrounds,fit,calc,positioning-plus}

\tikzset{
  basic box/.style = {
    shape = rectangle,
    align = center,
    draw  = #1,
    fill  = #1!25,
    rounded corners},
  header node/.style = {
    font          = \strut\Large\ttfamily,
    text depth    = +0pt,
    fill          = white,
    draw},
  header/.style = {%
    inner ysep = +1.5em,
    append after command = {
      \pgfextra{\let\TikZlastnode\tikzlastnode}
      node [header node] (header-\TikZlastnode) at (\TikZlastnode.north) {#1}
      node [span = (\TikZlastnode)(header-\TikZlastnode)]
        at (fit bounding box) (h-\TikZlastnode) {}
    }
  },
  hv/.style = {to path = {-|(\tikztotarget)\tikztonodes}},
  vh/.style = {to path = {|-(\tikztotarget)\tikztonodes}},
  fat blue line/.style = {ultra thick, blue}
}

\begin{document}

\begin{tikzpicture}[node distance = 1.2cm, thick, nodes = {align = center},>=latex]
  \node[shape = ellipse, fill = red] (imp-sol) {ellipsoid box};
  \node[fill = yellow, below = of imp-sol] (rec-box)
    {rectangular box, and very wiiiiiiiiiiiiiiide\\2nd line};
  \node[shift = (left:.5*x_node_dist)] at
    ($(imp-sol.west|-imp-sol.south)!.5!(rec-box.north west)$) (for-1)
    {formula 1};
  \node[shift = (right:.5*x_node_dist)] at
    ($(imp-sol.east|-imp-sol.south)!.5!(rec-box.north east)$) (for-2)
    {formula 2};
  \begin{scope}[on background layer]
    \node[fit = (for-1)(for-2)(imp-sol)(rec-box), basic box = blue,
      header = DMFT loop] (dmft-l) {};
  \end{scope}
  \path[very thick, blue, hv] (rec-box) edge[->] (for-1) edge[<-] (for-2)
                              (imp-sol) edge[->] (for-2) edge[<-] (for-1);
\end{tikzpicture}

\end{document}

在此处输入图片描述

答案1

欢迎使用 TeX-SE!我可以为您提供一个解决方法/修复,以解决标题中提出的问题:“使用节点系列库时如何防止 tikz 自定义节点填充覆盖文本?”。但是,我不会回答“这是由于 tikz/pgf 中的更新导致库失败吗?”的问题。修复方法是使用path pictures 进行填充。

\documentclass[tikz,border=10pt]{standalone}
\usetikzlibrary{shapes.geometric,backgrounds,fit,calc,positioning-plus,node-families}

\tikzset{
  basic box/.style = {
    shape = rectangle,
    align = center,
    draw  = #1,
    fill  = #1!25,
    rounded corners},
  header node/.style = {
    Minimum Width = header nodes,
    font          = \strut\Large\ttfamily,
    text depth    = +0pt,
    Fill          = white, %<- !!!
    draw},
  header/.style = {%
    inner ysep = +1.5em,
    append after command = {
      \pgfextra{\let\TikZlastnode\tikzlastnode}
      node [header node] (header-\TikZlastnode) at (\TikZlastnode.north) {#1}
      node [span = (\TikZlastnode)(header-\TikZlastnode)]
        at (fit bounding box) (h-\TikZlastnode) {}
    }
  },
  hv/.style = {to path = {-|(\tikztotarget)\tikztonodes}},
  vh/.style = {to path = {|-(\tikztotarget)\tikztonodes}},
  fat blue line/.style = {ultra thick, blue}
}
\tikzset{Node Options/.style={path picture={
   \path[#1] (path picture bounding box.south west)
   rectangle (path picture bounding box.north east);
  }},Fill/.style={Node Options={fill=#1}}}
\begin{document}

\begin{tikzpicture}[node distance = 1.2cm, thick, nodes = {align = center},>=latex]
  \node[Minimum Width = loop, shape = ellipse,Fill=red] (imp-sol) {ellipsoid box};
  \node[Minimum Width = loop,Fill = yellow, below = of imp-sol] (rec-box)
    {rectangular box, and very wiiiiiiiiiiiiiiide\\2nd line};
  \node[shift = (left:.5*x_node_dist)] at
    ($(imp-sol.west|-imp-sol.south)!.5!(rec-box.north west)$) (for-1)
    {formula 1};
  \node[shift = (right:.5*x_node_dist)] at
    ($(imp-sol.east|-imp-sol.south)!.5!(rec-box.north east)$) (for-2)
    {formula 2};
  \begin{scope}[on background layer]
    \node[fit = (for-1)(for-2)(imp-sol)(rec-box), basic box = blue,
      header = DMFT loop] (dmft-l) {};
  \end{scope}
  \path[very thick, blue, hv] (rec-box) edge[->] (for-1) edge[<-] (for-2)
                              (imp-sol) edge[->] (for-2) edge[<-] (for-1);
\end{tikzpicture}

\end{document}

在此处输入图片描述

仅出于完整性考虑:在此特定情况下,使用标准库可以获得非常相似的输出,而无需手动添加显式距离。但我当然知道,有些例子中 Qrrbrbirlbel nice 库有助于自动完成任务。

\documentclass[tikz,border=10pt]{standalone}
\usetikzlibrary{calc,fit,shapes.geometric,positioning,backgrounds}
\begin{document}

\begin{tikzpicture}[node distance=1.2cm, thick,nodes={align=center},>=latex,
    basic box/.style={shape=rectangle,align=center,draw=#1,fill=#1!25,rounded corners},
    hv/.style={to path={-|(\tikztotarget)\tikztonodes}}]
 \node[fill=yellow] (rec-box) {rectangular box, and very wiiiiiiiiiiiiiiide\\2nd line};
 \path let \p1=($(rec-box.east)-(rec-box.west)$) in 
 node[ellipse,fill=red,above=of rec-box,minimum width=\x1](imp-sol) {ellipsoid box};
 \path (rec-box.west) |-(imp-sol) node[pos=0.25,left](for-1) {formula 1}
 (rec-box.east) |-(imp-sol) node[pos=0.25,right](for-2) {formula 2};
  \begin{scope}[on background layer]
    \node[fit = (for-1)(for-2)(imp-sol)(rec-box),basic box=blue,
     inner ysep=1.5em,
      label={[anchor=center,fill=white,draw]above:DMFT loop}] (dmft-l) {};
  \end{scope}
  \path[very thick, blue, hv] (rec-box) edge[->] (for-1) edge[<-] (for-2)
                              (imp-sol) edge[->] (for-2) edge[<-] (for-1);
\end{tikzpicture}

\end{document}

在此处输入图片描述

答案2

这是由于 tikz/pgf 更新导致库失败吗?

是的。2013node年至 2019/2022 年期间,该行动的内部运作发生了很大变化。我有修复了这个问题

不过,我还创建了一个新的ext.node-families图书馆作为我的tikz-ext包裹它的工作原理非常不同,有两种模式:

  1. 一种模式仅比较文本框大小(这对您根本没有帮助)并且忽略形状和inner [xy]seps。

  2. 另一种模式再次使用minimum widthminimum height,但它不会使节点总是变宽,即使节点应该更小。

    由于ellipse使用略有不同的值来计算其相对于文本和inner seps 的大小,因此您需要包含所需调整的ext.node-families.shapes.geometric库(加载ext.node-families和)。shapes.geometric

sheader node将获得钥匙node family/text width = header nodes,并且ellipse和 very wiiiide都rectangle将获得node family/width = loop

我还positioning-plusext.positioning-plus库替换了(只需要数学函数x_node_dist)。

代码

\documentclass[tikz,border=10pt]{standalone}
\usetikzlibrary{
  backgrounds, calc,
  ext.positioning-plus,
  ext.node-families.shapes.geometric% loads ext.node-families
                                    %   and shapes.geometric
}
\tikzset{
  basic box/.style = {
    shape = rectangle,
    align = center,
    draw  = #1,
    fill  = #1!25,
    rounded corners},
  header node/.style = {
    node family/text width = header nodes,
    font          = \strut\Large\ttfamily,
    text depth    = +0pt,
    fill          = white,
    draw},
  header/.style = {%
    inner ysep = +1.5em,
    append after command = {
      \pgfextra{\let\TikZlastnode\tikzlastnode}
      node [header node] (header-\TikZlastnode) at (\TikZlastnode.north) {#1}
      node [span = (\TikZlastnode)(header-\TikZlastnode)]
        at (fit bounding box) (h-\TikZlastnode) {}
    }
  },
  hv/.style = {to path = {-|(\tikztotarget)\tikztonodes}},
  vh/.style = {to path = {|-(\tikztotarget)\tikztonodes}},
  fat blue line/.style = {ultra thick, blue}
}

\begin{document}
\begin{tikzpicture}[
  node distance = 1.2cm, thick, nodes = {align = center}, >=latex]
\node[shape = ellipse, node family/width = loop, fill = red]
  (imp-sol) {ellipsoid box};
\node[fill = yellow, node family/width = loop, below = of imp-sol]
  (rec-box) {rectangular box, and very wiiiiiiiiiiiiiiide\\2nd line};
\node[shift = (left:.5*x_node_dist)] at
  ($(imp-sol.west|-imp-sol.south)!.5!(rec-box.north west)$) (for-1)
  {formula 1};
\node[shift = (right:.5*x_node_dist)] at
  ($(imp-sol.east|-imp-sol.south)!.5!(rec-box.north east)$) (for-2)
  {formula 2};
\begin{scope}[on background layer]
  \node[fit = (for-1)(for-2)(imp-sol)(rec-box), basic box = blue,
    header = DMFT loop] (dmft-l) {};
\end{scope}
\path[very thick, blue, hv] (rec-box) edge[->] (for-1) edge[<-] (for-2)
                            (imp-sol) edge[->] (for-2) edge[<-] (for-1);
\end{tikzpicture}
\end{document}

输出

在此处输入图片描述

相关内容