5

I would like to increment and print counter at some node of tikz tree. I am able to do it when the tree grows to bottom, but not when it grows to left.

My problem is that couter must be increment following the y axis.

That is a MWE

\documentclass{article}
\usepackage{tikz}

\newcounter{toto}

\newcommand{\toto}{%
  \stepcounter{toto}%
  \ - \thetoto%
}


\begin{document}
\section{Ok}
  \begin{tikzpicture}[sibling distance=4cm,
                      edge from parent/.style={draw,thick}]
   \node{A\toto}
        child {node {B\toto}}
        child {node[] {C\toto}
            child {node  {D}}
            child {node {E\toto}
              }
        };


\end{tikzpicture}

\section{Not ok}

\setcounter{toto}{0}
\begin{tikzpicture}[grow=right,sibling distance=4cm,
                      edge from parent/.style={draw,thick}]
   \node{A}
        child {node {B\toto} }
        child {node[align=right] {C\toto}
            child {node  {D\toto}}
            child {node {E\toto}
              }
        };

\end{tikzpicture}
\end{document}

MWE

In the "Not Ok" example, the expected value should be :

  • E : 1
  • C : 2
  • D : 3
  • B : 4
  • Why do you continuously escape brackets in your code? – percusse Aug 15 '14 at 13:17
  • it was a pastebin mistake. Corrected. thanks. – Maïeul Aug 15 '14 at 13:19
1

The code below solves the OPs problem. The trick is to let tikz place the nodes and then to add the labels for the nodes afterwards. To place the nodes in the requested order I use the datatool package to sort the nodes according to height before printing their labels. For the OP's two examples the output is:

enter image description here

As I understand the question, the labels in (2) are now OK.

The letters are the node labels whereas the numbers come from your toto counter inserted via the \SortNodes macro defined below. This macro creates a datatool database that contains the node coordinates. Making a database for the nodes seems like overkill but the point is that once they are in the database they can be easily sorted and looped over. Perhaps there is an easier/better way to do this, but this was the only way that I found to sort them.

Here is the code:

\documentclass{article}
\usepackage{datatool}
\dtlexpandnewvalue% need  to expand the entries added to the database
\usepackage{tikz}
\usetikzlibrary{calc}

\newcounter{toto}
\makeatletter
\def\extractcoord#1#2#3{%from https://tex.stackexchange.com/questions/18292
  \path let \p1=(#3) in \pgfextra{
    \pgfmathsetmacro#1{\x{1}/\pgf@xx}
    \pgfmathsetmacro#2{\y{1}/\pgf@yy}
    \xdef#1{#1} \xdef#2{#2}
  };
}
\newcommand\SortNodes[1]{%
  % create the database and add the nodes
  \DTLifdbexists{nodes}{\DTLcleardb{nodes}}{\DTLnewdb{nodes}}%
  \foreach \Node in {#1} {%
     \extractcoord\Nodex\Nodey\Node
     \DTLnewrow{nodes}% add (x,y)-coordinates + Node label
     \DTLnewdbentry{nodes}{x}{\Nodex}
     \DTLnewdbentry{nodes}{y}{\Nodey}
     \DTLnewdbentry{nodes}{node}{\Node}% not needed here but added anyway
  }
  \DTLsort*{y=descending,x}{nodes}%
  \DTLforeach*{nodes}{\xx=x,\yy=y,\Node=node}{%
    \node at (\xx,\yy) {\stepcounter{toto}\Node-\thetoto};% print node label
 }%
}%
\makeatother

\begin{document}
\section{Ok}
  \begin{tikzpicture}[sibling distance=4cm,
                      edge from parent/.style={draw,thick}]

  \node(A){}
        child {node (B){}}
        child {node (C){}
            child {node (D){}}
            child {node (E){}}
        };

        \SortNodes{A,B,C,D,E}

\end{tikzpicture}

\section{Not ok}

  \setcounter{toto}{0}
\begin{tikzpicture}[grow=right,sibling distance=4cm,
                      edge from parent/.style={draw,thick}]

  \node(A){}
        child {node (B){}}
        child {node (C){}
            child {node (D){}}
            child {node (E){}}
        };
   \SortNodes{A,B,C,D,E}

\end{tikzpicture}

\end{document}

To find the coordinates of the nodes I use a slightly different technique than in my related answer for the OP. The main reason for this is that I had trouble getting the database to work and, initially, I thought that the coordinates were the problem. In fact, they were the problem but for different reasons: the issue was the the entries added to the database need to be expanded so once I found the command \dtlexpandnewvalue everything worked.

This is a chance that this solution will not be compatible with the OP's use-case but I think this will be OK.

| improve this answer | |
  • thanks a lot. It's work for this particular case, but it's to less flexible to be integrated in a general solution. I have found a other way. – Maïeul Aug 25 '14 at 13:16
5

You can execute the counter stepping at each child instead, which works independent of the growth direction or add only to the specific nodes as a style by changing the name and providing externally to each child node.

But you can't change the parsing order of how TikZ reads off how many children there are etc.

\documentclass[tikz]{standalone}
\newcounter{toto}
\setcounter{toto}{1}
\begin{document}
\begin{tikzpicture}[grow=right,sibling distance=4cm,edge from parent/.style={draw,thick},
every child node/.append style={/utils/exec=\stepcounter{toto}}]
   \node{A\thetoto}
        child {node {B\thetoto} }
        child {node[align=right] {C\thetoto}
            child {node  {D\thetoto}}
            child {node {E\thetoto}
              }
        };

\end{tikzpicture}
\end{document}

enter image description here

| improve this answer | |
  • ok, so that is link the order of parsing, not the vertical order. That don't change for my problem ... – Maïeul Aug 15 '14 at 13:33
  • @Maïeul Yes, so it's not possible to get the physical position of the node first and the assign the counter. The reason for my example is to show the order of execution. You need to hack deep to get into the child number that TikZ harvests and squeeze code there to put the counter. – percusse Aug 15 '14 at 13:39

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.