tikz 树内的计数器

tikz 树内的计数器

我想在 tikz 树的某个节点增加并打印计数器。当树长到底部时我可以做到这一点,但当它长到左边时就不行了。

我的问题是计数器必须沿着 y 轴递增。

这是一个 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}

平均能量损失

在“Not Ok”的例子中,预期值应该是:

  • 電子郵件 : 1
  • 丙:2
  • 数量:3
  • 乙:4

答案1

下面的代码解决了OP问题。诀窍是让蒂克兹 放置节点,然后为节点添加标签。为了按要求的顺序放置节点,我使用数据工具包在打印节点标签之前根据高度对节点进行排序。对于 OP 的两个示例,输出为:

在此处输入图片描述

据我理解,(2)中的标签现在是可以的。

字母是节点标签,而数字则来自toto通过\SortNodes下面定义的宏插入的计数器。此宏创建一个datatool包含节点坐标的数据库。为节点创建数据库似乎有点过分,但关键是一旦它们进入数据库,就可以轻松对它们进行排序和循环。也许有更简单/更好的方法来做到这一点,但这是我发现的唯一对它们进行排序的方法。

以下是代码:

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

为了找到节点的坐标,我使用了一种与我的略有不同的技术 相关答案对于 OP 来说。主要原因是我很难让数据库正常工作,最初,我认为坐标是问题所在。事实上,它们才是问题所在,但原因不同:问题是添加到数据库中的条目需要扩展,所以一旦我找到命令,\dtlexpandnewvalue一切都会正常。

这个解决方案可能与 OP 的用例不兼容,但我认为这没问题。

答案2

您可以在每个子节点上执行反向步进,其工作与增长方向无关,或者通过更改名称并向每个子节点外部提供,仅将特定节点作为样式添加到特定节点。

但是您无法改变 TikZ 读取有多少个子项的解析顺序等等。

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

在此处输入图片描述

相关内容