3

Using the combo of tikz extension libraries positioning-plus and node-families by qrrbrbirlbel to draw a flowchart. Using node-families to equally size 2 parallel nodes. This issue is that if a custom fill color is used for a node the fill comes in front of the text. Identified that the issue comes from the node-families library. Tried using both texlive and MiKTeX 2019 without any difference in the result.

Is this due to update in tikz/pgf causing the library to fail? In this example by the library author, it seems to compile correctly without any modification.

Example with node-families and text being covered by the nodes fill:

\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}

enter image description here

Example without node-families:

\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}

enter image description here

3

Welcome to TeX-SE! I can offer you a workaround/fix that addresses the question raised in the title: "How to prevent tikz custom node fill from covering the text when using node-families library?". However, I won't address the question "Is this due to update in tikz/pgf causing the library to fail?". The fix is to use path pictures for the fills.

\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}

enter image description here

Just for completeness: in this particular case a very similar output can be obtained with the standard libraries and without adding explicit distances by hand. But of course I do understand that there are examples in which Qrrbrbirlbel nice libraries are instrumental to do things automatically.

\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}

enter image description here

3
  • Thanks, can confirm the fix works. Could you please clarify how does the workaround exactly work? If I understand correctly replace the normal fill with the newly defined one (Fill) which uses path picture. So what does the normal fill use? – nkk Jun 8 '19 at 19:38
  • @nkk This answer is to some extent a gamble. I was looking for something that doesn't get "hacked" in Qrrbrbirlbel's libraries, and saw that path picture is such a thing. (Please do not get me wrong, these "hacks" are great!) A path picture allows you to put something on the background of a given path that gets clipped by the path, so it can be used in particular (but not only) for filling node paths. BTW, in this particular case you do not necessarily need these "hacks", you could go with a matrix, too. – user121799 Jun 8 '19 at 19:44
  • Great, this now makes sense. Started with tikz very recently and I'm loving it so far. For now, I'm using it for any diagrams that I need to get up to speed. – nkk Jun 8 '19 at 19:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.