TikZ 入门教程:节点(Node)与流程图

引言

实际工作中,我们更常见的需求是带文字标注的示意图、流程图、树形结构图等。这些都依赖 TikZ 中最核心的概念之一——节点(Node)


一、节点(Node)基础

1.1 什么是节点

节点是 TikZ 中可以承载文字或图形内容的对象,可以独立放置,也可以附着在路径上(比如线段的端点)。

最简单的节点:

\begin{tikzpicture}
  % node 命令:在坐标 (2,1) 放一个文字节点
  \node at (2,1) {Hello, TikZ!};
\end{tikzpicture}

也可以在 \draw 路径上附着节点:

\begin{tikzpicture}
  \draw[->] (0,0) -- (3,0) node[right] {终点};
  \draw[->] (0,0) -- (0,2) node[above] {方向};
\end{tikzpicture}

节点位置关键字(相对于附着点):abovebelowleftrightabove leftabove rightbelow leftbelow right,还可以加偏移如 above=5pt

1.2 带边框的节点

给节点加上 draw 选项,就会出现边框:

\begin{tikzpicture}
  % 默认是矩形边框
  \node[draw] at (0,0) {普通节点};

  % 圆角矩形(需要 shapes 库)
  \node[draw, rounded corners] at (3,0) {圆角节点};

  % 圆形节点
  \node[draw, circle] at (6,0) {圆形};

  % 椭圆节点
  \node[draw, ellipse] at (9,0) {椭圆};
\end{tikzpicture}

1.3 节点的内边距与最小尺寸

\begin{tikzpicture}
  % inner sep 控制文字与边框的距离
  \node[draw, inner sep=10pt] at (0,0) {大内边距};

  % minimum width / minimum height 设置最小尺寸
  \node[draw, minimum width=3cm, minimum height=1cm]
    at (4,0) {固定最小尺寸};

  % minimum size 同时设置宽高(常用于圆形节点)
  \node[draw, circle, minimum size=1.5cm] at (8,0) {大圆};
\end{tikzpicture}

1.4 节点的填充与文字颜色

\begin{tikzpicture}
  \node[draw=blue, fill=blue!20, text=blue!70!black,
        rounded corners, thick, inner sep=8pt]
    at (0,0) {蓝色主题节点};

  \node[draw=red!80, fill=red!10, font=\bfseries,
        minimum width=2.5cm]
    at (5,0) {\textbf{加粗红色}};
\end{tikzpicture}

二、节点命名与引用

2.1 给节点命名

节点可以命名,之后可以用名字引用它的位置:

\begin{tikzpicture}
  % 在 \node 后用圆括号指定名字
  \node[draw] (A) at (0,0) {节点 A};
  \node[draw] (B) at (4,0) {节点 B};
  \node[draw] (C) at (2,2) {节点 C};

  % 用节点名称连线(自动连接到节点边框)
  \draw[->] (A) -- (B);
  \draw[->] (A) -- (C);
  \draw[->] (B) -- (C);
\end{tikzpicture}

2.2 节点的锚点(Anchor)

每个节点有多个锚点,用于精确指定连线的起止位置:

        north
         |
west -- center -- east
         |
        south

完整锚点:northsoutheastwestnorth eastnorth westsouth eastsouth westcenter,以及 base(文字基线)。

\begin{tikzpicture}
  \node[draw, minimum width=2.5cm, minimum height=1.5cm]
    (box) at (0,0) {盒子};

  % 用锚点作为连线起点
  \draw[->] (box.north) -- (0, 2)   node[above] {向上};
  \draw[->] (box.east)  -- (2, 0)   node[right] {向右};
  \draw[->] (box.south) -- (0,-2)   node[below] {向下};
  \draw[->] (box.west)  -- (-2, 0)  node[left]  {向左};
\end{tikzpicture}

三、样式(Styles)复用

当多个节点有相同样式时,可以用 \tikzset 或行内选项定义可复用的样式名:

\begin{tikzpicture}[
  % 在 tikzpicture 选项中定义样式
  process/.style={
    draw=blue!70, fill=blue!15,
    rectangle, rounded corners,
    minimum width=3cm, minimum height=0.9cm,
    font=\small
  },
  decision/.style={
    draw=orange!80, fill=orange!15,
    diamond, aspect=2.5,
    minimum width=3cm, minimum height=0.9cm,
    font=\small
  },
  startstop/.style={
    draw=green!60!black, fill=green!20,
    rectangle, rounded corners=0.5cm,
    minimum width=2.5cm, minimum height=0.9cm,
    font=\small\bfseries
  }
]
  \node[startstop] (start) at (0,0)   {开始};
  \node[process]   (p1)    at (0,-2)  {处理步骤 1};
  \node[decision]  (d1)    at (0,-4)  {条件判断?};
  \node[process]   (p2)    at (3,-4)  {处理步骤 2};
  \node[startstop] (end)   at (0,-6)  {结束};

  \draw[->] (start) -- (p1);
  \draw[->] (p1)    -- (d1);
  \draw[->] (d1)    -- node[above] {是} (p2);
  \draw[->] (d1)    -- node[right] {否} (end);
  \draw[->] (p2)    |- (end);   % |- 表示先垂直后水平
