# Drawing a complete ER Diagram in Crow's foot style by TikZ

I need to draw a ER digram in Crow's foot style in LaTeX. After some search I found:

Creating crow's foot style E-R diagrams, rather than Chen-style ones

However, I found this style was not "complete" for me. I need to write down the "verb" between two tables and indicate both primary key (PK) and foreign key (FK) of the table. This red text on the uploaded image shown what I need.

After some coding I was only able to create some new relationship such as "1:zero,one, or many". But I was puzzled by inserting text as there are no any nodes. Appreciate for any help. Thanks you.

The best attempt I have is:

\documentclass[12pt]{article}

\usepackage{tikz}
\usetikzlibrary{shapes.multipart}
\usetikzlibrary{matrix}
\usetikzlibrary{positioning}
\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%
\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%
}

\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,
}
};

\draw [one to omany] (MEMBER-MID) to (TABLE-TID);

\end{tikzpicture}
%\end{landscape}

\end{document}

• Welcome to TeX.SX! – Herr K. Nov 1 '13 at 17:02
• Thank you, this is my first question after browsing thousands of questions in TeX.SX. :D – Travis Nov 1 '13 at 17:05

To get the nodes, normally you would simply put a node[above]{has} after the to. However, in this case, the zig zag to style redefines the to path, leaving out any nodes on the path. So that is the first thing we will need to change.

Change the style

zig zag to/.style={
to path={(\tikztostart) -| ($(\tikztostart)!#1!(\tikztotarget)$) |- (\tikztotarget)}
},


to

zig zag to/.style={
to path={(\tikztostart) -| ($(\tikztostart)!#1!(\tikztotarget)$) |- (\tikztotarget) \tikztonodes}
},


Then you can simply write \draw [one to omany] (MEMBER-MID) to node[above]{has} (TABLE-TID); to get the verb above the relationship.

Second, the primary and foreign key indication. The simplest way here is to specify them separately. That is, don't include them in the properties macro, but write two separate macros to handle them instead. You could add the following definitions for them to the preamble:

\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)};\\}


Finally the document itself would then look like this:

\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,

• Your coding was just amazing! Transforming to node make it easier for me to code. :D Forget to mention I need to underline the PK, but based on your coding, I simply add \uline` in the PK node to get it done. – Travis Nov 3 '13 at 17:29