对于示例关系 R: A -> B,我有以下 TikZ 代码:
\documentclass[tikz]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes,backgrounds,decorations.text,patterns}
\usetikzlibrary{plotmarks}
\begin{document}
\begin{tikzpicture}
\begin{scope}[mark=*,mark size=1pt]
% sets A & B
\draw (0,0) node[ellipse, minimum height=50pt,minimum width=30pt,draw,label=above:A]{};
\draw (2,0) node[ellipse, minimum height=50pt,minimum width=30pt,draw,label=above:B]{};
% draw line and label origin a to c
\draw[->] plot coordinates {(0,10pt)} (0,10pt) node[above]{a} -- (1.9,16pt);
% add end point
\node at (2,16pt) {\pgfuseplotmark{*}};
% add end label
\node[above] at (2,16pt) {c};
% draw line and label origin a to e
\draw[->] plot coordinates {(0,10pt)} (0,10pt) node[above]{a} -- (1.9,-15pt);
% add end point
\node at (2,-15pt) {\pgfuseplotmark{*}};
% add end label
\node[above] at (2,-15pt) {e};
% draw line and label origin b to d
\draw[->] plot coordinates {(0,-10pt)} (0,-10pt) node[above]{b} -- (1.6,2pt);
% add end point
\node at (1.7,2pt) {\pgfuseplotmark{*}};
% add end label
\node[above] at (1.7,2pt) {d};
\end{scope}
\end{tikzpicture}
\end{document}
生成:
在 TikZ 中有没有更简单的方法来实现这一点?这似乎需要做很多工作。
答案1
毫无疑问需要调整,因为我不知道适用的标准:
\documentclass[tikz,border=5pt]{standalone}
\usetikzlibrary{shapes,positioning,fit,calc}
\begin{document}
\begin{tikzpicture}
[
group/.style={ellipse, draw, minimum height=50pt, minimum width=30pt, label=above:#1},
my dot/.style={circle, fill, minimum width=2.5pt, label=above:#1, inner sep=0pt}
]
\node (a) [my dot=a] {};
\node (b) [below=of a, my dot=b] {};
\node (c) [right=50pt of a, my dot=c] {};
\node (e) [below=of c, my dot=e] {};
\node (d) [xshift=-2.5pt, my dot=d] at ($(c)!1/2!(e)$) {};
\foreach \i/\j in {a/c,a/e,b/d}
\draw [->, shorten >=2pt] (\i) -- (\j);
\node [fit=(a) (b), group=A] {};
\node [fit=(d) (c) (e), group=B] {};
\end{tikzpicture}
\end{document}
这使用样式来最大限度地减少代码重复。特别是,它使用对标签使用参数(#1)的样式。它还使用库fit
来表示省略号,并使用positioning
和calc
库来帮助指定位置。这使得可以节省大量代码。最后,使用循环来绘制箭头,尽管如果您只有 3 个箭头需要绘制,这可能并不值得 - 但是,如果您有 30 个以上的箭头,它确实会发挥作用。