我正在努力此图使用 TikZ,但我没能画出弯曲的箭头(参见我在注释行中尝试的操作)。如何在两个笛卡尔坐标之间画一条弧?如何将整个图表放入一个矩形中?我所做的没有奏效……
我想要这样的东西:
\draw [->, radius=r] (x1,y1) arc (x2,y2);
我尝试了评论中给出的解决方案,但并不满意。
平均能量损失
\documentclass[border=10pt]{standalone}
%\usepackage[margin=1cm]{geometry}
\usepackage{tikz,xcolor}
\usepackage{hyperref}
\usepackage{tkz-euclide}
\usetkzobj{all}
\usetikzlibrary{shapes.geometric,arrows,positioning,fit,calc,}
\tikzset{
b/.style={draw, rectangle, rounded corners=2ex,minimum height=0.5in, minimum width=2in,align=center},
c/.style={draw, rectangle, rounded corners=2ex, minimum height=0.5in, minimum width=2in,align=center, rotate=-90},
ar/.style={rounded corners=2ex,->,>=latex },
myarrow/.style args={#1 colored by #2 and #3}{
-stealth,line width=#1,#2,postaction={draw,-stealth,#3,line width=(#1)/3,
shorten <=(#1)/3,shorten >=2*(#1)/3},
}
}
\makeatletter
\newcommand{\gettikzxy}[3]{%
\tikz@scan@one@point\pgfutil@firstofone#1\relax
\edef#2{\the\pgf@x}%
\edef#3{\the\pgf@y}%
}
\makeatother
\begin{document}
\begin{tikzpicture}
\node (client) [b] {Client};
\node (serveur) [b, left=4 cm of client.west] {Serveur};
\gettikzxy{(client)}{\axc}{\ayc}
\draw[thick] (client.south) -- (\axc, \ayc - 300);
\gettikzxy{(serveur)}{\axs}{\ays}
\draw[thick] (serveur.south) -- (\axs, \ays - 300);
\draw [ar] (\axc, \ayc - 100) -- node[above]{\parbox[t]{5cm}{\centering POST \nolinkurl{authentification/}\\username=user\&password=abc123}} (\axs, \ays -100);
\draw [ar] (\axs, \ays - 150) -- node[above]{\parbox[t]{5cm}{\centering HTTP 200 OK\\ \color{green}{\{Token : "JWT"\}}}} (\axc, \ayc -150);
\draw [ar] (\axc, \ayc - 200) -- node[above]{\parbox[t]{5cm}{\centering GET \nolinkurl{api/user/id}\\ \color{green}{JWT : Token} }} (\axs, \ays -200);
\draw [ar] (\axc, \ayc - 250) -- node[below]{\parbox[t]{5cm}{\centering HTTP 200 OK\\ \color{green}{\{name : foo\} }}} (\axs, \ays -250);
%\draw[->] (\axs,\ays - 200) arc (-120:30:5) ;
% Draw the arc which center is (2,1)
%\draw[thick,red] ([shift=(90:1cm)]\axs,\ays-175) arc (90:360:0.9cm);
% \draw [->] (\axs,\ays-150) arc (\axs,\ays-200,2.1);
%\draw [<->] (0:2.1) arc (0:60:2.1);
%\draw [->,line width=5pt] (\axs:-200) arc (\axs:-300);
%\draw [ar] ([yshift=0.5cm]serveur.south) -- node[above]{
% \parbox[t]{5cm}{POST authentification/\\username=...\&password=..}} ([yshift=0.5cm]client.south);
%\draw [ar] ([yshift=-0.5cm]client.south) -- ([yshift=-0.5cm]serveur.north);
\node [rectangle, opacity=0.2, fill=blue, fit=(client)(serveur),]{};
\draw[->, thick] (\axs-3,\ays-150) to[bend left=250] (\axs-3,\ays-200);
\end{tikzpicture}
\end{document}
答案1
好吧,这是一个建议。它使用了在 TikZ 中绘制由三点定义的圆弧的最简单方法是什么?绘制圆弧。第三个坐标位于两点中间,稍微向左偏移,用作圆弧的中点。修改此偏移会改变圆的半径,尽管偏移当然与半径不同。
我还更改了所有线条和箭头的绘制方式。至于您是否认为这是一种改进,我将留给您自己决定。请注意,您可以为节点定义text width
和align
,因此无需\parbox
在每个节点中添加 。查看新toptext
样式。
关于背景填充:该fit
库允许您创建一个包含其他节点列表的节点。当您仅将两个顶部节点添加到此列表时,它当然不会覆盖整个图形。我所做的是bottom
在其中一条垂直线的末尾添加一个新节点,并将其添加到fit=
节点列表中。(您也可以使用节点的锚点current bounding box
。)使用backgrounds
库,我将填充放在背景上,因此它不会覆盖其他元素。
最后说明:\color{green}
是一个开关,它使后面的所有文本都变成绿色。因此, 中的最后一对括号 \color{green}{text}
不是必需的,它们不会限制 的效果\color
。但是有一个\textcolor
命令确实使用了这种语法,\textcolor{green}{green text}
。(比较\textcolor{red}{red text} black text \color{red}{red text} still red text
。)
\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\usepackage{tkz-euclide}
\usetkzobj{all}
\usetikzlibrary{shapes.geometric,arrows,positioning,fit,calc,backgrounds}
\usepackage{hyperref}
\tikzset{
b/.style={
draw,
rectangle,
rounded corners=2ex,
minimum height=0.5in,
minimum width=2in,
align=center},
c/.style={
draw,
rectangle,
rounded corners=2ex,
minimum height=0.5in,
minimum width=2in,
align=center,
rotate=-90},
ar/.style={
rounded corners=2ex,
->,
>=latex},
myarrow/.style args={#1 colored by #2 and #3}{
-stealth,
line width=#1,
#2,
postaction={draw,-stealth,#3,line width=(#1)/3,
shorten <=(#1)/3,
shorten >=2*(#1)/3},
},
toptext/.style={ % <-- New
above,
text width=5cm,
align=center}
}
\begin{document}
\begin{tikzpicture}
\node (client) [b] {Client};
\node (serveur) [b, left=4 cm of client.west] {Serveur};
% draw the vertical lines
\draw [thick] (serveur.south) -- ++(0,-300pt);
\draw (client.south) -- ++(0,-300pt) coordinate (bottom);
% add a coordinate below serveur for given y-offsets from bottom of serveur
\foreach [count=\i] \y in {-100,-150,-200,-250}
\path (serveur.south) ++(0,\y pt) coordinate (level \i);
\draw [ar] (level 1 -| client.south) -- node[toptext] {POST \nolinkurl{authentification/}\\username=user\&password=abc123} (level 1);
\draw [ar] (level 2) -- node[toptext] {HTTP 200 OK\\ \textcolor{green}{\{Token : "JWT"\}}} (level 2-| client.south);
\draw [ar] (level 3 -| client.south) -- node[toptext] {GET \nolinkurl{api/user/id}\\ \textcolor{green}{JWT : Token}} (level 3);
\draw [ar] (level 4 -| client.south) -- node[toptext,below] {HTTP 200 OK\\ \textcolor{green}{\{name : foo\}}} (level 4);
% define some coordinates
\coordinate (a) at ($(level 2) + (-3pt,0)$);
\coordinate (b) at ($(level 3) + (-3pt,0)$);
\coordinate (c) at ($(a)!0.5!(b) + (-1cm,0)$); % modify the -1cm offset here
% Just to show the points used
\foreach \x in {a,b,c}
\fill[red] (\x) circle[radius=2pt];
% Draw the arc through the points
\tkzCircumCenter(a,b,c)\tkzGetPoint{O}
\tikzset{compass style/.append style={-latex,thick,black}}
\tkzDrawArc(O,a)(b)
% fill background
\begin{scope}[on background layer]
\node [rectangle, opacity=0.2, fill=blue, fit=(client)(serveur)(bottom)]{};
\end{scope}
\end{tikzpicture}
\end{document}