我正在尝试使用 Tikz 重现以下图表:
以下是我目前获得的结果:
使用以下代码:
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{graphicx}
\usepackage{float}
\usepackage{amsmath}
\usepackage{amsthm}
\usepackage{tikz}
\usetikzlibrary{chains,shapes.multipart}
\usetikzlibrary{shapes, fit}
\usetikzlibrary{automata,positioning}
\tikzset{
activity/.style={
draw,
rectangle,
minimum height = 0.8cm,
minimum width = 1.5cm
},
}
\begin{document}
\begin{tikzpicture}
% Outer parallelogram (TaskA)
\draw (0,0) -- (-100:6cm) --++ (0:6cm) --++ (80:6cm) -- (0,0);
\node at (5,-0.5) {TaskA};
% Inner parallelogram (EntryA)
\draw (1.5,0) --++ (-100:1cm) --++ (0:2cm) --++ (80:1cm);
\node at (2.3,-0.5) {EntryA};
% Activities
\node[activity] (s) at (2.3,-2) {source};
\node[circle, draw] (plus) at (2.3, -3.5) {+};
\node[activity] (c1) at (1, -5) {choice1};
\node[activity] (c2) at (3.6, -5) {choice2};
\draw [->] (2.3,-1) -- (s.north);
\draw [->] (s.south) -- (plus.north);
\draw [->] (plus.south east) -- (c2.north);
\draw [->] (plus.south west) -- (c1.north);
% TaskB
\draw (0,-8) --++ (-100:2cm) --++ (0:6cm) --++ (80:2cm) -- (0,-8);
\node at (2.8,-9.5) {TaskB};
% EntryB1
\draw (0.5,-8) --++ (-100:1cm) --++ (0:2cm) --++ (80:1cm);
\node (eB1) at (1.3,-8.5) {EntryB1};
% EntryB2
\draw (3.5,-8) --++ (-100:1cm) --++ (0:2cm) --++ (80:1cm);
\node (eB2) at (4.3,-8.5) {EntryB2};
\node[circle,draw] (pA) at (8, -5) {ProcA};
\node[circle,draw] (pB) at (8, -10) {ProcB};
\draw [->] (c1.south) -- (eB1.north);
\draw [->] (c2.south) -- (eB2.north);
\end{tikzpicture}
\end{document}
- 我如何对齐底部箭头,使它们分别指向 EntryB1 和 EntryB2 的中心?
- 如何添加从外平行四边形指向圆“ProcA”和“ProcB”的两个箭头?
- 如何在图中心的箭头上添加上标“0.5”?
答案1
至于带有文字的箭头0.5
,可以通过node {$0.5$}
在路径内添加来实现。它看起来像这样
\draw [->] (plus.south east) -- node[anchor=south west]{$0.5$} (c2.north);
另外两个要点可以通过两种方式解决:
无需对您的确切代码进行任何具体更改,通过添加
local bounding box
到外部平行四边形,您可以随后调用它并将其视为节点。\documentclass{article} \usepackage[utf8]{inputenc} \usepackage{graphicx} \usepackage{float} \usepackage{amsmath} \usepackage{amsthm} \usepackage{tikz} \usetikzlibrary{chains,shapes.multipart} \usetikzlibrary{shapes, fit} \usetikzlibrary{automata,positioning} \usetikzlibrary{intersections} \tikzset{ activity/.style={ draw, rectangle, minimum height = 0.8cm, minimum width = 1.5cm }, } \begin{document} \begin{tikzpicture} % Outer parallelogram (TaskA) \draw[local bounding box=pOA] (0,0) -- (-100:6cm) --++ (0:6cm) --++ (80:6cm) -- (0,0); \node at (5,-0.5) {TaskA}; % Inner parallelogram (EntryA) \draw (1.5,0) --++ (-100:1cm) --++ (0:2cm) --++ (80:1cm); \node at (2.3,-0.5) {EntryA}; % Activities \node[activity] (s) at (2.3,-2) {source}; \node[circle, draw] (plus) at (2.3, -3.5) {+}; \node[activity] (c1) at (1, -5) {choice1}; \node[activity] (c2) at (3.6, -5) {choice2}; \draw [->] (2.3,-1) -- (s.north); \draw [->] (s.south) -- (plus.north); \draw [->] (plus.south east) -- node[anchor=south west]{$0.5$} (c2.north); \draw [->] (plus.south west) -- node[anchor=south east]{$0.5$} (c1.north); % TaskB \draw[local bounding box=pOB] (0,-8) --++ (-100:2cm) --++ (0:6cm) --++ (80:2cm) -- (0,-8); \node at (2.8,-9.5) {TaskB}; % EntryB1 \draw[local bounding box=e1] (0.5,-8) --++ (-100:1cm) --++ (0:2cm) --++ (80:1cm); \node (eB1) at (1.3,-8.5) {EntryB1}; % EntryB2 \draw[local bounding box=e2] (3.5,-8) --++ (-100:1cm) --++ (0:2cm) --++ (80:1cm); \node (eB2) at (4.3,-8.5) {EntryB2}; \node[circle,draw] (pA) at (8, -5) {ProcA}; \node[circle,draw] (pB) at (8, -10) {ProcB}; \draw [->] (c1.south) -- (e1.north); \draw [->] (c2.south) -- (e2.north); \draw [->, shorten <= -18pt] (pOA.east) -- (pA); \draw [->, shorten <= -5pt] (pOB.east) -- (pB); \end{tikzpicture} \end{document}
但是,
local bounding box
会创建一个矩形框,因此,为了使箭头指向外部平行四边形,您需要使用shorten <=
并目测长度以使其看起来像实际连接我个人建议的第二种方法不存在目测问题。它使用
shapes
库以及fit
一个库。它们显然都已加载。这样,您不再需要使用路径创建平行四边形,而是使用节点形状。这样,您可以像平常一样简单地绘制箭头,它们将像应该的那样连接起来。\documentclass{article} \usepackage[utf8]{inputenc} \usepackage{graphicx} \usepackage{float} \usepackage{amsmath} \usepackage{amsthm} \usepackage{tikz} \usetikzlibrary{chains,shapes.multipart} \usetikzlibrary{shapes, fit} \usetikzlibrary{automata,positioning} \begin{document} \begin{tikzpicture}[ every node/.style={draw, inner sep=8pt}, parallelogram/.style={draw, trapezium, trapezium left angle=80, trapezium right angle=-80} ] % Outer parallelogram (TaskA) \node[draw=none] (tA) at (5,-0.5) {TaskA}; \node[parallelogram] (eA) at (2.3,-0.5) {EntryA}; % Activities \node (s) at (2.3,-2) {source}; \node[circle] (plus) at (2.3, -3.5) {+}; \node (c1) at (1, -5) {choice1}; \node (c2) at (3.6, -5) {choice2}; \draw [->] (eA) -- (s.north); \draw [->] (s.south) -- (plus.north); \draw [->] (plus.south east) -- node[draw=none, inner sep=1pt, anchor=south west]{$0.5$} (c2.north); \draw [->] (plus.south west) -- node[draw=none, inner sep=1pt, anchor=south east]{$0.5$} (c1.north); % TaskB \node[draw=none] (tB) at (2.8,-9.5) {TaskB}; % EntryB1 \node[parallelogram] (eB1) at (1.3,-8.5) {EntryB1}; % EntryB2 \node[parallelogram] (eB2) at (4.3,-8.5) {EntryB2}; \node[circle, inner sep=2pt] (pA) at (8, -5) {ProcA}; \node[circle, inner sep=2pt] (pB) at (8, -10) {ProcB}; \draw[->] (c1.south) -- (eB1.north); \draw[->] (c2.south) -- (eB2.north); \node[parallelogram, xshift=10pt, fit=(eA) (c1) (c2)] (pOA) {}; \node[parallelogram, fit=(eB1) (eB2) (tB)] (pOB) {}; \draw[->] (pOA) -- (pA); \draw[->] (pOB) -- (pB); \end{tikzpicture} \end{document}
编辑:
关于评论中讨论的顶部对齐。
对于第二种方法,外平行四边形是使用
fit
tikz 库创建的节点,基本上会创建一个适合所有列出内容的节点。由于它是一个节点,因此可以通过inner sep
选项设置填充。但是,没有办法只控制一侧(左、右、上、下),因此为了实现该效果,您可以按填充量填充节点并获得所需的对齐方式。由于
innner sep
可以在您决定的任何时候更改,因此也必须修改移位。虽然有一种更通用的方法可以做到这一点,但使用\pgfkeysvalueof{/pgf/inner ysep}
它提取当前填充,以便移位将根据更改自动更新inner sep
\documentclass{article} \usepackage[utf8]{inputenc} \usepackage{graphicx} \usepackage{float} \usepackage{amsmath} \usepackage{amsthm} \usepackage{tikz} \usetikzlibrary{chains,shapes.multipart} \usetikzlibrary{shapes, fit} \usetikzlibrary{automata,positioning} \begin{document} \begin{tikzpicture}[ every node/.style={draw, inner sep=8pt}, parallelogram/.style={draw, trapezium, trapezium left angle=80, trapezium right angle=-80} ] % Outer parallelogram (TaskA) \node[draw=none] (tA) at (5,-0.5) {TaskA}; \node[parallelogram] (eA) at (2.3,-0.5) {EntryA}; % Activities \node (s) at (2.3,-2) {source}; \node[circle] (plus) at (2.3, -3.5) {+}; \node (c1) at (1, -5) {choice1}; \node (c2) at (3.6, -5) {choice2}; \draw [->] (eA) -- (s.north); \draw [->] (s.south) -- (plus.north); \draw [->] (plus.south east) -- node[draw=none, inner sep=1pt, anchor=south west]{$0.5$} (c2.north); \draw [->] (plus.south west) -- node[draw=none, inner sep=1pt, anchor=south east]{$0.5$} (c1.north); % TaskB \node[draw=none] (tB) at (2.8,-9.5) {TaskB}; % EntryB1 \node[parallelogram] (eB1) at (1.3,-8.5) {EntryB1}; % EntryB2 \node[parallelogram] (eB2) at (4.3,-8.5) {EntryB2}; \node[circle, inner sep=2pt] (pA) at (8, -5) {ProcA}; \node[circle, inner sep=2pt] (pB) at (8, -10) {ProcB}; \draw[->] (c1.south) -- (eB1.north); \draw[->] (c2.south) -- (eB2.north); \node[parallelogram, xshift=10pt, yshift=-\pgfkeysvalueof{/pgf/inner ysep}, fit=(eA) (c1) (c2)] (pOA) {}; \node[parallelogram, inner ysep=3pt, xshift=-3pt, yshift=-\pgfkeysvalueof{/pgf/inner ysep}, fit=(eB1) (eB2) (tB)] (pOB) {}; \draw[->] (pOA) -- (pA); \draw[->] (pOB) -- (pB); \end{tikzpicture} \end{document}