TikZ:支撑节点

TikZ:支撑节点

所以我想在 tikzpicture 的一部分周围放置一个水平支架。

我发现了替代方法,但似乎在这里不太适用:

在这两种情况下,最右边(最左边)位置已经有一个节点,从而可以通过或等效方法轻松计算括号端点-|

但并不总是存在这样的节点;例如,当尝试放置树的一部分的括号时(参见 MWE)。我隐约知道,从技术上讲,我可能可以在自定义代码中使用calc和计算最小/最大值x,但我希望有一种我不知道的更简单的方法。

\documentclass[tikz]{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations.pathreplacing,positioning}
\begin{document}
\tikzstyle{edge} =[draw,thick,-latex]
\begin{tikzpicture}[node distance=0.8cm]
% Root trunk
\node (a1) at (0,0) {Sometimes};
\node[below=of a1] (a2) {One};
\path[edge] (a1) -- (a2);
\node[below=of a2] (a99) {Thing};
\path[edge] (a2) -- (a99);
% Right leaf
\node[below right=0.8cm and 0.5cm of a99] (r1) {Goes};
\path[edge] (a99) -- (r1);
\node[below=of r1] (r2) {On};
\path[edge] (r1) -- (r2);
\node[below=of r2] (r3) {And};
\path[edge] (r2) -- (r3);
\node[below=of r3,rectangle,draw] (r99) {On};
\path[edge] (r3) -- (r99);
% Left leaf
\node[below left=0.8cm and 0.5cm of a99] (l1) {Leads};
\path[edge] (a99) -- (l1);
\node[below=of l1,align=center] (l2) {In wide, verbose, even \\ multi-lined ways};
\path[edge] (l1) -- (l2);
\node[below=of l2,rectangle,draw] (l99) {To another};
\path[edge] (l2) -- (l99);
% Mapping to (sub)sections
\draw[decorate,decoration={brace,amplitude=10pt,mirror}]
(a1.north west) -- (a99.south west) node [midway,xshift=-0.4cm,left] {Section foo};
\draw[decorate,decoration={brace,amplitude=10pt,mirror}]
(l1.north west) -- (l99.south west) node [midway,xshift=-0.4cm,left] {Section bar};
\draw[decorate,decoration={brace,amplitude=10pt}]
(r1.north east) -- (r99.south east) node [midway,xshift=0.4cm,right] {Section baz};
\end{tikzpicture}
\end{document}

渲染的 MWE

我希望牙套的位置更加合理,具体来说:

  • 不要离叶子的矩形太近,要离得远一些。
  • 通过移开整个支架,不会与宽的“内部”节点相交。
  • 支架应垂直,但轻微地倾斜的看起来也不错。

-|这是通过手动选择和计算出的括号端点的样子|-

带有完全垂直括号的正面示例

那么,如何在不进行手动操作的情况下将垂直支架放置在合适的位置?或者更具体地说,假设这是一个好主意:如何获取节点子集的极角(例如最右边和最上面)?

(另外:非常欢迎对我的 TeX 和帖子风格的一般建议和推荐!)

答案1

我会使用专为绘制树而设计的软件包或库之一。Forest 是我的最爱,因为它意味着您不必手动确定定位:该软件包会自动计算出为节点留出多少空间并相应地放置它们。它也非常强大和灵活,允许大量定制和自动化,并且具有非常简洁的树规范。

这是使用 的版本fit to。为了指定curl的跨度,我们传递节点 walk 作为参数。标签进入curl labelmirror curl触发镜像。

\documentclass[border=10pt]{standalone}
\usepackage{forest}
\usetikzlibrary{decorations.pathreplacing,arrows.meta}
\begin{document}
\forestset{
  declare toks={curl label}{},
  declare toks={curl mirror}{},
  mirror curl/.style={curl mirror=mirror},
  curl/.style n args=5{
    tikz+={
      \node (n) [fit to=#1, inner sep=0pt] {};
      \draw [decorate, decoration={brace, amplitude=10pt, #3}] (n.north #2) -- (n.south #2) node [midway, #4] {#5};
    }
  },
  curl left/.style={
    delay={
      curl/.process={OOw2 {curl label}{curl mirror}{ {#1}{west}{##2}{left, xshift=-10pt}{##1}}  }
    },
  },
  curl right/.style={
    delay={
      curl/.process={OOw2 {curl label}{curl mirror}{ {#1}{east}{##2}{right, xshift=10pt}{##1}}  }
    },
  },
}
\begin{forest}
  for tree={
    edge+={-Latex,thick},
    align=center,
  },
  where n children=0{draw}{},
  [Sometimes
    [One
      [Thing, curl left=cur, curl label=Section foo, mirror curl
        [Leads, curl left=tree, curl label=Section bar, mirror curl
          [{In wide, verbose, even\\multi-lined ways}
            [To Another]
          ]
        ]
        [Goes, curl right=tree, curl label=Section baz
          [On
            [And
              [On]
            ]
          ]
        ]
      ]
    ]
  ]
\end{forest}
\end{document}

森林解决方案

或者您可以指定跨度的起点和终点坐标:

\documentclass[border=10pt]{standalone}
\usepackage{forest}
\usetikzlibrary{decorations.pathreplacing,arrows.meta}
\begin{document}
\forestset{
  declare toks={curl label}{},
  declare toks={curl mirror}{},
  mirror curl/.style={curl mirror=mirror},
  curl/.style n args=5{
    tikz+={
      \draw [decorate, decoration={brace, amplitude=10pt, #3}] #1 -- #2 node [midway, #4] {#5};
    }
  },
  curl left/.style args={from #1 to #2}{
    delay={
      curl/.process={OOw2 {curl label}{curl mirror}{ {#1}{#2}{##2}{left, xshift=-10pt}{##1}}  }
    },
  },
  curl right/.style args={from #1 to #2}{
    delay={
      curl/.process={OOw2 {curl label}{curl mirror}{ {#1}{#2}{##2}{right, xshift=10pt}{##1}}  }
    },
  },
}
\begin{forest}
  for tree={
    edge+={-Latex,thick},
    align=center,
  },
  where n children=0{draw}{},
  [Sometimes
    [One
      [Thing, curl left=from (.south -| !r.west) to (!r.north west), curl label=Section foo
        [Leads
          [{In wide, verbose, even\\multi-lined ways}, curl left=from (!u.north -| .west) to (!1.south -| .west), curl label=Section bar, mirror curl
            [To Another]
          ]
        ]
        [Goes, curl right=from (.north east) to (.east |- !F.south), curl label=Section baz
          [On
            [And
              [On]
            ]
          ]
        ]
      ]
    ]
  ]
\end{forest}    
\end{document}

请注意,( -| )坐标规范也可以用于您的原始代码。这是一种确保花括号按您希望的方式对齐的简单方法。

如果您有一个节点子集,,,,a那么将给出一个足够大的b紧密盒子的左上角以包含它们,将给出右下角等等。c(<widest node>.west |- <topmost node>.north)(<widest node>.east |- <bottommost node>.south)

相关内容