\end{tikzpicture}

四、连线样式

4.1 直线、折线与曲线

\begin{tikzpicture}
  \node[draw] (A) at (0,2)  {A};
  \node[draw] (B) at (4,2)  {B};
  \node[draw] (C) at (0,0)  {C};
  \node[draw] (D) at (4,0)  {D};

  % 直线连接
  \draw[->] (A) -- (B);

  % 直角折线(先水平后垂直)
  \draw[->] (A) -| (D);

  % 直角折线(先垂直后水平)
  \draw[->] (C) |- (B);

  % 曲线(to 命令 + bend 选项)
  \draw[->, bend left=30]  (A) to (D);
  \draw[->, bend right=20] (C) to (B);
\end{tikzpicture}

4.2 带标签的连线

\begin{tikzpicture}
  \node[draw, circle] (S) at (0,0)  {S};
  \node[draw, circle] (T) at (5,0)  {T};

  % 在线段中点上方放标签
  \draw[->] (S) -- node[above] {路径标签} (T);

  % 在线段中点下方放标签
  \draw[->, dashed, red] (S)
    .. controls (2.5,2) ..
    node[above, midway] {曲线标签} (T);
\end{tikzpicture}

4.3 箭头样式库

引入 arrows.meta 库可以使用更多箭头样式:

\usetikzlibrary{arrows.meta}  % 导言区

\begin{tikzpicture}
  \draw[-Stealth]           (0,4) -- (4,4) node[right] {Stealth};
  \draw[-Triangle]          (0,3) -- (4,3) node[right] {Triangle};
  \draw[-{Latex[width=8pt]}](0,2) -- (4,2) node[right] {Latex};
  \draw[{Bar}-{Bar}]        (0,1) -- (4,1) node[right] {Bar(双横线)};
  \draw[-open triangle 45]  (0,0) -- (4,0) node[right] {open triangle};
\end{tikzpicture}

五、流程图实战

下面用一个完整的流程图示例把本篇知识串联起来。以"用户登录流程"为例:

\usetikzlibrary{shapes.geometric, arrows.meta, positioning}

\begin{tikzpicture}[
  node distance=1.5cm,          % 节点间默认距离
  >=Stealth,                     % 全局箭头样式
  % 自定义样式
  startstop/.style={
    rounded rectangle,
    draw=teal, fill=teal!15,
    minimum width=2.8cm, minimum height=0.8cm,
    font=\small\bfseries
  },
  process/.style={
    rectangle,
    draw=blue!70, fill=blue!10,
    minimum width=3.2cm, minimum height=0.8cm,
    font=\small
  },
  decision/.style={
    diamond, aspect=2.8,
    draw=orange!80, fill=orange!10,
    minimum width=3.2cm, minimum height=0.8cm,
    font=\small
  },
  io/.style={
    trapezium,
    trapezium left angle=70, trapezium right angle=110,
    draw=purple!70, fill=purple!10,
    minimum width=3cm, minimum height=0.8cm,
    font=\small
  }
]

  % 节点定义(使用 positioning 库的相对定位)
  \node[startstop] (start)   {开始};
  \node[io,    below=of start]  (input)  {输入用户名和密码};
  \node[process,below=of input] (check)  {查询数据库};
  \node[decision,below=of check](valid)  {账号存在?};
  \node[process, below=of valid](pwdchk) {验证密码};
  \node[decision,below=of pwdchk](match) {密码正确?};
  \node[process, below=of match](login)  {登录成功,跳转主页};
  \node[startstop,below=of login](end)   {结束};

  % 右侧错误处理节点
  \node[process, right=2.5cm of valid]  (nouser) {提示:账号不存在};
  \node[process, right=2.5cm of match]  (nopwd)  {提示:密码错误};

  % 连线
  \draw[->] (start)   -- (input);
  \draw[->] (input)   -- (check);
  \draw[->] (check)   -- (valid);
  \draw[->] (valid)   -- node[left]  {是} (pwdchk);
  \draw[->] (valid)   -- node[above] {否} (nouser);
  \draw[->] (pwdchk)  -- (match);
  \draw[->] (match)   -- node[left]  {是} (login);
  \draw[->] (match)   -- node[above] {否} (nopwd);
  \draw[->] (login)   -- (end);

  % 错误节点返回输入
  \draw[->] (nouser.north) -- ++(0,0.5) -| (input.east);
  \draw[->] (nopwd.north)  -- ++(0,0.5) -| (input.east);

