使用 TikZ 绘制完整的鱼尾纹 ER 图

使用 TikZ 绘制完整的鱼尾纹 ER 图

我需要在 LaTeX 中绘制鱼尾纹风格的 ER 图。经过一番搜索,我发现:

创建鱼尾纹风格的 ER 图,而不是陈式 ER 图

但是,我发现这种风格对我来说并不“完整”。我需要写下两个表之间的“动词”,并指明表的主键 (PK) 和外键 (FK)。上传图片上的红色文本显示了我需要的内容。

所需的 ERD

经过一些编码后,我只能创建一些新的关系,例如“1:零、一或多”。但是我对插入文本感到困惑,因为没有任何节点。感谢您的帮助。谢谢。

我所做的最好的尝试是:

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

答案1

要获取节点,通常只需node[above]{has}在 后面放置一个to。但是,在这种情况下,样式zig zag to重新定义了to path,忽略了路径上的任何节点。所以这是我们需要更改的第一件事。

更改样式

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

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

然后,您只需简单地写下来\draw [one to omany] (MEMBER-MID) to node[above]{has} (TABLE-TID); 即可获得关系上方的动词。

第二,主键和外键指示。这里最简单的方法是分别指定它们。也就是说,不要将它们包含在宏中properties,而是编写两个单独的宏来处理它们。您可以在序言中添加以下定义:

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

最后文档本身看起来会像这样:

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

这应该会给你提供类似于你提供的图像的输出。我还没有用你的 MWE 之外的任何东西测试过它,但我没有发现任何明显的问题。

相关内容