我发现这发布了有关如何使用 Tikz 制作鱼尾纹 ERM 图的帖子,但由于实体在框架之外,因此看起来很奇怪。不过,它确实有效。
然后我发现这甚至更好的版本,并尝试将其组合起来,但遗憾的是我无法找出它不起作用的原因。我无法并排打印两个实体并用乌鸦脚线将它们连接起来。它们总是互相打印……
怎样才能兼具线条与风格?
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{shapes.multipart}
\usetikzlibrary{matrix}
\usetikzlibrary{positioning}
\usetikzlibrary{shadows}
\usetikzlibrary{calc}
\tikzset{
entity/.code={
\tikzset{
rounded corners,
name=#1,
inner sep=2pt,
every entity/.try,
}%
\def\entityname{#1}%
},
entity anchor/.style={matrix anchor=#1},
every entity/.style={
draw,
},
every property/.style={
inner xsep=0.20cm, inner ysep=0.075cm, anchor=west, text width=1.75in
}
}
\def\property#1{\node[name=\entityname-#1, every property/.try]{\propertysplit#1;};}
\def\properties{\begingroup\catcode`\_=11\relax\processproperties}
\def\processproperties#1{\endgroup%
\gdef\propertycode{}%
\foreach \p in {#1}{%
\expandafter\expandafter\expandafter\gdef\expandafter\expandafter\expandafter\propertycode%
\expandafter\expandafter\expandafter{\expandafter\propertycode\expandafter\property\expandafter{\p}\\}%
}%
\propertycode%
}
\def\propertysplit#1:#2;{#1:\hfill#2}
\def\entitynamenode{%
\node[every entity name/.try] (\entityname-name) {\entityname};
\draw (\entityname-name.south west) -- (\entityname-name.south east);
\\[1ex]
}
\tikzset{
every entity name/.style={every property/.try, align=center}
}
\begin{document}
\begin{tikzpicture}[every node/.style={font=\ttfamily}, node distance=0.5in]
\matrix (m1) [entity=Employee] {
\entitynamenode
\properties{
Username:,
Password : varchar(255),
Name : varchar(255),
LastName : varchar(255)
}
};
\matrix (m2) [entity=Student] {
\entitynamenode
\properties{
Username:,
Password : varchar(255),
Name : varchar(255),
LastName : varchar(255)
}
};
\draw [->] (m1) -- (m2); % <-- it break's here...
%\draw [one to omany] (Employee-Username:) to node[above]{label} (Student-Username:);
\end{tikzpicture}
\end{document}
编辑:这是用于可视化 IT 数据库结构的鱼尾纹符号:
答案1
由于您的 MWE 超出了我的知识水平,因此我提出了一个带有pic
(entity
)的解决方案tabular
。
的参数pic
有 3 个:节点名称、实体名称和行tabular
(将完整名称作为第三个参数可能更优雅tabular
,在这种情况下,您可以定义两种新的列类型以避免一直输入它们)。
等的代码one to many
取自你链接的其中一篇帖子。
我添加了另一个实体只是为了表明实体的大小根据您放入的行数而变化tabular
。
\documentclass{article}
\usepackage{array}
\renewcommand{\arraystretch}{1.1}
\usepackage{tikz}
\usetikzlibrary{shapes.multipart}
\usetikzlibrary{positioning}
\usetikzlibrary{shadows}
\usetikzlibrary{calc}
% 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%
%\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%
}
\makeatother
\tikzset{%
pics/entity/.style n args={3}{code={%
\node[draw, blue,
shade, top color=white, bottom color=blue!30,
drop shadow={gray!70,
shadow xshift=3pt,
shadow yshift=-3pt,
rounded corners},
rounded corners,
font=\ttfamily\footnotesize,
rectangle
] (#1)
{\color{black}\begin{tabular}{>{\raggedright\arraybackslash}p{4.5em}>{\raggedleft\arraybackslash}p{6em}}
#3
\end{tabular}
};%
\node[font=\ttfamily\footnotesize,
text height=1.5ex,text depth=.25ex,
above =0pt of #1
]
{#2};%
}},
pics/entitysimple/.style n args={3}{code={%
\node[draw, rounded corners,
rectangle split,
rectangle split parts=2,
font=\ttfamily\footnotesize,
text height=1.5ex,text depth=.25ex
] (#1)
{#2 \nodepart{second}
\begin{tabular}{>{\raggedright\arraybackslash}p{4.5em}>{\raggedleft\arraybackslash}p{6em}}
#3
\end{tabular}
};%
}},
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
},
}
\begin{document}
\noindent Version like your colored image:
\begin{center}
\begin{tikzpicture}
\pic {entity={empl}{Employee}{%
Username: & \textcolor{red}{(PK)} \\
Password: & varchar(255) \\
Name: & varchar(255) \\
LastName: & varchar(255) \\
}};
\pic[right=7em of empl] {entity={stud}{Student}{%
Username: & \textcolor{red}{(PK)} \\
Password: & varchar(255) \\
Name: & varchar(255) \\
LastName: & varchar(255) \\
}};
\pic[below=12ex of stud] {entity={thesis}{Thesis}{%
Title: & \textcolor{red}{(PK)} \\
Year: & numeric(4) \\
}};
\draw[one to omany] ($(empl.north east)-(0,10pt)$) -- node[above]{\footnotesize\texttt{teaches}} ($(stud.north west)-(0,10pt)$);
\draw[one to one] ($(stud.south)+(50pt,0)$) -- node[left]{\footnotesize\texttt{writes}} ($(thesis.north)+(50pt,0)$);
\draw[one to many] ($(empl.south)+(30pt,0)$) |- node[left, yshift=36pt] {\footnotesize\texttt{supervises}} ($(thesis.west)+(0,4pt)$);
\end{tikzpicture}
\end{center}
Version like your code:
\begin{center}
\begin{tikzpicture}
\pic {entitysimple={empl}{Employee}{%
Username: & \textcolor{red}{(PK)} \\
Password: & varchar(255) \\
Name: & varchar(255) \\
LastName: & varchar(255) \\
}};
\pic[right=7em of empl] {entitysimple={stud}{Student}{%
Username: & \textcolor{red}{(PK)} \\
Password: & varchar(255) \\
Name: & varchar(255) \\
LastName: & varchar(255) \\
}};
\pic[below=12ex of stud] {entitysimple={thesis}{Thesis}{%
Title: & \textcolor{red}{(PK)} \\
Year: & numeric(4) \\
}};
\draw[one to omany] (empl.east) -- node[above]{\footnotesize\texttt{teaches}} (stud.west);
\draw[one to one] (stud.south) -- node[left]{\footnotesize\texttt{writes}} (thesis.north);
\draw[one to many] (empl.south) |- node[left, yshift=44pt, xshift=-2pt] {\footnotesize\texttt{supervises}} (thesis.west);
\end{tikzpicture}
\end{center}
\end{document}