4

Update Thanks to the latest update by Schrodinger's cat, i'm now ready to produce pretty easily the following type of regular Mindmap on 3 levels.

CircularRegularMindmap

We're almost there for a fully automated organization of regular circular mindmaps. The possible improvment would be to Imply (and not input manually) the sibling angles in level 1, 2 and 3 by reusing the \tikzcountchildi counters for the number of nodes (+Phantom node) at each level.

Evolution of the answer

Based on mindmap-growcyclic-from and this answer how-to-put-level-2-concept-mindmap-nodes-alongside-a-rectangle, how could we get the circle path result on nodes at level 2 AND 3 ?

Based on schrodinger's cat answer, there is trick with the development of \tikzcountgrandchild or the sibling angles but am still struggling to find the solution.

enter image description here

\documentclass[tikz,border=9]{standalone}
\usetikzlibrary{mindmap,decorations}
\usepackage{xspace}

\makeatletter
\newcount\tikzcountgrandchild
\def\tikz@grow@concentric{%
  \pgftransformreset%
  \pgftransformshift{\pgfpoint{\pgfkeysvalueof{/tikz/overall xshift}}{\pgfkeysvalueof{/tikz/overall yshift}}}% 
  \pgftransformrotate{\pgfkeysvalueof{/tikz/overall rotation}+(\pgfkeysvalueof{/tikz/sibling angle})*(\tikzcountgrandchild)}%
  \ifnum\tikztreelevel=1
    \pgftransformrotate{(\pgfkeysvalueof{/tikz/sibling angle})*(\pgfkeysvalueof{/tikz/noc}-1)/2}%
  \fi
  \pgftransformxshift{\the\tikzleveldistance}%
  \ifnum\tikztreelevel=2
    \global\advance\tikzcountgrandchild by1
 \fi
%  \ifnum\tikztreelevel=3
%    \global\advance\tikzcountgrandchild by1
% \fi
}

