我有以下 Tikz 代码:
\usetikzlibrary{positioning}
\begin{tikzpicture}
\tikzstyle{bordered} = [draw,thick,inner sep=5,minimum size=10,minimum width=100,font=\sffamily]
\tikzstyle{arrow} = [thick,-latex,font=\sffamily]
\node [] (init) {};
\node [bordered,below=of init] (image) {App Image};
\node [bordered,below=of image] (running) {Running Container};
\node [bordered,below=of running] (stopped) {Persisted Container};
\draw [arrow] (init) -- (image) node [midway,right] {Install};
\draw [arrow] (image) -- (running) node [midway,right] {Start};
\draw [arrow] (running) -- (stopped) node [midway,right] {Terminate or Kill};
\draw [arrow] (stopped.west) -- (running.west) node [midway,left] {Start};
\draw [arrow] (stopped.west) -- (image.west) node [midway,left] {Reset};
\end{tikzpicture}
其结果是:
我希望最后两条边与它们的节点保持一定距离,并且成直角。以下是我想要的效果:
我可以通过在每个“真实”节点旁边添加不可见节点来实现这一点,但我认为一定有更好、更舒适的解决方案?
答案1
可能有多种方法可以解决此问题。此示例显示了我经常使用的方法。
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}
\tikzstyle{bordered} = [draw,thick,inner sep=5,minimum size=10,minimum width=100,font=\sffamily]
\tikzstyle{arrow} = [thick,-latex,font=\sffamily]
\node [] (init) {};
\node [bordered,below=of init] (image) {App Image};
\node [bordered,below=of image] (running) {Running Container};
\node [bordered,below=of running] (stopped) {Persisted Container};
\draw [arrow] (init) -- (image) node [midway,right] {Install};
\draw [arrow] (image) -- (running) node [midway,right] {Start};
\draw [arrow] (running) -- (stopped) node [midway,right] {Terminate or Kill};
\draw [arrow] ($(stopped.west)+(0,2pt)$) --
++(-1em,0) --
($(running.west)+(-1em,0)$)
node [midway,right] {Start} --
(running.west);
\draw [arrow] ($(stopped.west)+(0,-2pt)$) --
++(-2em,0) --
($(image.west)+(-2em,0)$)
node [midway,left] {Reset} --
(image.west) ;
\end{tikzpicture}
\end{document}
答案2
使用垂直语法(|-
或-|
)的更简单的变体:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}
\tikzstyle{bordered} = [draw,thick,inner sep=5,minimum size=10,minimum width=100,font=\sffamily]
\tikzstyle{arrow} = [thick,-latex,font=\sffamily]
\node [] (init) {};
\node [bordered,below=of init] (image) {App Image};
\node [bordered,below=of image] (running) {Running Container};
\node [bordered,below=of running] (stopped) {Persisted Container};
\draw [arrow] (init) -- (image) node [midway,right] {Install};
\draw [arrow] (image) -- (running) node [midway,right] {Start};
\draw [arrow] (running) -- (stopped) node [midway,right] {Terminate or Kill};
\draw [arrow]
(stopped.west) ++ (up:2pt)
-- ++(left:1em)
|- (running.west)
node[pos=0.25,right]{Start} ;
\draw [arrow]
(stopped.west) ++ (down:2pt)
-- ++(left:2em)
|- (image.west)
node[pos=0.25,left]{Reset};
\end{tikzpicture}
\end{document}
答案3
PSTricks 解决方案:
\documentclass{article}
\usepackage{pstricks}
\usepackage{xfp}
% parameters
\def\boxWidth{3.4}
\def\boxHeight{0.7}
\def\separation{1}
\def\arrow{0.4}
% simplifies notation
\def\constA#1#2{\fpeval{#1*\boxHeight+#2*\separation}}
\def\constB#1{\fpeval{1+#1*\arrow}}
\def\constC#1{\fpeval{\constB{2}+#1*\boxWidth}}
\begin{document}
\psset{arrows = ->}
\begin{pspicture}(\fpeval{1+2*\arrow+max(\boxWidth,\boxWidth/2+2.85)},
\fpeval{3*(\boxHeight+\separation)})
\psline(\constC{0.5},\constA{3}{3})(\constC{0.5},\constA{3}{2})
\uput[r](\constC{0.5},\constA{2.5}{3}){Install}
\psframe(\constB{2},\constA{2}{2})(\constC{1},\constA{3}{2})
\rput(\constC{0.5},\constA{2.5}{2}){App Image}
\psline(\constC{0.5},\constA{2}{2})(\constC{0.5},\constA{2}{1})
\uput[r](\constC{0.5},\constA{2}{1.5}){Start}
\psframe(\constB{2},\constA{1}{1})(\constC{1},\constA{2}{1})
\rput(\constC{0.5},\constA{1.5}{1}){Running Container}
\uput[r](\constC{0.5},\constA{1}{0.5}){Terminate or Kill}
\psline(\constC{0.5},\constA{1}{1})(\constC{0.5},\constA{1}{0})
\psframe(\constB{2},0)(\constC{1},\constA{1}{0})
\rput(\constC{0.5},\constA{0.5}{0}){Persisted Container}
\psline(\constB{2},\fpeval{1/3*\boxHeight})%
(1,\fpeval{1/3*\boxHeight})%
(1,\constA{2.5}{2})%
(\constB{2},\constA{2.5}{2})
\uput[l](1,\constA{1.5}{1}){Reset}
\psline(\constB{2},\fpeval{2/3*\boxHeight})%
(\constB{1},\fpeval{2/3*\boxHeight})%
(\constB{1},\constA{1.5}{1})%
(\constB{2},\constA{1.5}{1})
\uput[r](\constB{1},\constA{1}{0.5}){Start}
\end{pspicture}
\end{document}
您所要做的就是改变参数的值,绘图就会相应地调整。
答案4
很晚了...所以或多或少是为了锻炼;另一种紧凑的代码:
\documentclass[border=3mm,tikz]{standalone}
\usetikzlibrary{arrows.meta,chains,quotes}
\begin{document}
\begin{tikzpicture}[
auto,
font = \sffamily,
node distance = 12mm,
start chain = going below,
bordered/.style = {draw, thick,
minimum height=6mm, minimum width=33mm, text depth=0.25ex,
on chain},
arrow/.style = {thick,-{Latex[]}},
sy/.style = {yshift=#1 mm}
]
\coordinate[on chain] (init);
\node (image) [bordered] {App Image};
\node (running) [bordered] {Running Container};
\node (stopped) [bordered] {Persisted Container};
\path[arrow]
(init) edge["Install"] (image)
(image) edge["Start"] (running)
(running) edge["Terminate or Kill"] (stopped);
\draw[arrow] ([sy=+1] stopped.west) -- + (-0.5,0)
|- node[pos=0.25,swap] {Start} (running);
\draw[arrow] ([sy=-1] stopped.west) -- + (-0.7,0)
|- node[pos=0.25] {Reset} (image);
\end{tikzpicture}
\end{document}