我正在使用它pgf-umlsd
来绘制消息传递图。目前,它看起来像这样:
\documentclass{article}
\usepackage{float}
\usepackage{tikz}
\usetikzlibrary{positioning, fit, calc, shapes, arrows, arrows.new}
\usepackage[underline=false]{pgf-umlsd}
\begin{document}
\begin{figure}[H]
\centering
\begin{sequencediagram}
\newinst{c}{Client}
\newinst[6]{s}{Server}
\mess[1]{c}{A}{s}
\mess[1]{s}{B}{c}
\mess[1]{c}{A}{s}
\mess[1]{s}{B}{c}
\mess[1]{c}{...}{s}
\mess[1]{s}{...}{c}
\stepcounter{seqlevel}
\mess[1]{s}{C}{c}
\end{sequencediagram}
\caption{Client-Server messaging}
\end{figure}
\end{document}
我想知道如何根据我所拥有的内容执行以下操作:
在下面的线上添加垂直线
Server
来覆盖来箭和出箭之间的距离。在每个栏的右侧,添加文本注释来描述服务器在接收特定消息和发送另一条消息之间所执行的操作。
在消息正上方添加 3 个垂直点,
C
以表示在发送之前发生了A
更多消息交换。B
Server
C
我查看了的手册pgf-umlsd
,但没有找到任何此类绘图的示例。
答案1
您需要的一切都在pgf-umlsd.sty
代码中。接下来是\mess
在 v0.7 中声明。
% message between threads
% Example:
% \mess[delay]{sender}{message content}{receiver}
\newcommand{\mess}[4][0]{
\stepcounter{seqlevel}
\path
(#2)+(0,-\theseqlevel*\unitfactor-0.7*\unitfactor) node (mess from) {};
\addtocounter{seqlevel}{#1}
\path
(#4)+(0,-\theseqlevel*\unitfactor-0.7*\unitfactor) node (mess to) {};
\draw[->,>=angle 60] (mess from) -- (mess to) node[midway, above]
{#3};
\node (#3 from) at (mess from) {};
\node (#3 to) at (mess to) {};
}
此命令在两个线程(和)之间绘制一个箭头(可能带有标签(parameter #3
)和一定的延迟(optional parameter #1
)。最后,这对您有好处,它声明了消息起源和消息结尾处的节点。parameter #2
parameter #4
(#3 from)
(#3 to)
这意味着\mess[1]{c}{A}{s}
您可以使用节点A from
并A to
添加一些注释:
\node[left=0mm of A from] {First message};
\node[right=0mm of A to] {First message received};
请注意,如果您对两条或多条消息使用相同的注释/标签,则只有最后一条消息可以用节点引用。在您的示例中,所有注释都必须添加在消息之后。
可以使用相同的节点在消息到达和离开之间画一条线。
解决上一个问题的方法是借助前一个(C from)
和(C to)
节点来放置点。
完整代码如下
\documentclass[tikz,border=3mm]{standalone}
\usepackage{pgf-umlsd}
\usetikzlibrary{shadows,positioning}
\begin{document}
\begin{sequencediagram}
\newinst{c}{Client}
\newinst[6]{s}{Server}
\mess[1]{c}{A}{s}
\node[left=0mm of A from] {First message};
\node[right=0mm of A to] {First message received};
\mess[1]{s}{B}{c}
\node[right=0mm of B from] {Ack to First message};
\draw[line width=3pt] (A to) -- (B from);
\mess[1]{c}{A}{s}
\node[right=0mm of A to] {Something else happens here};
\mess[1]{s}{B}{c}
\mess[1]{c}{...}{s}
\mess[1]{s}{...}{c}
\stepcounter{seqlevel}
\mess[1]{s}{C}{c}
\path(C from) -- (C to) node[midway, above=1cm]
{\vdots};
\end{sequencediagram}
\end{document}
结果是
更新
如果您想更改通过添加的评论的字体(或任何其他参数)\node
,只需将其添加到节点选项中,即\node[right=0mm of A to, font=\small\ttfamily] {Something else happens here};
。
但是如果您需要更改字体选项,则message content
需要更改\mess
命令声明。在下一个代码中,我添加了第五个参数,\mess
该参数将用于设置消息内容的节点选项。我的示例展示了如何使用显式选项执行此操作,但您可以声明一些选项style
并在那里使用它。如您所见,即使没有任何更改,您也需要在每个命令中包含一个空的第五个参数\mess
。
\documentclass[tikz,border=3mm]{standalone}
\usepackage{pgf-umlsd}
\usetikzlibrary{shadows,positioning}
% message between threads
% Example:
% \mess[delay]{sender}{message content}{receiver}
\renewcommand{\mess}[5][0]{
\stepcounter{seqlevel}
\path
(#2)+(0,-\theseqlevel*\unitfactor-0.7*\unitfactor) node (mess from) {};
\addtocounter{seqlevel}{#1}
\path
(#4)+(0,-\theseqlevel*\unitfactor-0.7*\unitfactor) node (mess to) {};
\draw[->,>=angle 60] (mess from) -- (mess to) node[midway, above,#5]
{#3};
\node (#3 from) at (mess from) {};
\node (#3 to) at (mess to) {};
}
\begin{document}
\begin{sequencediagram}
\newinst{c}{Client}
\newinst[6]{s}{Server}
\mess[1]{c}{A}{s}{font=\Large, text=red}
\node[left=0mm of A from] {First message};
\node[right=0mm of A to] {First message received};
\mess[1]{s}{B}{c}{}
\node[right=0mm of B from] {Ack to First message};
\draw[line width=3pt] (A to) -- (B from);
\mess[1]{c}{A}{s}{font=\itshape, draw=blue}
\node[right=0mm of A to, font=\small\ttfamily] {Something else happens here};
\mess[1]{s}{B}{c}{}
\mess[1]{c}{...}{s}{}
\mess[1]{s}{...}{c}{}
\stepcounter{seqlevel}
\mess[1]{s}{C}{c}{}
\path(C from) -- (C to) node[midway, above=\unitfactor]
{\vdots};
\end{sequencediagram}
\end{document}