我想创建 IETF 文档中所示的小型协议消息图(例如协同应用协议)。根据文本量自动对齐效果会更好(较大的文本会像CoAP HLS)
例子:
Client Server
| |
| |
+----->| Header: GET (T=CON, Code=0.01, MID=0x7d34)
| GET | Uri-Path: "temperature"
| |
| |
|<-----+ Header: 2.05 Content (T=ACK, Code=2.05, MID=0x7d34)
| 2.05 | Payload: "22.3 C"
| |
是否有一些可以提供帮助的包? 硕士和pgf-umlsd或者tikz-uml看起来不对劲……
或者我可以使用 TikZ “手绘”它。如果这里没有包可以提供帮助,那么最小的 TikZ 示例会是什么样子?
答案1
我认为,如果您开始发表评论,然后使用它们作为参考来绘制消息交换,那么绘制这样的图表很容易。
下一个代码显示了一个最小示例。我曾经matrix
创建过所有comments
和server
和client
标签。当然,您不需要使用matrix
,可以使用相对位置来放置它们。
棘手的部分是如何将消息箭头与相应的注释第一行对齐。也许有更好的解决方案,但我使用了\subnode
命令tikzmark
库。它在每个注释节点内创建一个内部引用。
最后,借助交叉坐标(|-
或-|
)可以轻松绘制消息交换。
这是一个最小示例的完整代码:
\documentclass[tikz,border=2mm]{standalone}
\usetikzlibrary{matrix,positioning,tikzmark}
\begin{document}
\begin{tikzpicture}[remember picture, % --- Dont' forget it with tikzmark ---
comment/.style={text width=10cm, align=left},
font=\small\ttfamily]
%Place `Client`, `Server` and `comment` nodes
\matrix{%
\node (client) {Client}; &
\node (server) {Server}; & \\
& &
\node[comment] (1) {\subnode{A}{Header}:
GET (T=CON, Code=0.01, MID=0x7d34)\\
Uri-Path: "temperature"}; \\
& &
\node[comment] (2) {\subnode{B}{Header}:
2.05 Content (T=ACK, Code=2.05, MID=0x7d34)\\
Payload: "22.3 C"}; \\};
%Draw vertical lines
\draw (client) -- (client|-2.south);
\draw (server) -- (server|-2.south);
%Draw message interchanges
\draw[->] (A-|client)--node[below]{GET} (A-|server) ;
\draw[<-] (B-|client)-- node[below]{2.05} (B-|server) ;
\end{tikzpicture}
\end{document}
编译上述代码两次可得到
更新
如果要将注释对齐在冒号周围,可以使用tabular
注释内部。在这种情况下,您必须使用ampersand replacement
选项内部,因为内部和内部\matrix
必须有不同的&
符号。tabular
matrix
\begin{tikzpicture}[remember picture,
comment/.style={text width=10cm, align=left},
font=\small\ttfamily]
%Place `Client`, `Server` and `comment` nodes
\matrix [ampersand replacement=\&]{%
\node (client) {Client}; \&
\node (server) {Server}; \& \\
\& \&
\node[comment] (1) {\begin{tabular}{r@{ }l}\subnode{A}{Header}:&
GET (T=CON, Code=0.01, MID=0x7d34)\\
Uri-Path:& "temperature"\end{tabular}}; \\
\& \&
\node[comment] (2) {\begin{tabular}{r@{ }l}\subnode{B}{Header}:&
2.05 Content (T=ACK, Code=2.05, MID=0x7d34)\\
Payload:& "22.3 C"\end{tabular}}; \\};
%Draw vertical lines
\draw (client) -- (client|-2.south);
\draw (server) -- (server|-2.south);
%Draw message interchanges
\draw[->] (A-|client)--node[below]{GET} (A-|server) ;
\draw[<-] (B-|client)-- node[below]{2.05} (B-|server) ;
\end{tikzpicture}
结果是
但是,如果你想要对齐所有注释,最好将它们全部放在 中tabular
。你可以避免使用\matrix
并在其后放置server
和client
标签。为了区分不同的注释,你可以\\[vertical distance]
在 中使用tabular
。
解决方案如下:
\begin{tikzpicture}[remember picture,
font=\small\ttfamily]
%Place a `comment` node with all text inside a tabular
\node(comments) {\begin{tabular}{r@{ }l}
\subnode{A}{Header}:&
GET (T=CON, Code=0.01, MID=0x7d34)\\
Uri-Path:& "temperature"\\[3mm]
\subnode{B}{Header}:&
2.05 Content (T=ACK, Code=2.05, MID=0x7d34)\\
Payload:& "22.3 C"\end{tabular}};
% Place `server` and `client` nodes
\node[above left=1mm and 0mm of comments] (server) {Server};
\node[left=5mm of server] (client) {Client};
%Draw vertical lines
\draw (client) -- (client|-comments.south);
\draw (server) -- (server|-comments.south);
%Draw message interchanges
\draw[->] (A-|client)--node[below]{GET} (A-|server) ;
\draw[<-] (B-|client)-- node[below]{2.05} (B-|server) ;
\end{tikzpicture}
结果是:
答案2
msc 包(www.ctan.org/pkg/msc mirror.ctan.org:macros/latex/contrib/msc)似乎可以满足您的要求。
当然它不是 pgf-sexy...