Tikz:从列表创建节点并调整路径起始位置

Tikz:从列表创建节点并调整路径起始位置

作为更大图表的一部分,我写了下面的内容,它基本上实现了我想要的功能:

\documentclass{report}
\usepackage{tikz}
\usetikzlibrary{arrows,positioning}
\begin{document}

\begin{tikzpicture}[box/.style={rectangle,draw=black},
                    vh path/.style={to path={|- (\tikztotarget)}}
                   ]
  \node[box] (ReadQueryParametersJSON) at (0,0) {ReadQueryParametersJSON};
  \node[box] (ParseParametricLine) [below=of ReadQueryParametersJSON,anchor=west,xshift=-1cm] {ParseParametricLine};
  \node[box] (ReadJSONFile) [below=of ParseParametricLine.west,anchor=west] {ReadJSONFile};
  \node[box] (GUIMapping) [below=of ReadJSONFile.west,anchor=west] {GUIMapping};

  \path [->] (node cs:name=ReadQueryParametersJSON,angle=-169.69) edge [vh path] (GUIMapping)
             (node cs:name=ReadQueryParametersJSON,angle=-168.69) edge [vh path] (ReadJSONFile)
             (node cs:name=ReadQueryParametersJSON,angle=-167.47) edge [vh path] (ParseParametricLine);

  %\node[box] (root) at (0,-4) {root};
  %\foreach \name in {aa,bb,cc,dd}
  %   \node[box] (\name) at ++(0,-1) {\name};
\end{tikzpicture} 


\end{document}

我能找到的唯一一种偏移箭头起点的机制是使用角度,这意味着对于均匀间距,参数取决于反正切和盒子的尺寸。这有点复杂。有更好的方法吗?

我需要多次创建这样的结构,因此我尝试编写一个循环来自动生成此结构,从注释掉的代码开始。此代码将根节点放在 (1,-4) 处,并将所有列出的节点放在绝对位置 (1,-1) 的顶部,尽管我使用 ++ 来获取相对位置。为什么这不起作用?我该如何编写此循环(不使用绝对坐标,以便子节点相对于父节点定位)?


marmot 的 xshift 解决方案正是我所需要的。我尝试将 xshift 放在各个地方,但似乎没有任何效果。另一个使用循环的解决方案也很好用。我发现我有 2.10 版的手册,这解释了为什么我找不到这些选项。

当我使用循环生成布局时,我无法绘制线条,这是个谜。当我准备发布这个例子时,这个问题变得更加神秘,因为它开始起作用了——有时。所以在这个例子中,我生成了两组节点。一组我使用我定义的新命令绘制线条,它可以工作。另一次我只是试图画一条线,但它不起作用。我搞不清楚有什么区别,为什么它一次有效,另一次无效。另一个问题是,是否有一种整洁的方法来避免将顶部子节点视为特殊参数(因为它本身需要向右移动)。最后,我添加了一个节点距离规范来收紧布局,手册上说距离应该是边到边,但我得到的是从中心到中心。为什么?

\documentclass{report}
\usepackage{tikz}
\usetikzlibrary{arrows,positioning}
\begin{document}

% arguments: {root node}{root node position}{first child}{list of remaining children}
\newcommand{\verticalnodes}[4]{
       \node[box] (#1) at #2 {#1};
       \node[box] (#3) [below=of #1.west,anchor=west,xshift=1cm] {#3};  % Can this special case go in the loop?
       \foreach \name [remember= \name as \n (initially #3),count=\shift from 0]in #4 {
          \node[box,below=of \n.west,anchor=west] (\name) {\name};
          %\path [->] ([xshift=6mm-\shift*2 mm]#1.south west) edge  [vh path](\name);
       }
}

% Arguments: {root node}{list of children}{horizontal offset of rightmost line from left edge}
\newcommand{\drawlines}[3]{
   \foreach \name [count=\shift from 0]in #2
     \path [->] ([xshift=#3-\shift*2 mm]#1.south west) edge [vh path](\name);
}

\begin{tikzpicture}[box/.style={rectangle,draw=black,node distance=6mm}, % Not getting 6mm spacing
                            vh path/.style={to path={|- (\tikztotarget)}}
                   ]
  \verticalnodes{ReadQueryParametersJSON}{(0,0)}{ParseParametricLine}{{ReadJSONFile,GUIMapping}}
  \drawlines{ReadQueryParametersJSON}{{ParseParametricLine,ReadJSONFile,GUIMapping}}{6mm}

  \node[box] (rootroot) at (0,6) {rootroot};
  \node[box] (toplevel) [below=of rootroot.west,anchor=west,xshift=1cm] {toplevel};
  \foreach \name [remember= \name as \n (initially toplevel)]in {aaaaaa,bbbbbbbbbbbb,cccccccccc} {
      \node[box,below=of \n.west,anchor=west] (\name) {\name};
  }
  path [->] (rootroot) edge [vh path] (toplevel);  % Why doesn't this draw anything?

\end{tikzpicture} 
\end{document}

答案1

您在寻找过去的美好xshift吗?

\documentclass{report}
\usepackage{tikz}
\usetikzlibrary{arrows,positioning}
\begin{document}

\begin{tikzpicture}[box/.style={rectangle,draw=black},
                    vh path/.style={to path={|- (\tikztotarget)}}
                   ]
  \node[box] (ReadQueryParametersJSON) at (0,0) {ReadQueryParametersJSON};
  \node[box] (ParseParametricLine) [below=of ReadQueryParametersJSON,anchor=west,xshift=-1cm] {ParseParametricLine};
  \node[box] (ReadJSONFile) [below=of ParseParametricLine.west,anchor=west] {ReadJSONFile};
  \node[box] (GUIMapping) [below=of ReadJSONFile.west,anchor=west] {GUIMapping};

  \path [->] ([xshift=4mm]ReadQueryParametersJSON.south west) edge [vh path] (GUIMapping)
             ([xshift=6mm]ReadQueryParametersJSON.south west) edge [vh path] (ReadJSONFile)
             ([xshift=8mm]ReadQueryParametersJSON.south west) edge [vh path] (ParseParametricLine);

  %\node[box] (root) at (0,-4) {root};
  %\foreach \name in {aa,bb,cc,dd}
  %   \node[box] (\name) at ++(0,-1) {\name};
\end{tikzpicture} 

在此处输入图片描述

答案2

如果我正确理解了你的问题,你可以above of=按以下方式使用密钥:

根

\documentclass{report}
\usepackage{tikz}
\usetikzlibrary{arrows,positioning}
\begin{document}

\begin{tikzpicture}[
box/.style={draw=black},
vh path/.style={to path={|- (\tikztotarget)}}
                   ]

  \node[box] (root) at (0,-4) {root};
  \foreach \name [remember= \name as \n (initially root)]in {aa,bb,cc,dd}
     \node[box, above=of \n] (\name) {\name};
\end{tikzpicture} 


\end{document}

相关内容