我想在 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}