Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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.

The wanted ERD

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{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}
share|improve this question
    
Welcome to TeX.SX! –  Kevin C 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

1 Answer 1

up vote 3 down vote accepted

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

\draw [one to omany] (MEMBER-MID) to node[above]{label} (TABLE-TID);

\end{tikzpicture}
\end{document}

This should give you output that looks like the image you provided. I haven't tested it with anything outside of your MWE, but I don't see any glaring issues with it.

share|improve this answer
    
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

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.