我發現這關於如何使用 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
取自您連結的帖子之一。
我添加了另一個實體,只是為了表明該實體的大小會根據您放入 .txt 檔案中的行數而變化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}