\end{tikzpicture}

六、\foreach 循环

\foreach 是绘制重复元素的利器,避免手写大量重复代码:

6.1 基本用法

\begin{tikzpicture}
  % 画 5 个间距为 1cm 的圆
  \foreach \x in {0,1,2,3,4} {
    \draw (\x, 0) circle (0.4);
  }

  % 同时遍历两个变量(用 / 分隔配对)
  \foreach \x/\label in {0/A, 1/B, 2/C, 3/D} {
    \node[draw, circle] at (\x*1.5, 2) {\label};
  }
\end{tikzpicture}

6.2 绘制正多边形

\begin{tikzpicture}
  % 画正六边形的顶点并连线
  \foreach \i in {0,...,5} {
    \coordinate (P\i) at (\i*60:2);
  }
  \draw (P0) -- (P1) -- (P2) -- (P3) -- (P4) -- (P5) -- cycle;

  % 在每个顶点放圆形节点
  \foreach \i in {0,...,5} {
    \fill[blue] (P\i) circle (3pt);
    \node[above right] at (P\i) {$P_{\i}$};
  }
\end{tikzpicture}

6.3 步进循环(使用范围语法)

\begin{tikzpicture}
  % 每隔 0.5 单位画一条竖线
  \foreach \x in {0, 0.5, ..., 4} {
    \draw[gray!50] (\x, 0) -- (\x, 3);
  }
  % 每隔 0.5 单位画一条横线
  \foreach \y in {0, 0.5, ..., 3} {
    \draw[gray!50] (0, \y) -- (4, \y);
  }
\end{tikzpicture}

七、树形图(Tree)

TikZ 内置了对树形结构的支持,使用 child 关键字:

\begin{tikzpicture}[
  level distance=1.5cm,
  sibling distance=3cm,
  every node/.style={draw, rounded corners, fill=blue!10,
                     minimum width=1.6cm, minimum height=0.7cm,
                     font=\small},
  edge from parent/.style={draw, ->}
]
  \node {根节点}
    child { node {左子节点}
      child { node {叶 A} }
      child { node {叶 B} }
    }
    child { node {中子节点}
      child { node {叶 C} }
    }
    child { node {右子节点}
      child { node {叶 D} }
      child { node {叶 E} }
      child { node {叶 F} }
    };
\end{tikzpicture}

八、矩阵节点(Matrix)

matrix 库可以方便地排列多个节点,类似表格布局:

\usetikzlibrary{matrix}

\begin{tikzpicture}
  \matrix[
    matrix of nodes,
    nodes={draw, minimum size=1cm, anchor=center},
    column sep=3pt,
    row sep=3pt
  ] {
    1 & 2 & 3 \\
    4 & 5 & 6 \\
    7 & 8 & 9 \\
  };
\end{tikzpicture}

九、综合示例:神经网络示意图

\usetikzlibrary{positioning}

\begin{tikzpicture}[
  >=Stealth,
  neuron/.style={
    circle, draw=blue!70, fill=blue!15,
    minimum size=0.9cm, font=\tiny
  },
  layer label/.style={font=\small\bfseries, text=gray}
]
  % 输入层(3 个神经元)
  \foreach \i in {1,2,3} {
    \node[neuron] (I\i) at (0, -\i*1.5) {$x_{\i}$};
  }

  % 隐藏层(4 个神经元)
  \foreach \j in {1,2,3,4} {
    \node[neuron, fill=orange!20, draw=orange!70]
      (H\j) at (3, {-\j*1.5+0.75}) {$h_{\j}$};
  }

  % 输出层(2 个神经元)
  \foreach \k in {1,2} {
    \node[neuron, fill=green!20, draw=green!70]
      (O\k) at (6, {-\k*1.5-0.75}) {$y_{\k}$};
  }

  % 输入层 → 隐藏层(全连接)
  \foreach \i in {1,2,3}
    \foreach \j in {1,2,3,4}
      \draw[->, gray!50, thin] (I\i) -- (H\j);

  % 隐藏层 → 输出层(全连接)
  \foreach \j in {1,2,3,4}
    \foreach \k in {1,2}
      \draw[->, gray!50, thin] (H\j) -- (O\k);

  % 层标签
  \node[layer label] at (0, 1.2)   {输入层};
  \node[layer label] at (3, 1.2)   {隐藏层};
  \node[layer label] at (6, 1.2)   {输出层};
\end{tikzpicture}

posted @ 2026-06-05 10:58  江鸟Dev  阅读(14)  评论(0)    收藏  举报