4

I would like to set draw options in tikz depending on some pgfmath calculations. More specifically, I would like to draw or not draw an edge depending on some value in an array.

This works fine if the calculations can be executed outside the actual \draw command, as in this example:

\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}[every node/.style={circle, inner sep=0mm,minimum size=1mm,draw}]
\foreach \i in {1,...,7}{
    \node (\i) at (\i,0) {\i};
}

\foreach \i in {1,...,6}{
    \pgfmathparse{ifthenelse(array({1,0,0,0,1,1},\i-1)==1, "black", "none")}
    \draw[draw=\pgfmathresult] (\i) -- (\the\numexpr\i+1\relax);
} 

\end{tikzpicture}
\end{document}

enter image description here

However, in certain situations (for instance when using grow cyclic, as below), it is not obvious how to execute the calculation outside the \draw command:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{trees}
\begin{document}
\begin{tikzpicture}[
    grow cyclic,circle,sibling angle=30,draw,
    level 1/.style={level distance=3cm},
    level 2/.style={level distance=3cm,sibling angle=60},
    every node/.style={inner sep=0mm,minimum size=1mm,draw}]

    \node (Ac) {$u$} child foreach \i in {1,...,7} {
        node (\i) {\i} %edge from parent[draw=\pgfmathparse{ifthenelse(array({1,0,0,0,1,1},\i-1)==1, "black", "none")}\pgfmathresult];
    };

\end{tikzpicture}
\end{document}

The commented part is an attempt of performing the calculation in situ, however this produces an error message (I suspect that tikz does not like that \pgfmathparse is not expandable).

1 Answer 1

3

Adaptations

  • use package etoolbox
  • added a 7th number to the array to match the size
  • created style myline that gets the array and \i as parameters, and sets style mylineB, which is used afterwards (with /.append style).

Code

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{trees}
\usepackage{etoolbox}
\begin{document}
\begin{tikzpicture}[
    grow cyclic,circle,sibling angle=30,draw,
    level 1/.style={level distance=3cm},
    level 2/.style={level distance=3cm,sibling angle=60},
    every node/.style={inner sep=0mm,minimum size=1mm,draw},
    myline/.code 2 args={
        \pgfmathparse{array({#1},#2-1)}
        \ifnumequal{\pgfmathresult}{1}{%
            \tikzset{mylineB/.style={draw=black}}
        }{
            \tikzset{mylineB/.style={draw=none}}
        },
    },
    myline/.append style={mylineB},
]

    \node (Ac) {$u$} child foreach \i in {1,...,7} {
        node (\i) {\i} edge from parent[myline={1,0,0,0,1,1,0}{\i}]
    };
\end{tikzpicture}
\end{document}

Result

enter image description here

2
  • 1
    Thanks a lot! Creating a new style to solve the problem is something I would never have come up with, nor known how to do. Just out of interest, do you know the reason why this works while just using pgfmathparse in place fails? What difference does it make to tikz that the computation is "hidden" in the style rather than invoked in situ?
    – user631620
    Nov 24, 2021 at 8:58
  • 1
    If you just put the whole thing in myline/.style it should not make any difference (and would not work with the current code). But here I used the key handler .code which interprets everything afterwards as normal LaTeX code and not as a style. For more information have a look into the documentation of tikz/pgf Part VII Utilities.
    – dexteritas
    Nov 24, 2021 at 9:08

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .