代码中的创造力时刻已经到来!
我想做一个实体关系模型(ER模型)使用tikzpicture
环境。
我发现TikZ
实际上有一个用于该内容的库(\usetikzlibrary{er}
)和其他东西,但实际上我不需要颜色或奇怪的形状来创建以下通用 ER 图:
手册er
没有提到创建关系也没有提到围绕实体的标签,所以这对我来说很困难。
一般注意事项
- 存在四种关系可能性(其组合则处于另一个极端):
- 一个实体可以有一个、几个或没有属性,一个属性在另一个属性之下(字母大小小于实体的文本)。
- 实体必须有坐标才能添加标签(尺寸小于属性)。注意其子实体
is in
之间的标签。Entity C
- 实体之间的关系可能具有折叠/正交性。
- 属性必须有
\scriptsize
字体。
使其发生!
编辑(MWE 添加)
谢谢CarLaTeX 的有用评论我又取得了一些进步:
\documentclass{article}
\usepackage{array}
\renewcommand{\arraystretch}{1.1}
\usepackage{tikz}
\usetikzlibrary{shapes.multipart}
\usetikzlibrary{positioning}
\usetikzlibrary{shadows}
\usetikzlibrary{calc}
\usepackage{pdflscape}
% code for "one to omany", etc. is taken from https://tex.stackexchange.com/q/141797/101651
\makeatletter
\pgfarrowsdeclare{crow's foot}{crow's foot}
{
\pgfarrowsleftextend{+-.5\pgflinewidth}%
\pgfarrowsrightextend{+.5\pgflinewidth}%
}
{
\pgfutil@tempdima=0.6pt%
\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%
\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%
\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%
}
\makeatother
\tikzset{%
pics/entity/.style n args={3}{code={%
\node[draw,
rectangle split,
rectangle split parts=2,
text height=1.5ex,
] (#1)
{#2 \nodepart{second}
\begin{tabular}{>{\raggedright\arraybackslash}p{8.5em}}
#3
\end{tabular}
};%
}},
pics/entitynoatt/.style n args={2}{code={%
\node[draw,
text height=1.5ex,
] (#1)
{#2};%
}},
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 oone/.style={ % I do not how to make "one to Optional-one" rel
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
}
}
\begin{document}
\begin{landscape}
\begin{center}
\begin{tikzpicture}
\pic {entity={A}{Entity A}{%
attribute 1 \\
attribute 2 \\
... \\
attribute i
}};
\pic[right=7em of A] {entity={AB}{Entity A for Entity B}{%
attribute 1 \\
attribute 2
}};
\pic[right=7em of AB] {entity={B}{Entity B}{%
attribute 1 \\
attribute 2 \\
... \\
attribute i
}};
\pic[below=16ex of B] {entity={C}{Entity C}{%
attribute 1
}};
\pic[below=15ex of AB] {entitynoatt={C1}{Entity C\_1}};
\pic[below=9ex of C1] {entitynoatt={C2}{Entity C\_2}};
\draw[one to omany] (A.east) -- node[above]{\footnotesize is in} (AB.west);
\draw[one to omany] (B.west) -- node[above]{\footnotesize is in} (AB.east);
\draw[one to one] (B.south) -- node[right]{\footnotesize is in} (C.north);
\draw[one to oone] (C.west) -| ($(C.west)!.5!(C1.east)$) |- node[above]{\footnotesize is in} (C1.east); % Make "oone" rel
\draw[one to oone] (C.west) -| ($(C.west)!.5!(C2.east)$) |- node[below]{\footnotesize is in} (C2.east); % Make "oone" rel
\end{tikzpicture}
\end{center}
\end{landscape}
\end{document}
不过,有些地方我想修改一下:
- 在实体的
#1
参数(标签)中添加新行。 - 在可选基数中用白色圆圈代替透明圆圈。
- 当两个曲线关系在同一点时,减少该部分的厚度,因为从远处看它似乎更厚:。
- 建立“一对可选一”和“可选一对可选一”的关系。
- 将关系之间的标签放置在实体的外边缘。
一些链接
谢谢!
答案1
在实体的 #1 参数(标签)中添加新行
只需声明一个text width=...
,然后就可以\\
在节点描述中使用。
在可选基数中用白色圆圈代替透明圆圈。
\pgfsetfillcolor{white}
和已完成\pgfusepathqfillstroke
。
当在同一点找到两个弯曲关系时,减少该部分的厚度,因为从远处看它似乎更厚:减少厚度。
确实,是因为它被绘制了两次所以更厚,我采用了一个技巧只绘制一次(第二条路径只绘制到交叉点)。
建立“一对可选一”和“可选一对可选一”的关系。
创建one to oone
并oone to none
或多或少oone to oone
复制自我之前的回答,也是从这里。
将关系之间的标签放置在实体的外边缘。
由于标签与路径并不严格相关,只需将一些节点放在所需的位置即可。
属性必须有
\scriptsize
字体。
添加[font=\scriptsize]
到\nodepart
。
\documentclass{article}
\usepackage{array}
\renewcommand{\arraystretch}{1.1}
\usepackage{tikz}
\usetikzlibrary{shapes.multipart}
\usetikzlibrary{positioning}
\usetikzlibrary{shadows}
\usetikzlibrary{calc}
\usepackage{pdflscape}
% code for "one to omany", etc. is taken from https://tex.stackexchange.com/q/141797/101651
\makeatletter
\pgfarrowsdeclare{crow's foot}{crow's foot}
{
\pgfarrowsleftextend{+-.5\pgflinewidth}%
\pgfarrowsrightextend{+.5\pgflinewidth}%
}
{
\pgfutil@tempdima=0.6pt%
\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%
\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}}%
\pgfusepathqstroke%
\pgfsetfillcolor{white}
\pgfpathcircle{\pgfpoint{-11.5pt}{0}} {3.5pt}
\pgfusepathqfillstroke%
}
\pgfarrowsdeclare{one}{one}
{
\pgfarrowsleftextend{+-.5\pgflinewidth}%
\pgfarrowsrightextend{+.5\pgflinewidth}%
}
{
\pgfutil@tempdima=0.6pt%
\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%
}
\pgfarrowsdeclare{oone}{oone}
{
\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{-4pt}{-6pt}}%
\pgfpathlineto{\pgfqpoint{-4pt}{-6pt}}%
\pgfpathlineto{\pgfqpoint{-4pt}{6pt}}%
\pgfsetfillcolor{white}
\pgfpathcircle{\pgfpoint{-11.5pt}{0}} {3.5pt}
\pgfusepathqfillstroke%
}
\makeatother
\tikzset{%
mylabel/.style={font=\footnotesize},
pics/entity/.style n args={3}{code={%
\node[draw,
rectangle split,
rectangle split parts=2,
text height=1.5ex,
text width=8.5em,
text centered
] (#1)
{#2 \nodepart[font=\scriptsize]{second}
\begin{tabular}{>{\raggedright\arraybackslash}p{9em}}
#3
\end{tabular}
};%
}},
pics/entitynoatt/.style n args={2}{code={%
\node[draw,
text height=1.5ex,
text width=8.5em,
text centered
] (#1)
{#2};%
}},
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 oone/.style={% One to Optional-one
one-oone, zig zag to
},
oone to none/.style={% Optional-one to none
oone-, zig zag to
},
oone to oone/.style={% Optional one to Optional-one
oone-oone, zig zag to
},
one to many/.style={
one-crow's foot, zig zag to,
},
one to omany/.style={
one-omany, zig zag to
},
one to none/.style={
one-, zig zag to
},
}
\begin{document}
\begin{landscape}
\begin{center}
\begin{tikzpicture}
\pic {entity={A}{Entity A}{%
attribute 1 \\
attribute 2 \\
... \\
attribute i
}};
\pic[right=7em of A] {entity={AB}{{Entity A \\ for \\ Entity B}}{%
attribute 1 \\
attribute 2
}};
\pic[right=7em of AB] {entity={B}{Entity B}{%
attribute 1 \\
attribute 2 \\
... \\
attribute i
}};
\pic[below=16ex of B] {entity={C}{Entity C}{%
attribute 1
}};
\pic[below=15ex of AB] {entitynoatt={C1}{Entity C\textunderscore 1}};
\pic[below=9ex of C1] {entitynoatt={C2}{Entity C\textunderscore 2}};
\draw[one to omany] (A.east) -- (AB.west);
\node[mylabel, anchor=south east] at (A.north east) {is in};
\draw[one to omany] (B.west) -- (AB.east);
\node[mylabel, anchor=south west] at (B.north west) {is in};
\draw[one to one] (B.south) -- (C.north);
\node[mylabel, anchor=south west] at (B.south east) {is in};
\node[mylabel, anchor=north west] at (C.north east) {is in};
%From section 13.3 of the TikZ manual, (2,1 |- 3,4) and (3,4 -| 2,1) both yield the same as (2,4)
\coordinate (mymiddle) at ($(C.west)!.5!(C1.east)$);
\coordinate (mylink) at (C.west -| mymiddle);
\draw[one to oone] (C.west) -| (mymiddle) node[mylabel, above=10pt]{is in} |- (C1.east); % Make "oone" rel
\draw[oone to none] (C2.east) -| node[mylabel, below=2pt]{is in} (mylink);
\end{tikzpicture}
\end{center}
\end{landscape}
\end{document}
答案2
我回答得太晚了,没能获得赏金,但@CarLaTeX 值得,因为她为你做了大量研究。
您的问题和杰出贡献者的评论激励我解决您的问题。对此我表示感谢。
首先,使用pdflscape
包来拥有格式的页面是没有意义的landscape
:它是文章类的原生选项:\documentclass[landscape]{article}
将旧代码 v 1.18 与新代码 3.0.1a 进行转录:
您的代码的操作\pgfarrowsdeclare
未记录在 TikZ 3.0.1a 版中。此操作可在手册第 317 页找到1.18
(可用这里可供下载)。
我按照手册的语法转录了他的代码3.0.1a
,现在调用该操作\pgfdeclarearrow
(名称被反转,参见 3.0.1a 手册第 1017 页)。
我注意到这个旧代码很笨拙:许多操作根本没有必要,而且什么也不做。我删除了所有注释行,因为在前面加 是没用的\pgfpathlineto
。\pgfpathmoveto
就\pgfpathlineto
足够了。
\pgfarrowsdeclare{omany}{omany}
{
\pgfarrowsleftextend{+-.5\pgflinewidth}%
\pgfarrowsrightextend{+.5\pgflinewidth}%
}
{
\pgfutil@tempdima=0.6pt%
\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%
}
因此我清除了所有关系箭头的代码。
箭头现在根据线条的粗细改变比例。
\arrowsize
我使用了一个为此调用的 TeX 注册表。
从现在开始,箭头会根据线的粗细略微增加\pgflinewidth
。
\arrowsize=0.5pt%
\advance\arrowsize by .25\pgflinewidth
C
和之间的线的粗细问题C1 C2
:
这是由于您在放置C1
和时计算错误C2
,因为这两个节点的中间不在的正中间 C
。
因此,为了避免复杂的计算,我以不同的方式构建了你的图表:我放置C1
了C2
相对的至C
和不是正如您对 所做的那样AB
。
\pic[above left=2ex and 7em of C] {entitynoatt={C1}{Entity C\_1}};
\pic[below left=2ex and 7em of C] {entitynoatt={C2}{Entity C\_2}};
为了放置标签,我创建了一个名为的图片,is in
其参数是angle
它的anchor
。
is in/.pic={\node[label=#1:is in,outer sep=0pt,minimum size=0pt]{};}
实体关系图符号
由于我不知道实体关系图符号,所以我在网上搜索了一下。看来这些符号没有标准化,因此我们可以自由地根据自己的喜好进行设计。
因此,在这一点上地点,绘制如下:
在这个以及:
ETC。
这是我的建议:
我画了不同粗细的线来直观地展示箭头长度的变化。名称箭头上写着多于, 这线尺寸以下。
我刚刚打电话给他们:
mmany
表示“强制性的许多”;omany
表示“可选多个”;mone
为“强制性的”;oone
“可选”
他们的代码如下:
\documentclass[tikz,border=10mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning}
\pgfdeclarearrow{ %page 1020 of 3.0.1a manual
name = mmany,
parameters = { },
setup code = { },
drawing code = {
\newdimen\arrowsize%
\arrowsize=0.5pt%
\pgfsetdash{}{+0pt}%
\pgfsetmiterjoin%
\advance\arrowsize by .25\pgflinewidth%
\pgfpathmoveto{\pgfqpoint{0pt}{-9\arrowsize}}%
\pgfpathlineto{\pgfqpoint{-13\arrowsize}{0pt}}%
\pgfpathlineto{\pgfqpoint{0pt}{9\arrowsize}}%
\pgfpathmoveto{\pgfqpoint{-19\arrowsize}{-10\arrowsize}}%
\pgfpathlineto{\pgfqpoint{-19\arrowsize}{10\arrowsize}}%
\pgfusepathqstroke%
},
defaults = { }
}
\pgfdeclarearrow{ %page 1020 of 3.0.1a manual
name = omany,
parameters = { },
setup code = { },
drawing code = {
\newdimen\arrowsize%
\arrowsize=0.5pt%
\pgfsetdash{}{+0pt}%
\pgfsetmiterjoin%
\advance\arrowsize by .25\pgflinewidth%
\pgfpathmoveto{\pgfqpoint{0pt}{-9\arrowsize}}%
\pgfpathlineto{\pgfqpoint{-13\arrowsize}{0pt}}%
\pgfpathlineto{\pgfqpoint{0pt}{9\arrowsize}}%
\pgfusepathqstroke%
\pgfsetfillcolor{white}
\pgfpathcircle{\pgfpoint{-19\arrowsize}{0}} {6\arrowsize}%
\pgfusepathqfillstroke%
},
defaults = { }
}
\pgfdeclarearrow{ %page 1020 of 3.0.1a manual
name = mone,
parameters = { },
setup code = { },
drawing code = {
\newdimen\arrowsize%
\arrowsize=0.5pt%%
\pgfsetdash{}{+0pt}%
\pgfsetmiterjoin%
\advance\arrowsize by .25\pgflinewidth%
\pgfpathmoveto{\pgfqpoint{-9\arrowsize}{-10\arrowsize}}%
\pgfpathlineto{\pgfqpoint{-9\arrowsize}{10\arrowsize}}%
\pgfpathmoveto{\pgfqpoint{-19\arrowsize}{-10\arrowsize}}%
\pgfpathlineto{\pgfqpoint{-19\arrowsize}{10\arrowsize}}%
\pgfusepathqstroke%
},
defaults = { }
}
\pgfdeclarearrow{ %page 1020 of 3.0.1a manual
name = oone,
parameters = { },
setup code = { },
drawing code = {
\newdimen\arrowsize%
\arrowsize=0.5pt%
\pgfsetdash{}{+0pt}%
\pgfsetmiterjoin%
\advance\arrowsize by .25\pgflinewidth
\pgfpathmoveto{\pgfqpoint{-9\arrowsize}{-10\arrowsize}}%
\pgfpathlineto{\pgfqpoint{-9\arrowsize}{10\arrowsize}}%
\pgfsetfillcolor{white}
\pgfpathcircle{\pgfpoint{-19\arrowsize}{0}} {6\arrowsize}%
\pgfusepathqfillstroke%
},
defaults = { }
}
\begin{document}
\begin{tikzpicture}[every node/.style={font=\scriptsize}]
\draw[mmany - mmany,very thin] (0,0) -- node[above]{ mmany}node[below]{very thin} (5,0);
\draw[omany - omany] (0,-1) -- node[above]{omany}node[below]{normal size} (5,-1);
\draw[mone - mone,thick] (0,-2) -- node[above]{mone}node[below]{thick} (5,-2);
\draw[oone - oone,very thick] (0,-3) -- node[above]{ oone}node[below]{very thick} (5,-3);
\end{tikzpicture}
\end{document}
使用边缘操作连接实体
我zig-zag
从样式中删除了该选项relationship
。这样就可以edges
用它来构建relationship arrows
它们entities
,然后只需通过它们的名称来调用它们。
\draw[one to omany] (A) edge (AB);
\draw[one to omany] (B) edge (AB);
\draw[one to one] (B) edge (C);
\path[one to oone,zig zag] (C1) edge (C); % by default zig zag=.5
\path[one to oone,zig zag=.5 ] (C2) edge (C);%
结果和最终代码:
\documentclass[landscape]{article}
\usepackage{array}
\renewcommand{\arraystretch}{1.1}
\usepackage{tikz}
\usetikzlibrary{shapes.multipart}
\usetikzlibrary{positioning}
\usetikzlibrary{calc}
%\usetikzlibrary{er}
\pgfdeclarearrow{ %page 1020 of 3.0.1a manual
name = mmany,
parameters = { },
setup code = { },
drawing code = {
\newdimen\arrowsize%
\arrowsize=0.5pt%
\pgfsetdash{}{+0pt}%
\pgfsetmiterjoin%
\advance\arrowsize by .25\pgflinewidth%
\pgfpathmoveto{\pgfqpoint{0pt}{-9\arrowsize}}%
\pgfpathlineto{\pgfqpoint{-13\arrowsize}{0pt}}%
\pgfpathlineto{\pgfqpoint{0pt}{9\arrowsize}}%
\pgfpathmoveto{\pgfqpoint{-19\arrowsize}{-10\arrowsize}}%
\pgfpathlineto{\pgfqpoint{-19\arrowsize}{10\arrowsize}}%
\pgfusepathqstroke%
},
defaults = { }
}
\pgfdeclarearrow{ %page 1020 of 3.0.1a manual
name = omany,
parameters = { },
setup code = { },
drawing code = {
\newdimen\arrowsize%
\arrowsize=0.5pt%
\pgfsetdash{}{+0pt}%
\pgfsetmiterjoin%
\advance\arrowsize by .25\pgflinewidth%
\pgfpathmoveto{\pgfqpoint{0pt}{-9\arrowsize}}%
\pgfpathlineto{\pgfqpoint{-13\arrowsize}{0pt}}%
\pgfpathlineto{\pgfqpoint{0pt}{9\arrowsize}}%
\pgfusepathqstroke%
\pgfsetfillcolor{white}
\pgfpathcircle{\pgfpoint{-19\arrowsize}{0}} {6\arrowsize}%
\pgfusepathqfillstroke%
},
defaults = { }
}
\pgfdeclarearrow{ %page 1020 of 3.0.1a manual
name = mone,
parameters = { },
setup code = { },
drawing code = {
\newdimen\arrowsize%
\arrowsize=0.5pt%%
\pgfsetdash{}{+0pt}%
\pgfsetmiterjoin%
\advance\arrowsize by .25\pgflinewidth%
\pgfpathmoveto{\pgfqpoint{-9\arrowsize}{-10\arrowsize}}%
\pgfpathlineto{\pgfqpoint{-9\arrowsize}{10\arrowsize}}%
\pgfpathmoveto{\pgfqpoint{-19\arrowsize}{-10\arrowsize}}%
\pgfpathlineto{\pgfqpoint{-19\arrowsize}{10\arrowsize}}%
\pgfusepathqstroke%
},
defaults = { }
}
\pgfdeclarearrow{ %page 1020 of 3.0.1a manual
name = oone,
parameters = { },
setup code = { },
drawing code = {
\newdimen\arrowsize%
\arrowsize=0.5pt%
\pgfsetdash{}{+0pt}%
\pgfsetmiterjoin%
\advance\arrowsize by .25\pgflinewidth
\pgfpathmoveto{\pgfqpoint{-9\arrowsize}{-10\arrowsize}}%
\pgfpathlineto{\pgfqpoint{-9\arrowsize}{10\arrowsize}}%
\pgfsetfillcolor{white}
\pgfpathcircle{\pgfpoint{-19\arrowsize}{0}} {6\arrowsize}%
\pgfusepathqfillstroke%
},
defaults = { }
}
\tikzset{%
is in/.pic={\node[label=#1:is in,outer sep=0pt,minimum size=0pt]{};},
pics/entity/.style n args={3}{code={%
\node[draw,
rectangle split,
rectangle split parts=2,
text height=1.5ex,
] (#1)
{#2 \nodepart{second}
\begin{tabular}{>{\raggedright\arraybackslash}p{8.5em}}
#3
\end{tabular}
};%
}},
pics/entitynoatt/.style n args={2}{code={%
\node[draw,
text height=1.5ex,
] (#1)
{#2};%
}},
zig zag/.style={
to path={(\tikztostart) -| ($(\tikztostart)!#1!(\tikztotarget)$) |- (\tikztotarget)}
},
zig zag/.default=0.5,
one to one/.style={
mone-mone,
},
one to oone/.style={
mone-oone
},
one to many/.style={
mone-mmany,
},
one to omany/.style={
mone-omany
}
}
\begin{document}
\begin{center}
\begin{tikzpicture}
[every node/.style={ minimum width=4cm},
every second node part/.style={font=\small},
every label/.style={minimum size=0pt}
]
\pic {entity={A}{Entity A}{%
attribute 1 \\
attribute 2 \\
... \\
attribute i
}};
\pic at (A.north east){is in=0};
\pic[right=7em of A] {entity={AB}{Entity A for Entity B}{%
attribute 1 \\
attribute 2
}};
\pic[right=7em of AB] {entity={B}{Entity B}{%
attribute 1 \\
attribute 2 \\
... \\
attribute i
}};
\pic at (B.north west){is in=180};
\pic at (B.south east){is in=0};
\pic[below=16ex of B] {entity={C}{Entity C}{%
attribute 1
}};
\pic at (C.north east){is in=0};
\pic[above left=2ex and 7em of C] {entitynoatt={C1}{Entity C\_1}};
\pic[below left=2ex and 7em of C] {entitynoatt={C2}{Entity C\_2}};
\pic at (C1.north east){is in=30};
\pic at (C2.south east){is in=-30};
\draw[one to omany] (A) edge (AB);
\draw[one to omany] (B) edge (AB);
\draw[one to one] (B) edge (C);
\path[one to oone,zig zag] (C1) edge (C);
\path[one to oone,zig zag] (C2) edge (C);%
\end{tikzpicture}
\end{center}
\end{document}
使用 www.DeepL.com/Translator 翻译