\begin{document}
\tikzset{overall rotation/.initial=0,
    overall xshift/.initial=0pt,
    overall yshift/.initial=0pt,
    Xshift/.style={xshift=#1,overall xshift=#1},
    Yshift/.style={yshift=#1,overall yshift=#1},
    noc/.initial=0,
    branch color/.style={
        concept color=#1!white,
        every child/.append style={concept color=#1!white!30!white},
    }
}

\begin{tikzpicture}
    \begin{scope}[text width=1.5cm,align=flush center,
            mindmap,growth function=\tikz@grow@concentric,
            overall rotation=-45,
            sibling angle=360/30,
            nodes={concept},
            concept color=green!70!black,
            root concept/.append style={ ball color=green!50, line width=1.5ex,text=green!40!black,font=\huge\bfseries\scshape,minimum size=4.5cm,text width=4.5cm,},                   
            level 1/.style={,level distance=8cm,font=\Large,minimum size=3.0cm,text width=2.5cm,},
            level 2/.style={level distance=12cm,font=\large,minimum size=2.0cm,text width=2.0cm},
            level 3/.style={level distance=15cm,font=\large,minimum size=2.0cm,text width=2.0cm}
        ]
        \node [root concept]{Clients} 
        child[noc=3,branch color=green!70]{node {Retail} 
            child[] {node {CGPI}} 
            child[] {node {Banques priv\'ees}} 
            child[] {node {Retail banking}} 
        }
        child[noc=3,branch color=green!70]{node {ALM} 
            child { node (equity) {Equity}
                child { node {Indices}}
                child { node {Stocks}}
                child { node {ETFs}}
            }
            child { node (commo) {Commodities}
                child { node {Soft commo}}
                child { node {Precious}}        
                child { node {Oil/Gas}}
            }
            child[] {node {Assurances}} 
            child[] {node {Caisse de retraite}}         
        } 
        child[noc=1,branch color=green!80]{node {Directions financi\'eres} 
            child[] {node {Corporate}} 
        } 
        child[noc=3,branch color=green!70]{node {Instrument specialists} 
            child {node {Asset Managers traditionnels}} 
            child {node {Hedge funds}} 
            child {node {Trading desks form other banks}} 
        } 
        ;
    \end{scope}

    \begin{scope}[Xshift=-5cm,text width=1.5cm,align=flush center,
            mindmap,growth function=\tikz@grow@concentric,
            overall rotation=45,
            sibling angle=360/30,
            nodes={concept},
            concept color=yellow!70!black,
            root concept/.append style={ ball color=yellow!50, line width=1.5ex,text=yellow!40!black,font=\huge\bfseries\scshape,minimum size=4.5cm,text width=4.5cm,},                   
            level 1/.style={,level distance=8cm,font=\Large,minimum size=3.0cm,text width=2.5cm,},
            level 2/.style={level distance=12cm,font=\large,minimum size=2.0cm,text width=2.0cm}
        ]
        \node [root concept]{Suppliers} 
        child[noc=3,branch color=yellow!70]{node {Retail} 
            child[] {node {CGPI}} 
            child[] {node {Banques priv\'ees}} 
            child[] {node {Retail banking}} 
        }
        child[noc=3,branch color=yellow!70]{node {ALM} 
            child[] {node {Mutuelles}} 
            child[] {node {Assurances}} 
            child[] {node {Caisse de retraite}}         
        } 
        child[noc=1,branch color=yellow!80]{node {Directions financi\'eres} 
            child[] {node {Corporate}} 
        } 
        child[noc=3,branch color=yellow!70]{node {Instrument specialists} 
            child {node {Asset Managers traditionnels}} 
            child {node {Hedge funds}} 
            child {node {Trading desks form other banks}} 
        } 
        ;
    \end{scope}

\end{tikzpicture}
\end{document}

Once you have the counter at level 1, 2 and 3, could not we just "imply" the node angles going from level 3, then level 2 and level 1 ? For instance, on the green map below.

enter image description here

We have 15 nodes level 3, 11 nodes level 2, 4 nodes level 1,

in terms of coordinates (with the counters) to describe each node, we have :

(1 1 0) 1 node level 2
(1 2 0) 1 node level 2
(1 3 0) 1 node level 2      1 node level 1
(2 1 0) 1 node level 2
(2 2 0) 1 node level 2
(2 3 1) 1 node level 2
(2 3 2)
(2 3 3)
(2 4 1) 1 node level 2
(2 4 2)
(2 4 3)                     1 node level 1
(3 1 0) 1 node level 2      1 node level 1
(4 1 0) 1 node level 2
(4 2 0) 1 node level 2
(4 3 0) 1 node level 2      1 node level 1

we have the number of

level 3 by counting the numer of (x,y,z)that are distinct (#rows of the table)
level 2 by counting the numer of (x,y) that are distinct
level 1 by counting the numer of (x) that are distinct

if we want the minmap to describe a certain portion of a circle, aren't we able to have automatically from the count in the table above

angle @ level3 is set to  (portion * 360/14) (and not 15)
angle @ level2 is set to  (portion * 360/10) (and not 11)
angle @ level1 is set to  (portion * 360/3) (and not 4)

?

In the quick sketch below, we want to have a quarter circle shape (without loss of generality) of the final minmap. Nodes @ level 2 without actual nodes at level 3 actually contribute to the counter of nodes required on level 3 (nodes that are not filled). quickSketch

2
  • So far I can see the problem (not I have answer). When I first write \tikz@grow@concentric there is a tree of depth 2. So the statistics is relatively easy because you only have to count how many children. Now you have to count how many grandchildren. The code will be longer, but it should still be possible. I will try to rework the whole mechanism to minimize annoying setup such as noc.
    – Symbol 1
    Mar 15, 2020 at 21:18
  • 2
    I think that a fully automatic solution will have to go in two runs. In order to know what the various angles should be, one would have to know how many children the later children at the same level have, and then the number of grandchildren and so on. Conceivably one could write the information to the aux file and recover it in the second run.
    – user194703
    Mar 16, 2020 at 3:49

2 Answers 2

2
+150

UPDATED ANSWER to your edited question. Just define some counts for the various levels and introduce some offset angles. (More generally one will probably need to add some level-dependent additional angles, or do an automatized version, which the lowest code will get turned into at some point.) For your current example this seems to be sufficient.

\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{mindmap}
\makeatletter
\newif\ifmmap@debug
\mmap@debugfalse
\newcommand{\mmap@debug@message}[1]{\ifmmap@debug
\typeout{#1}%
\fi}
\newcount\tikzcountchildi
\newcount\tikzcountchildii
\newcount\tikzcountchildiii
\newcount\tikzcountchildiv
\newcount\tikzcountchildv
\tikzcountchildi=0
\tikzcountchildii=0
\tikzcountchildiii=0
\tikzcountchildiv=0
\tikzcountchildv=0
\tikzset{Julien growth/.style={growth function=\tikz@grow@Julien,
mmap/initialize counts},
mmap/.cd,initialize counts/.code={\global\tikzcountchildi=0%
\global\tikzcountchildii=0%
\global\tikzcountchildiii=0%
\global\tikzcountchildiv=0%
\global\tikzcountchildv=0%
}
}



\def\tikz@grow@Julien{%
  \pgftransformreset% 
  \pgftransformshift{\pgfpoint{\pgfkeysvalueof{/tikz/mmap/overall xshift}}%
        {\pgfkeysvalueof{/tikz/mmap/overall yshift}}}%
  \ifcase\tikztreelevel 
  \or
    \pgfmathsetmacro{\pgfutil@tempb}{\pgfkeysvalueof{/tikz/mmap/overall rotation}%
        +\pgfkeysvalueof{/tikz/mmap/sign}*\pgfkeysvalueof{/tikz/offset angle}%
        +\pgfkeysvalueof{/tikz/mmap/sign}*\pgfkeysvalueof{/tikz/sibling angle}*\tikzcountchildi}%
    \global\advance\tikzcountchildi by1\relax%
  \or
    \pgfmathsetmacro{\pgfutil@tempb}{\pgfkeysvalueof{/tikz/mmap/overall rotation}%
        +\pgfkeysvalueof{/tikz/mmap/sign}*\pgfkeysvalueof{/tikz/offset angle}%
        +\pgfkeysvalueof{/tikz/mmap/sign}*\pgfkeysvalueof{/tikz/sibling angle}*\tikzcountchildii}%
    \global\advance\tikzcountchildii by1\relax%
  \or
    \pgfmathsetmacro{\pgfutil@tempb}{\pgfkeysvalueof{/tikz/mmap/overall rotation}%
        +\pgfkeysvalueof{/tikz/mmap/sign}*\pgfkeysvalueof{/tikz/offset angle}%
        +\pgfkeysvalueof{/tikz/mmap/sign}*\pgfkeysvalueof{/tikz/sibling angle}*\tikzcountchildiii}%
    \global\advance\tikzcountchildiii by1\relax%
  \or
    \pgfmathsetmacro{\pgfutil@tempb}{\pgfkeysvalueof{/tikz/mmap/overall rotation}%
        +\pgfkeysvalueof{/tikz/mmap/sign}*\pgfkeysvalueof{/tikz/offset angle}%
        +\pgfkeysvalueof{/tikz/mmap/sign}*\pgfkeysvalueof{/tikz/sibling angle}*\tikzcountchildiv}%
    \global\advance\tikzcountchildiv by1\relax%
  \or
    \pgfmathsetmacro{\pgfutil@tempb}{\pgfkeysvalueof{/tikz/mmap/overall rotation}%
        +\pgfkeysvalueof{/tikz/mmap/sign}*\pgfkeysvalueof{/tikz/offset angle}%
        +\pgfkeysvalueof{/tikz/mmap/sign}*\pgfkeysvalueof{/tikz/sibling angle}*\tikzcountchildv}%
    \global\advance\tikzcountchildv by1\relax%
  \fi
  \mmap@debug@message{level=\the\tikztreelevel,%
  \the\tikzcountchildi,\the\tikzcountchildii,\the\tikzcountchildiii,
  rotation=\pgfutil@tempb,sibling angle=\pgfkeysvalueof{/tikz/sibling angle}}%
  \pgftransformrotate{\pgfutil@tempb}%
  \pgftransformxshift{\the\tikzleveldistance}%
}
\makeatother
\begin{document}
\tikzset{mmap/.cd,overall rotation/.initial=0,% overall transformation of mind maps
    overall xshift/.initial=0pt,
    overall yshift/.initial=0pt,
    sign/.initial=1,% 1=clockwise,-1=counterclockwise
    /tikz/.cd,offset angle/.initial=0,
    Xshift/.style={xshift=#1,mmap/overall xshift=#1},
    Yshift/.style={yshift=#1,mmap/overall yshift=#1},
    branch color/.style={
        concept color=#1!white,
        every child/.append style={concept color=#1!white!30!white},
    }
}

\begin{tikzpicture}[node font=\sffamily]
    \begin{scope}[text width=1.5cm,align=flush center,
            mindmap,Julien growth,
            mmap/overall rotation=110,mmap/sign=-1,
            nodes={concept},
            concept color=green!70!black,
            root concept/.append style={ball color=green!50, line width=1.5ex,text=green!40!black,font=\huge\bfseries\scshape,minimum size=4.5cm,text width=4.5cm,},                   
            level 1/.style={level distance=5cm,font=\Large,minimum size=3.0cm,
                text width=2.5cm,sibling angle=65},
            level 2/.style={level distance=9cm,
                font=\large,minimum size=2.0cm,text width=2.0cm,
                    sibling angle=22},
            level 3/.style={level distance=12cm,font=\large,minimum
            size=2.0cm,text width=2.0cm,sibling angle=12,
            offset angle=50},
        ]
        \node [root concept]{Clients} 
        child[branch color=green!70]{node {Retail} 
            child[] {node {CGPI}} 
            child[] {node {Banques priv\'ees}} 
            child[] {node {Retail banking}} 
        }
        child[branch color=green!70]{node {ALM} 
            child { node (equity) {Equity}
                child { node {Indices}}
                child { node {Stocks}}
                child { node {ETFs}}
            }
            child { node (commo) {Commo--\\dities}
                child { node {Soft commo}}
                child { node {Precious}}        
                child { node {Oil/Gas}}
            }
            child[] {node {Assurances}} 
            child[] {node {Caisse de retraite}}         
        } 
        child[branch color=green!80]{node {Directions financi\'eres} 
            child[] {node {Corporate}} 
        } 
        child[branch color=green!70]{node {Instrument specialists} 
            child {node {Asset Managers traditionnels}} 
            child {node {Hedge funds}} 
            child {node {Trading desks form other banks}} 
        } 
        ;
    \end{scope}

    \begin{scope}[Xshift=-12cm,text width=1.5cm,align=flush center,
            mindmap,Julien growth,
            mmap/overall rotation=290,mmap/sign=-1,
            nodes={concept},
            concept color=yellow!70!black,
            root concept/.append style={ ball color=yellow!50, line width=1.5ex,text=yellow!40!black,font=\huge\bfseries\scshape,minimum size=4.5cm,text width=4.5cm,},                   
            level 1/.style={level distance=5cm,font=\Large,minimum size=3.0cm,text width=2.5cm,
                sibling angle=60},
            level 2/.style={level distance=9cm,font=\large,minimum
                size=2.0cm,text width=2.0cm,sibling angle=24},
        ]
        \node [root concept]{Suppliers} 
        child[branch color=yellow!70]{node {Retail} 
            child[] {node {CGPI}} 
            child[] {node {Banques priv\'ees}} 
            child[] {node {Retail banking}} 
        }
        child[branch color=yellow!70]{node {ALM} 
            child[] {node {Mutuelles}} 
            child[] {node {Assurances}} 
            child[] {node {Caisse de retraite}}         
        } 
        child[branch color=yellow!80]{node {Directions financi\'eres} 
            child[] {node {Corporate}} 
        } 
        child[branch color=yellow!70]{node {Instrument specialists} 
            child {node {Asset Managers traditionnels}} 
            child {node {Hedge funds}} 
            child {node {Trading desks form other banks}} 
        } 
        ;
    \end{scope}
\end{tikzpicture}
\end{document}

enter image description here

OLDER ANSWER: This is some aux file hackery. The lowest code may be useful for writing an automatized version of the above code.

This code is not too serious an answer. So, yes, one can write stuff to the aux file and recover it when needed. But I definitely do not claim that this is a universally working code. Probably one has to choose the parameters differently. In order to have more than one mindmap, one needs to give the garlic growth a unique id (such as A or B). (I do not like onions, so I called this one garlic.) One has to compile this a few times.

\documentclass[tikz,border=9]{standalone}
\usetikzlibrary{mindmap,decorations}
\usepackage{xspace}
\makeatletter
\newcount\tikzcountchildi
\newcount\tikzcountchildii
\newcount\tikzcountchildiii
\tikzcountchildi=0
\tikzcountchildii=0
\tikzcountchildiii=0
\tikzset{garlic growth/.style={growth function=\tikz@grow@garlic,
/tikz/mmap/name=#1,mmap/#1/.is family,
mmap/initialize counts},
mmap/.cd,initialize counts/.code={\tikzcountchildi=0%
\tikzcountchildii=0%
\tikzcountchildiii=0%
}
}
\def\tikz@mmap@store@aux#1#2{%
\immediate\write\@mainaux{\string\expandafter\xdef\noexpand\csname pgfk@/tikz/mmap/\pgfkeysvalueof{/tikz/mmap/name}/#1\string\endcsname{#2}}}%
\def\tikz@mmap@get@from@aux#1#2{%
\ifcsname pgfk@/tikz/mmap/\pgfkeysvalueof{/tikz/mmap/name}/#1\endcsname
\edef#2{\csname pgfk@/tikz/mmap/\pgfkeysvalueof{/tikz/mmap/name}/#1\endcsname}%
\else
\edef#2{0}%
\fi
}

\newcount\tikzcountgrandchild
\def\tikz@grow@garlic{%
  \ifcase\tikztreelevel 
  \or
    \global\advance\tikzcountchildi by1\relax%
    \ifnum\tikznumberofcurrentchild=1\relax
     \tikz@mmap@store@aux{n}{\the\tikznumberofchildren}%
     \tikz@mmap@store@aux{l-1}{\the\tikzleveldistance}%
    \fi
    \tikzcountchildii=0\relax
  \or
    \global\advance\tikzcountchildii by1\relax%
    \ifnum\tikzcountchildii=1\relax
     \ifnum\tikznumberofcurrentchild=1\relax
      \tikz@mmap@store@aux{l-2}{\the\tikzleveldistance}%
     \fi
    \fi
    \ifnum\tikznumberofcurrentchild=1\relax
     \tikz@mmap@store@aux{n-\the\tikzcountchildi}{\the\tikznumberofchildren}%
     \c@pgf@counta=0\relax% loop counter
     \edef\pgfutil@tempb{0}% angle space needed for this child
     \tikz@mmap@get@from@aux{s-\the\tikzcountchildi}{\pgfutil@tempf}%    
     \pgfmathsetmacro{\pgfutil@tempf}{-\pgfutil@tempf/2}% offset
     \edef\pgfutil@tempe{0}% local rotation angle of grandchild
     \edef\pgfutil@tempg{0}% last angle space needed for grandchild
     % if there were no grandgrand children we only needed to count the children
     \pgfutil@loop
      \ifnum\c@pgf@counta<\tikznumberofchildren
       \advance\c@pgf@counta by1\relax
       \tikz@mmap@get@from@aux{n-\the\tikzcountchildi-\the\c@pgf@counta}{\pgfutil@tempa}%
        \ifnum\pgfutil@tempa=0\relax
         %\typeout{level \the\tikzcountchildi-\the\c@pgf@counta :found 0 children}
         \pgfmathsetmacro{\pgfutil@tempg}{\pgfkeysvalueof{/tikz/mmap/angle 2}}%
        \else
         %\typeout{level \the\tikzcountchildi-\the\c@pgf@counta :found \pgfutil@tempa\space children}
         \pgfmathsetmacro{\pgfutil@tempg}{max(\pgfkeysvalueof{/tikz/mmap/angle 2},%
         \pgfutil@tempa*\pgfkeysvalueof{/tikz/mmap/angle 3})}%
        \fi
        \pgfmathsetmacro{\pgfutil@tempe}{\pgfutil@tempf+\pgfutil@tempb+\pgfutil@tempg/2}%
        \tikz@mmap@store@aux{t-\the\tikzcountchildi-\the\c@pgf@counta}{\pgfutil@tempe}%
        \pgfmathsetmacro{\pgfutil@tempb}{\pgfutil@tempb+\pgfutil@tempg}%        
      \pgfutil@repeat
      %\typeout{n_1=\the\tikzcountchildi : space needed=\pgfutil@tempb}%
      \tikz@mmap@store@aux{s-\the\tikzcountchildi}{\pgfutil@tempb}%
      \ifnum\tikzcountchildi=1
       \tikz@mmap@store@aux{t-\the\tikzcountchildi}{\pgfutil@tempb/2}%
      \else
       \tikz@mmap@get@from@aux{s-\the\numexpr\tikzcountchildi-1}{\pgfutil@tempc}%
       \tikz@mmap@get@from@aux{t-\the\numexpr\tikzcountchildi-1}{\pgfutil@tempd}%
       \pgfmathsetmacro{\pgfutil@tempa}{\pgfutil@tempd+\pgfutil@tempc/2+\pgfutil@tempb/2}%
       \tikz@mmap@store@aux{t-\the\tikzcountchildi}{\pgfutil@tempa}%
      \fi 
    \fi
    %\typeout{level \the\tikzcountchildi-\the\tikzcountchildii:
    %\the\tikznumberofcurrentchild/\the\tikznumberofchildren}
    \pgfmathsetmacro{\pgfutil@tempg}{\tikznumberofchildren*\pgfkeysvalueof{/tikz/mmap/angle 2}}%
    \tikz@mmap@store@aux{s-\the\tikzcountchildi-\the\tikzcountchildii}{\pgfutil@tempg}%     
    \tikzcountchildiii=0\relax
  \or
    \global\advance\tikzcountchildiii by1\relax%
    \ifnum\tikznumberofcurrentchild=1\relax
     \tikz@mmap@store@aux{n-\the\tikzcountchildi-\the\tikzcountchildii}{\the\tikznumberofchildren}%
    \fi 
    \pgfmathsetmacro{\pgfutil@tempa}{(\tikznumberofcurrentchild-\tikznumberofchildren/2-1/2)*%
        (\pgfkeysvalueof{/tikz/sibling angle})}
    \tikz@mmap@store@aux{t-\the\tikzcountchildi-\the\tikzcountchildii-\the\tikzcountchildiii}{\pgfutil@tempa}%
  \fi
  \pgftransformreset% 
  \pgftransformshift{\pgfpoint{\pgfkeysvalueof{/tikz/mmap/overall xshift}}%
        {\pgfkeysvalueof{/tikz/mmap/overall yshift}}}%
  \tikz@mmap@get@from@aux{t-\the\tikzcountchildi}{\pgfutil@tempa}%
  \pgfmathsetmacro{\pgfutil@tempb}{\pgfkeysvalueof{/tikz/mmap/overall rotation}+\pgfkeysvalueof{/tikz/mmap/sign}*\pgfutil@tempa}%
  \pgftransformrotate{\pgfutil@tempb}%
  \tikz@mmap@get@from@aux{l-1}{\pgfutil@tempc}%
  \pgftransformxshift{\pgfutil@tempc}%
  \ifnum\tikztreelevel=1
    %\typeout{t-\the\tikzcountchildi: rotate by \pgfutil@tempb (t=\pgfutil@tempa)}
  \else
    \tikz@mmap@get@from@aux{t-\the\tikzcountchildi-\the\tikzcountchildii}{\pgfutil@tempa}%
    \pgftransformrotate{\pgfutil@tempa}%
    \tikz@mmap@get@from@aux{l-2}{\pgfutil@tempc}%
    \pgftransformxshift{\pgfutil@tempc}%
    %\typeout{level 2 rotation by \pgfutil@tempa\space and shift by \pgfutil@tempc}
    \ifnum\tikztreelevel=2
    \else
     \tikz@mmap@get@from@aux{t-\the\tikzcountchildi-\the\tikzcountchildii-\the\tikzcountchildiii}{\pgfutil@tempa}%
     \pgftransformrotate{\pgfutil@tempa}%
     \pgftransformxshift{\the\tikzleveldistance}%
    \fi
  \fi
}
\makeatother
\begin{document}
\tikzset{mmap/.cd,
    name/.initial=undef,
    overall rotation/.initial=0,
    overall xshift/.initial=0pt,
    overall yshift/.initial=0pt,
    angle 1/.initial=5,
    angle 2/.initial=25,
    angle 3/.initial=15,
    sign/.initial=1,
    /tikz/.cd,
    Xshift/.style={xshift=#1,mmap/overall xshift=#1},
    Yshift/.style={yshift=#1,mmap/overall yshift=#1},
    branch color/.style={
        concept color=#1!white,
        every child/.append style={concept color=#1!white!30!white},
    }
}

\begin{tikzpicture}
    \begin{scope}[text width=1.5cm,align=flush center,
            mindmap,garlic growth=A,
            mmap/overall rotation=135,mmap/sign=-1,
            sibling angle=40,
            nodes={concept},
            concept color=green!70!black,
            root concept/.append style={ball color=green!50, line width=1.5ex,text=green!40!black,font=\huge\bfseries\scshape,minimum size=4.5cm,text width=4.5cm,},                   
            level 1/.style={level distance=5cm,font=\Large,minimum size=3.0cm,text width=2.5cm,},
            level 2/.style={level distance=6cm,font=\large,minimum size=2.0cm,text width=2.0cm},
            level 3/.style={level distance=4cm,font=\large,minimum size=2.0cm,text width=2.0cm}
        ]
        \node [root concept]{Clients} 
        child[branch color=green!70]{node {Retail} 
            child[] {node {CGPI}} 
            child[] {node {Banques priv\'ees}} 
            child[] {node {Retail banking}} 
        }
        child[branch color=green!70]{node {ALM} 
            child { node (equity) {Equity}
                child { node {Indices}}
                child { node {Stocks}}
                child { node {ETFs}}
            }
            child { node (commo) {Commodities}
                child { node {Soft commo}}
                child { node {Precious}}        
                child { node {Oil/Gas}}
            }
            child[] {node {Assurances}} 
            child[] {node {Caisse de retraite}}         
        } 
        child[branch color=green!80]{node {Directions financi\'eres} 
            child[] {node {Corporate}} 
        } 
        child[branch color=green!70]{node {Instrument specialists} 
            child {node {Asset Managers traditionnels}} 
            child {node {Hedge funds}} 
            child {node {Trading desks form other banks}} 
        } 
        ;
    \end{scope}

    \begin{scope}[Xshift=-12cm,Yshift=3cm,text width=1.5cm,align=flush center,
            mindmap,garlic growth=B,
            mmap/overall rotation=250,mmap/sign=-1,
            nodes={concept},
            concept color=yellow!70!black,
            root concept/.append style={ ball color=yellow!50, line width=1.5ex,text=yellow!40!black,font=\huge\bfseries\scshape,minimum size=4.5cm,text width=4.5cm,},                   
            level 1/.style={level distance=6cm,font=\Large,minimum size=3.0cm,text width=2.5cm,},
            level 2/.style={level distance=6cm,font=\large,minimum
                size=2.0cm,text width=2.0cm},
            mmap/.cd,
            angle 1=5,angle 2=20,angle 3=5,
        ]
        \node [root concept]{Suppliers} 
        child[branch color=yellow!70]{node {Retail} 
            child[] {node {CGPI}} 
            child[] {node {Banques priv\'ees}} 
            child[] {node {Retail banking}} 
        }
        child[branch color=yellow!70]{node {ALM} 
            child[] {node {Mutuelles}} 
            child[] {node {Assurances}} 
            child[] {node {Caisse de retraite}}         
        } 
        child[branch color=yellow!80]{node {Directions financi\'eres} 
            child[] {node {Corporate}} 
        } 
        child[branch color=yellow!70]{node {Instrument specialists} 
            child {node {Asset Managers traditionnels}} 
            child {node {Hedge funds}} 
            child {node {Trading desks form other banks}} 
        } 
        ;
    \end{scope}
\end{tikzpicture}
\end{document}

enter image description here

Overall I think it may make more sense to marry the graph drawing algorithms to mind map. Some spring layout or whatever. Something where an algorithm tries to find the optimal values.

ADDENDUMM: This is work in progress. If I do not succeed, which is quite possible, here is a better structured and documented base version of the code. I have not added any explicit growth function, but this is the easier part (IMHO). It stores the number of leafs in the aux file and also computes a quantity m which is explained in the code.

\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{mindmap}
\usepackage[fleqn]{amsmath}
\makeatletter
\newif\ifmmap@debug
\mmap@debugtrue
\newcommand{\mmap@debug@message}[1]{\ifmmap@debug
\typeout{#1}%
\fi}
\newcount\tikzcountchildi
\newcount\tikzcountchildii
\newcount\tikzcountchildiii
\newcount\tikzcountchildiv
\newcount\tikzcountchildv
\tikzcountchildi=0
\tikzcountchildii=0
\tikzcountchildiii=0
\tikzcountchildiv=0
\tikzcountchildv=0
\tikzset{garlic growth/.style={growth function=\tikz@grow@garlic,
/tikz/mmap/name=#1,mmap/#1/.is family,
mmap/initialize counts},
mmap/.cd,initialize counts/.code={\tikzcountchildi=0%
\tikzcountchildii=0%
\tikzcountchildiii=0%
\tikzcountchildiv=0%
\tikzcountchildv=0%
}
}
\def\tikz@mmap@store@aux#1#2{%
\immediate\write\@mainaux{\string\expandafter\xdef\noexpand\csname pgfk@/tikz/mmap/\pgfkeysvalueof{/tikz/mmap/name}/#1\string\endcsname{#2}}}%
\def\tikz@mmap@get@from@aux#1#2{%
\ifcsname pgfk@/tikz/mmap/\pgfkeysvalueof{/tikz/mmap/name}/#1\endcsname
\edef#2{\csname pgfk@/tikz/mmap/\pgfkeysvalueof{/tikz/mmap/name}/#1\endcsname}%
\else
\edef#2{0}%
\fi
}
% m is the effective number of children
\def\tikz@compute@mandn#1{% #1=current level k
     \ifcase#1\relax % build up identifier : -i_1-i_2-...-i_k
     \or
      \edef\pgfutil@tempc{-\the\tikzcountchildi}% 
     \or
      \edef\pgfutil@tempc{-\the\tikzcountchildi-\the\tikzcountchildii}% 
     \or
      \edef\pgfutil@tempc{-\the\tikzcountchildi-\the\tikzcountchildii-\the\tikzcountchildiii}% 
     \or
      \edef\pgfutil@tempc{-\the\tikzcountchildi-\the\tikzcountchildii-\the\tikzcountchildiii-\the\tikzcountchildiv}% 
     \or
      \edef\pgfutil@tempc{-\the\tikzcountchildi-\the\tikzcountchildii-\the\tikzcountchildiii-\the\tikzcountchildiv-\the\tikzcountchildv}% 
     \fi
     % store the number of children of parent leaf (and the level distance)
     \ifnum\tikznumberofcurrentchild=1\relax
      \tikz@mmap@store@aux{l-#1}{\the\tikzleveldistance}%
      \tikz@mmap@store@aux{n\pgfutil@tempc}{\the\tikznumberofchildren}%
     \fi
     \ifnum\tikznumberofchildren=0\relax % no children
      \pgfmathsetmacro{\pgfutil@tempb}{\pgfkeysvalueof{/tikz/mmap/angle #1}}
     \else 
      % sum over the children 
      \c@pgf@counta=0\relax% loop counter
      \edef\pgfutil@tempb{0}% accumulate angle space m needed for this child
      \pgfutil@loop
       \ifnum\c@pgf@counta<\tikznumberofchildren
        \advance\c@pgf@counta by1\relax
        % read out the m value of child
        \tikz@mmap@get@from@aux{m\pgfutil@tempc-\the\c@pgf@counta}{\pgfutil@tempa}%
        \ifdim\pgfutil@tempa pt=0pt\relax
         \pgfmathsetmacro{\pgfutil@tempa}{\pgfkeysvalueof{/tikz/mmap/angle \the\numexpr#1+1}}%
         \mmap@debug@message{m\pgfutil@tempc-\the\c@pgf@counta=0, so added standard angle \pgfutil@tempa}
        \else
         \pgfmathsetmacro{\pgfutil@tempa}{max(\pgfkeysvalueof{/tikz/mmap/angle \the\numexpr#1+1},\pgfutil@tempa}%
         \mmap@debug@message{m\pgfutil@tempc-\the\c@pgf@counta=\pgfutil@tempa\space found and added}%
        \fi
        \pgfmathsetmacro{\pgfutil@tempb}{\pgfutil@tempb+\pgfutil@tempa}%
       \pgfutil@repeat
      \fi 
      \tikz@mmap@store@aux{m\pgfutil@tempc}{\pgfutil@tempb}%
}

\def\tikz@grow@garlic{%
  \ifcase\tikztreelevel 
  \or
    \global\advance\tikzcountchildi by1\relax%
    \ifnum\tikznumberofcurrentchild=1\relax
     \tikz@mmap@store@aux{n}{\the\tikznumberofchildren}%
     \tikz@mmap@store@aux{l-1}{\the\tikzleveldistance}%
    \fi
    \tikzcountchildii=0\relax
  \or
    \global\advance\tikzcountchildii by1\relax%
    \tikz@compute@mandn1
    \tikzcountchildiii=0\relax
  \or
    \global\advance\tikzcountchildiii by1\relax%
    \tikz@compute@mandn2
    \tikzcountchildiv=0\relax
  \or
    \global\advance\tikzcountchildiv by1\relax%
    \tikz@compute@mandn3
    \tikzcountchildv=0\relax
  \or
    \global\advance\tikzcountchildv by1\relax%
    \tikz@compute@mandn4
  \fi
  \pgftransformreset% 
  \pgftransformshift{\pgfpoint{\pgfkeysvalueof{/tikz/mmap/overall xshift}}%
        {\pgfkeysvalueof{/tikz/mmap/overall yshift}}}%
}
\makeatother
\begin{document}
\tikzset{mmap/.cd,
    name/.initial=undef,
    overall rotation/.initial=0,
    overall xshift/.initial=0pt,
    overall yshift/.initial=0pt,
    angle 1/.initial=20,
    angle 2/.initial=20,
    angle 3/.initial=20,
    angle 4/.initial=20,
    angle 5/.initial=20,
    sign/.initial=1,
    /tikz/.cd,
    Xshift/.style={xshift=#1,mmap/overall xshift=#1},
    Yshift/.style={yshift=#1,mmap/overall yshift=#1},
    branch color/.style={
        concept color=#1!white,
        every child/.append style={concept color=#1!white!30!white},
    }
}

\begin{tikzpicture}
    \begin{scope}[text width=1.5cm,align=flush center,
            mindmap,garlic growth=A,
            mmap/overall rotation=135,mmap/sign=-1,
            sibling angle=33,
            nodes={concept},
            concept color=green!70!black,
            root concept/.append style={ball color=green!50, line width=1.5ex,text=green!40!black,font=\huge\bfseries\scshape,minimum size=4.5cm,text width=4.5cm,},                   
            level 1/.style={level distance=5cm,font=\Large,minimum size=3.0cm,text width=2.5cm,},
            level 2/.style={level distance=6cm,font=\large,minimum size=2.0cm,text width=2.0cm},
            level 3/.style={level distance=4cm,font=\large,minimum
            size=2.0cm,text width=2.0cm},
            mmap/.cd,angle 1=-5,angle 2=25,angle 3=14,          
        ]
        \node [root concept]{Clients} 
        child[branch color=green!70]{node {Retail} 
            child[] {node {CGPI}} 
            child[] {node {Banques priv\'ees}} 
            child[] {node {Retail banking}} 
        }
        child[branch color=green!70]{node {ALM} 
            child { node (equity) {Equity}
                child { node {Indices}}
                child { node {Stocks}}
                child { node {ETFs}}
            }
            child { node (commo) {Commodities}
                child { node {Soft commo}}
                child { node {Precious}}        
                child { node {Oil/Gas}}
            }
            child[] {node {Assurances}} 
            child[] {node {Caisse de retraite}}         
        } 
        child[branch color=green!80]{node {Directions financi\'eres} 
            child[] {node {Corporate}} 
        } 
        child[branch color=green!70]{node {Instrument specialists} 
            child {node {Asset Managers traditionnels}} 
            child {node {Hedge funds}} 
            child {node {Trading desks form other banks}} 
        } 
        ;
    \end{scope}

    \begin{scope}[Xshift=-12cm,Yshift=3cm,text width=1.5cm,align=flush center,
            mindmap,garlic growth=B,
            mmap/overall rotation=250,mmap/sign=-1,
            nodes={concept},
            concept color=yellow!70!black,
            root concept/.append style={ ball color=yellow!50, line width=1.5ex,text=yellow!40!black,font=\huge\bfseries\scshape,minimum size=4.5cm,text width=4.5cm,},                   
            level 1/.style={level distance=6cm,font=\Large,minimum size=3.0cm,text width=2.5cm,},
            level 2/.style={level distance=6cm,font=\large,minimum
                size=2.0cm,text width=2.0cm},
            mmap/.cd,
            angle 1=5,angle 2=20,angle 3=5,
        ]
        \node [root concept]{Suppliers} 
        child[branch color=yellow!70]{node {Retail} 
            child[] {node {CGPI}} 
            child[] {node {Banques priv\'ees}} 
            child[] {node {Retail banking}} 
        }
        child[branch color=yellow!70]{node {ALM} 
            child[] {node {Mutuelles}} 
            child[] {node {Assurances}} 
            child[] {node {Caisse de retraite}}         
        } 
        child[branch color=yellow!80]{node {Directions financi\'eres} 
            child[] {node {Corporate}} 
        } 
        child[branch color=yellow!70]{node {Instrument specialists} 
            child {node {Asset Managers traditionnels}} 
            child {node {Hedge funds}} 
            child {node {Trading desks form other banks}} 
        } 
        ;
    \end{scope}
    \node[anchor=south,text width=14cm] at (current bounding box.north)
    {Let us define an array $m$ recursively as follows. For any \emph{outermost}
    leaf
    \[ 
      m_{i_1i_2\cdots i_k}=\alpha_k\;,
    \]
    where $k$ is the level and $\alpha_k$ is the level--dependent ``standard
    angle''. In the code, 
    \[
     \alpha_k=\texttt{\textbackslash pgfkeysvalueof\{/tikz/mmap/angle $k$\}}\;,
    \]
    i.e.\ the $\alpha_k$ are stored in the keys \texttt{angle $k$} in the
    \texttt{mmap} directory. If the leaf is \emph{not outermost}, $m$ is defined
    as the sum of the $m$--values of the children,
    \[ 
     m_{i_1i_2\cdots i_k}=
     \sum\limits_{j=1}^{n_\mathrm{children}}
     \max \{m_{i_1i_2\cdots i_k-j},\alpha_k\}\;.
    \]
    };
\end{tikzpicture}
\end{document}

enter image description here

I think one needs to clarify how the tree should look like. Then one can conceivably use the stored leaf counts and m entries to draw it.

9
  • Just wow ! Your answer is not a joke :) Your code is very dense and I'm currently playing with the new options you put in the growcycle. Once you have the counter at level 1, 2 and 3, could not we just "imply" the node angles going from level 3, then level 2 and level 1 ? I'd like to type an example but i'll add it to my post.
    – JeT
    Mar 21, 2020 at 9:59
  • I updated my post, maybe it's too simplistic a way to see things from my side :)
    – JeT
    Mar 21, 2020 at 10:09
  • 1
    @Julien-ElieTaieb This is more or less what the code does. If you remove the % before the \typeout commands and/or look at the aux file you will see that it keeps track of how many children a node has, and how many grand children the children have. For instance, \expandafter\xdef \csname pgfk@/tikz/mmap/A/n-1\endcsname{3} tells us that in the green char the first node has 3 children, and \expandafter\xdef \csname pgfk@/tikz/mmap/A/n-2-1\endcsname{3} says that the first child of child 2 has 3 children.
    – user194703
    Mar 21, 2020 at 14:26
  • 1
    @Julien-ElieTaieb I added a better documented version. This is also a response to the edit of your question. However, I fail to fully understand it. Could you please have a look at the addendum and let me know how the quantities computed and recorded there (if any) can be used in your construction?
    – user194703
    Mar 21, 2020 at 20:20
  • Merci @ Schrödinger's cat ! I tried to compile your code (twice) but I i just get the 2 concept nodes and all the nodes in the middle.
    – JeT
    Mar 21, 2020 at 20:38
5

I have rewrite the grow function. Now you have to specify nold, which is the number of leaf descendants. That is, count the number of descendants who don't have any child. Cat's Xshift and Yshift are kept. But I renamed the internal overall xxxx as smuggle xxxx. Because we are smuggling the parameter over the \pgftransformreset barrier.

\documentclass[tikz,border=9]{standalone}
\usetikzlibrary{mindmap}

\makeatletter
\newcount\tikz@count@leaf % count only leaf
\def\tikz@grow@concentric{
    \pgftransformreset%
    \pgftransformshift{\pgfpoint
        {\pgfkeysvalueof{/tikz/smuggle xshift}}
        {\pgfkeysvalueof{/tikz/smuggle yshift}}}
    \pgftransformrotate{
        \pgfkeysvalueof{/tikz/smuggle rotation}+
        (\pgfkeysvalueof{/tikz/sibling angle})*(\tikz@count@leaf)}
    \ifnum\pgfkeysvalueof{/tikz/nold}=0
        % this is a leaf
        \global\advance\tikz@count@leaf by1
    \else
        % this is not a leaf
        % we need to rotate it further
        \pgftransformrotate{
            (\pgfkeysvalueof{/tikz/sibling angle})*
            (\pgfkeysvalueof{/tikz/nold}-1)/2}
        \tikzset{nold/.initial=0} % reset for safty
    \fi
    \pgftransformxshift{\the\tikzleveldistance}
}

\begin{document}
\tikzset{
    smuggle rotation/.initial=0,
    smuggle xshift/.initial=0pt,
    smuggle yshift/.initial=0pt,
    Xshift/.style={xshift=#1,smuggle xshift=#1},
    Yshift/.style={yshift=#1,smuggle yshift=#1},
    Rotate/.style={smuggle rotate=#1},
    nold/.initial=0, % hint tikz the number of leaf in its descendants
    % explain: don't count a child if they have your grand-child
    branch color/.style={
        concept color=#1!white,
        every child/.append style={concept color=#1!white!30!white},
    }
}

\begin{tikzpicture}
    \draw foreach\i in{1,...,36}{
        (0:0)--(\i*10:15)
    };
    \begin{scope}[text width=1.5cm,align=flush center,
            mindmap,growth function=\tikz@grow@concentric,
            smuggle rotation=-30,
            sibling angle=10,
            nodes={concept},
            concept color=green!70!black,
            root concept/.append style={
                ball color=green!50,line width=1.5ex,text=green!40!black,
                font=\huge\bfseries\scshape,minimum size=4.5cm,text width=4.5cm
            },
            level 1/.style={
                level distance=8cm,font=\Large,
                minimum size=3.0cm,text width=2.5cm
            },
            level 2/.style={
                level distance=12cm,font=\large,
                minimum size=2.0cm,text width=2.0cm
            },
            level 3/.style={
                level distance=15cm,font=\large,
                minimum size=2.0cm,text width=2.0cm
            }
        ]
        \node [root concept]{Clients}
        child[nold=3,branch color=green!70]{node {Retail} 
            child {node {CGPI}} 
            child {node {Banques priv\'ees}}
            child {node {Retail banking}} 
        }
        child[nold=8,branch color=green!70]{node {ALM}
            child[nold=3]{ node (equity) {Equity}
                child { node {Indices}}
                child { node {Stocks}}
                child { node {ETFs}}
            }
            child[nold=3]{ node (commo) {Commodities}
                child { node {Soft commo}}
                child { node {Precious}}
                child { node {Oil/Gas}}
            }
            child {node {Assurances}}
            child {node {Caisse de retraite}}
        }
        child[nold=1,branch color=green!80]{node {Directions financieres}
            child {node {Corporate}}
        }
        child[nold=3,branch color=green!70]{node {Instrument specialists} 
            child {node {Asset Managers traditionnels}}
            child {node {Hedge funds}}
            child {node {Trading desks form other banks}}
        }
        ;
    \end{scope}
\end{tikzpicture}
\end{document}

1
  • Wow! Thank you symbol :) when I read the new function I understand it would actually apply to level 3 or 4 as long as we describe correctly the argument nold. Merci !
    – JeT
    Mar 15, 2020 at 22:26

You must log in to answer this question.

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