3

Using TikZ and pgf versions v3.1.9a (3.1.9a), I tried to compile the following code

\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{trees,mindmap}
\tikzset{grow cyclic list/.code={%
  \def\tikzgrowthpositions{{#1}}%
  \foreach \n [count=\i,remember=\i]in {#1}{}%
  \let\tikzgrowthpositionscount=\i%
  \tikzset{growth function=\tikzgrowcycliclist}}}
\def\tikzgrowcycliclist{%
  \pgftransformshift{%
    \pgfpointpolar{\tikzgrowthpositions[mod(\the\tikznumberofcurrentchild-1,\tikzgrowthpositionscount)]}%
      {\the\tikzleveldistance}}}
\begin{document}
\begin{tikzpicture}[small mindmap, concept color=blue!20,  
  every child node/.style={concept}]
\node [concept] (languages) 
  {O} [grow cyclic list={90,0,-45,210}] 
    child { node {A} }
    child { node {B} }
    child { node {C} 
      [clockwise from=0, sibling angle=45]
      child { node {C1} }
      child { node {C1} }
      child { node {C1} }
    }
    child { node {D} };
\end{tikzpicture}
\end{document}

which is a part of the Mark Wibrow's answer here. But it throws the following error:

Argument of \pgfmath@dimen@@ has an extra }. ^^Ichild { node {D} };

Does anybody know how to resolve it?

2 Answers2

3

The problem is that the old answer exploited a misfeature of \foreach that has been since fixed.

What happened was that the “count” that was “remembered” was still available at the end of \foreach, but this is wrong: you'd clobber the meaning of \i in your case. And if you had an accented “î” in some node…

There's a much easier way to count elements of a list:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{trees,mindmap}

\ExplSyntaxOn \cs_set_eq:NN \clistcount \clist_count:n \ExplSyntaxOff

\tikzset{ grow cyclic list/.code={% \def\tikzgrowthpositions{{#1}}% % \foreach \n [count=\i,remember=\i]in {#1}{\global\let\tikzgrowthpositionscount=\i}% \edef\tikzgrowthpositionscount{\clistcount{#1}}% \tikzset{growth function=\tikzgrowcycliclist} } }

\def\tikzgrowcycliclist{% \pgftransformshift{% \pgfpointpolar{% \tikzgrowthpositions[mod(\the\tikznumberofcurrentchild-1,\tikzgrowthpositionscount)]% }% {\the\tikzleveldistance} }% }

\begin{document}

\begin{tikzpicture}[ small mindmap, concept color=blue!20,
every child node/.style={concept} ] \node [concept] (languages) {O} [grow cyclic list={90,0,-45,210}] child { node {A} } child { node {B} } child { node {C} [clockwise from=0, sibling angle=45] child { node {C1} } child { node {C1} } child { node {C1} } } child { node {D} }; \end{tikzpicture}

\end{document}

I left commented the alternative \foreach method, but my suggestion is much more efficient.

For a “pure TikZ” solution

\tikzset{
  grow cyclic list/.code={%
    \def\tikzgrowthpositions{{#1}}%
    \pgfmathsetmacro\tikzgrowthpositionscount{dim({#1})}%
    \tikzset{growth function=\tikzgrowcycliclist}
  }
}
egreg
  • 1,121,712
  • dim! I always learn something new about PGF/TikZ! – Jasper Habicht Jul 20 '22 at 09:28
  • 1
    @JasperHabicht This has a story. I once found it in the code, but not in the manual, so I opened an issue in the Github site. It turned out I was assaulted by a well known person. I'll not mention the futile reasons, except that the function wasn't documented because it was buggy when the list contained a single item. But as a consequence of the issue report, the bug was fixed and the function found its place in the manual. – egreg Jul 20 '22 at 09:33
1

I would think that \tikzgrowthpositionscount needs to be set inside the \foreach loop and it should be made global to be accessible outside the loop. The remember option only stores the last item value, but it does not make the variable accessible outside the for loop (might have been changed at some point in time).

\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{trees,mindmap,calc}
\tikzset{grow cyclic list/.code={%
  \def\tikzgrowthpositions{{#1}}%
  \foreach \n [count=\i]in {#1}{%
    \global\let\tikzgrowthpositionscount=\i%
  }%
  \tikzset{growth function=\tikzgrowcycliclist}}}
\def\tikzgrowcycliclist{%
  \pgftransformshift{%
    \pgfpointpolar{\tikzgrowthpositions[mod(\the\tikznumberofcurrentchild-1,\tikzgrowthpositionscount)]}%
      {\the\tikzleveldistance}}}
\begin{document}
\begin{tikzpicture}[small mindmap, concept color=blue!20,  
  every child node/.style={concept}]
\node [concept] (languages) 
  {O} [grow cyclic list={90,0,-45,210}] 
    child { node {A} }
    child { node {B} }
    child { node {C} 
      [clockwise from=0, sibling angle=45]
      child { node {C1} }
      child { node {C1} }
      child { node {C1} }
    }
    child { node {D} };
\end{tikzpicture}
\end{document}

enter image description here