我需要在 LaTeX 中绘制鱼尾纹风格的 ER 图。经过一番搜索,我发现:
但是,我发现这种风格对我来说并不“完整”。我需要写下两个表之间的“动词”,并指明表的主键 (PK) 和外键 (FK)。上传图片上的红色文本显示了我需要的内容。
经过一些编码后,我只能创建一些新的关系,例如“1:零、一或多”。但是我对插入文本感到困惑,因为没有任何节点。感谢您的帮助。谢谢。
我所做的最好的尝试是:
\documentclass[12pt]{article}
\usepackage{tikz}
\usetikzlibrary{shapes.multipart}
\usetikzlibrary{matrix}
\usetikzlibrary{positioning}
\usetikzlibrary{shadows}
\usetikzlibrary{calc}
%\usepackage{pdflscape}
% Monspace Font Package
%\usepackage{courier}
\usepackage{lmodern}
%\renewcommand*\familydefault{\ttdefault} %% Only if the base font of the document is to be typewriter style
\makeatletter
\pgfarrowsdeclare{crow's foot}{crow's foot}
{
\pgfarrowsleftextend{+-.5\pgflinewidth}%
\pgfarrowsrightextend{+.5\pgflinewidth}%
}
{
\pgfutil@tempdima=0.6pt%
%\advance\pgfutil@tempdima by.25\pgflinewidth%
\pgfsetdash{}{+0pt}%
\pgfsetmiterjoin%
\pgfpathmoveto{\pgfqpoint{0pt}{-9\pgfutil@tempdima}}%
\pgfpathlineto{\pgfqpoint{-13\pgfutil@tempdima}{0pt}}%
\pgfpathlineto{\pgfqpoint{0pt}{9\pgfutil@tempdima}}%
\pgfpathmoveto{\pgfqpoint{0\pgfutil@tempdima}{0\pgfutil@tempdima}}%
\pgfpathmoveto{\pgfqpoint{-8pt}{-6pt}}%
\pgfpathlineto{\pgfqpoint{-8pt}{-6pt}}%
\pgfpathlineto{\pgfqpoint{-8pt}{6pt}}%
\pgfusepathqstroke%
}
\pgfarrowsdeclare{omany}{omany}
{
\pgfarrowsleftextend{+-.5\pgflinewidth}%
\pgfarrowsrightextend{+.5\pgflinewidth}%
}
{
\pgfutil@tempdima=0.6pt%
%\advance\pgfutil@tempdima by.25\pgflinewidth%
\pgfsetdash{}{+0pt}%
\pgfsetmiterjoin%
\pgfpathmoveto{\pgfqpoint{0pt}{-9\pgfutil@tempdima}}%
\pgfpathlineto{\pgfqpoint{-13\pgfutil@tempdima}{0pt}}%
\pgfpathlineto{\pgfqpoint{0pt}{9\pgfutil@tempdima}}%
\pgfpathmoveto{\pgfqpoint{0\pgfutil@tempdima}{0\pgfutil@tempdima}}%
\pgfpathmoveto{\pgfqpoint{0\pgfutil@tempdima}{0\pgfutil@tempdima}}%
\pgfpathmoveto{\pgfqpoint{-6pt}{-6pt}}%
\pgfpathcircle{\pgfpoint{-11.5pt}{0}} {3.5pt}
\pgfusepathqstroke%
}
\pgfarrowsdeclare{one}{one}
{
\pgfarrowsleftextend{+-.5\pgflinewidth}%
\pgfarrowsrightextend{+.5\pgflinewidth}%
}
{
\pgfutil@tempdima=0.6pt%
%\advance\pgfutil@tempdima by.25\pgflinewidth%
\pgfsetdash{}{+0pt}%
\pgfsetmiterjoin%
\pgfpathmoveto{\pgfqpoint{0\pgfutil@tempdima}{0\pgfutil@tempdima}}%
\pgfpathmoveto{\pgfqpoint{-6pt}{-6pt}}%
\pgfpathlineto{\pgfqpoint{-6pt}{-6pt}}%
\pgfpathlineto{\pgfqpoint{-6pt}{6pt}}%
\pgfpathmoveto{\pgfqpoint{0\pgfutil@tempdima}{0\pgfutil@tempdima}}%
\pgfpathmoveto{\pgfqpoint{-8pt}{-6pt}}%
\pgfpathlineto{\pgfqpoint{-8pt}{-6pt}}%
\pgfpathlineto{\pgfqpoint{-8pt}{6pt}}%
\pgfusepathqstroke%
}
\tikzset{
entity/.code={
\tikzset{
label=above:#1,
name=#1,
inner sep=0pt,
every entity/.try,
fill=white
}%
\def\entityname{#1}%
},
entity anchor/.style={matrix anchor=#1.center},
every entity/.style={
draw,
},
every property/.style={
inner xsep=0.25cm, inner ysep=0.15cm, anchor=west, text width=1in
},
zig zag to/.style={
to path={(\tikztostart) -| ($(\tikztostart)!#1!(\tikztotarget)$) |- (\tikztotarget)}
},
zig zag to/.default=0.5,
one to one/.style={
one-one, zig zag to
},
one to many/.style={
one-crow's foot, zig zag to,
},
one to omany/.style={
one-omany, zig zag to
},
many to one/.style={
crow's foot-one, zig zag to
},
many to many/.style={
crow's foot-crow's foot, zig zag to
}
}
\def\property#1{\node[name=\entityname-#1, every property/.try]{#1};}
\def\properties{\begingroup\catcode`\_=11\relax\processproperties}
\def\processproperties#1{\endgroup%
\def\propertycode{}%
\foreach \p in {#1}{%
\expandafter\expandafter\expandafter\gdef\expandafter\expandafter\expandafter\propertycode%
\expandafter\expandafter\expandafter{\expandafter\propertycode\expandafter\property\expandafter{\p}\\}%
}%
\propertycode%
}
\begin{document}
%\begin{landscape}
\begin{tikzpicture}[every node/.style={font=\ttfamily}, node distance=5cm]
\matrix [entity=MEMBER] {
\properties{
MID,
MName
}
};
\matrix [entity=TABLE, right=of MEMBER-MID, entity anchor=TABLE-TID] {
\properties{
TID,
MID,
CNAME,
CADDRESS
}
};
\draw [one to omany] (MEMBER-MID) to (TABLE-TID);
\end{tikzpicture}
%\end{landscape}
\end{document}
答案1
要获取节点,通常只需node[above]{has}
在 后面放置一个to
。但是,在这种情况下,样式zig zag to
重新定义了to path
,忽略了路径上的任何节点。所以这是我们需要更改的第一件事。
更改样式
zig zag to/.style={
to path={(\tikztostart) -| ($(\tikztostart)!#1!(\tikztotarget)$) |- (\tikztotarget)}
},
到
zig zag to/.style={
to path={(\tikztostart) -| ($(\tikztostart)!#1!(\tikztotarget)$) |- (\tikztotarget) \tikztonodes}
},
然后,您只需简单地写下来\draw [one to omany] (MEMBER-MID) to node[above]{has} (TABLE-TID);
即可获得关系上方的动词。
第二,主键和外键指示。这里最简单的方法是分别指定它们。也就是说,不要将它们包含在宏中properties
,而是编写两个单独的宏来处理它们。您可以在序言中添加以下定义:
\def\pk#1{\node[name=\entityname-#1, every property/.try]{#1};\node[name=\entityname-#1, every property/.try, red, text width=1in, align=right]{(PK)};\\}
\def\fk#1{\node[name=\entityname-#1, every property/.try]{#1};\node[name=\entityname-#1, every property/.try, red, text width=1in, align=right]{(FK)};\\}
最后文档本身看起来会像这样:
\begin{document}
\begin{tikzpicture}[every node/.style={font=\ttfamily}, node distance=5cm]
\matrix [entity=MEMBER] {
\pk{MID}
\properties{
MName
}
};
\matrix [entity=TABLE, right=of MEMBER-MID, entity anchor=TABLE-TID] {
\pk{TID}
\fk{MID}
\properties{
CNAME,
CADDRESS
}
};
\draw [one to omany] (MEMBER-MID) to node[above]{label} (TABLE-TID);
\end{tikzpicture}
\end{document}
这应该会给你提供类似于你提供的图像的输出。我还没有用你的 MWE 之外的任何东西测试过它,但我没有发现任何明显的问题。