TikZ ER 图 - 阻止跨单元格绘制关系

TikZ ER 图 - 阻止跨单元格绘制关系

我已经调整了代码来自这篇文章

我遇到的问题是表格之间的关系(线)跨越表格而不是绕过表格。

MWE 很长,但如下所示:

\documentclass[border=0.25in]{standalone}

\usepackage{tikz}
\usetikzlibrary{shapes.multipart}
\usetikzlibrary{matrix}
\usetikzlibrary{positioning}
\usetikzlibrary{shadows}
\usetikzlibrary{calc}

\makeatletter
\pgfarrowsdeclare{crow's foot}{crow's foot}
{
  \pgfarrowsleftextend{+-.5\pgflinewidth}%
  \pgfarrowsrightextend{+.5\pgflinewidth}%
}
{
  \pgfutil@tempdima=0.5pt%
  \advance\pgfutil@tempdima by.25\pgflinewidth%
  \pgfsetdash{}{+0pt}%
  \pgfsetmiterjoin%
  \pgfpathmoveto{\pgfqpoint{0pt}{-6\pgfutil@tempdima}}%
  \pgfpathlineto{\pgfqpoint{-6\pgfutil@tempdima}{0pt}}%
  \pgfpathlineto{\pgfqpoint{0pt}{6\pgfutil@tempdima}}%
  \pgfusepathqstroke%
}


\tikzset{
    entity/.code={
        \tikzset{
            label=above:#1,
            name=#1,
            inner sep=0pt,
            every entity/.try,
            fill=white,
            general shadow={
                shadow xshift=0.0625in,
                shadow yshift=-0.0625in,
                opacity=0.5,
                fill=black!50
            }
        }%
        \def\entityname{#1}%
    },
    entity anchor/.style={matrix anchor=#1.center},
    every entity/.style={
            draw,
    },
    every property/.style={
        inner xsep=0.25cm, inner ysep=0.125cm, anchor=west, text width=1.5in
    },
    zig zag to/.style={
        to path={(\tikztostart) -| ($(\tikztostart)!#1!(\tikztotarget)$) |- (\tikztotarget)}
    },
    zig zag to/.default=0.5,
    one to many/.style={
        -crow's foot, zig zag to
    },
    many to one/.style={
        crow's foot-, 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{tikzpicture}[every node/.style={font=\ttfamily}, node distance=1.25in]

\matrix [entity=Order Form, entity anchor=Order Form-Order ID -> PK]  {
    \properties{
        Order ID -> PK, 
        Cust ID -> FK,
        Order Date
    }
};

\matrix  [entity=Product Table, right=of Order Form-Order ID -> PK, entity anchor=Product Table-Vinyl ID -> PK]  {
    \properties{
        Vinyl ID -> PK,
        title,
        release year,
        record lbl,
        artist,
        album / single,
        cost price,
        Supplier ID -> FK,
        Retail Price,
        Reorder Lvl,
        Stock Lvl
    }
};

\matrix  [entity=Supplier Table, below=of Product Table, entity anchor=Supplier Table-Supplier ID -> PK]  {
    \properties{
        Supplier ID -> PK,
        Supplier Name,
        Sup Add 1,
        Sup Add 2,
        Sup Add 3      
    }
};

\matrix  [entity=Order Details, left=of Supplier Table, entity anchor=Order Details-Vinyl ID -> FK]  {
    \properties{
        Vinyl ID -> FK,
        Order ID -> FK,
        Quantity
    }
};


\matrix  [entity=Customer Table, below=of Supplier Table, entity anchor=Customer Table-Cust ID]  {
    \properties{
        Cust ID,
        First Name,
        Surname,
        Email,
        Postcode,
        Add. Line 1,
        Add. Line 2,
        Add. Line 3
    }
};

\draw [one to many] (Product Table-Vinyl ID -> PK) to (Order Details-Vinyl ID -> FK);
\draw [one to many] (Order Form-Order ID -> PK)   to (Order Details-Order ID -> FK);
\draw [one to many] (Customer Table-Cust ID) to (Order Form-Cust ID -> FK);
\draw [one to many] (Supplier Table-Supplier ID -> PK)  to (Product Table-Supplier ID -> FK);
\end{tikzpicture}

\end{document}

这是问题的图像(可能更清楚) -

在此处输入图片描述

我不知道如何阻止线条以目前的方式越过方框。我找不到可以更改的值来阻止此行为。

顺便说一句,这样做似乎相当耗费人力,如果其他人有其他方法的建议,我会很高兴听到

谢谢

答案1

这是一个可能的解决方案。zig zag to样式设置为默认值 0.5,方法是

zig zag to/.default=0.5

此外,one to many以下两种样式也使用该默认值,这会导致错误。本提案删除了样式定义zig zag to中的one to many,因此不使用

\draw (<start>) to (<end>)

命令中的语法draw。而是使用那些常见的相对和正交坐标绘图技巧。

\draw (<start>) --++(x,0) |- (<end>);

因为内部标签(<start>)(<end>)仍然有效,包含局部坐标。

在此处输入图片描述

代码

\documentclass[border=0.25in]{standalone}

\usepackage{tikz}
\usetikzlibrary{shapes.multipart}
\usetikzlibrary{matrix}
\usetikzlibrary{positioning}
\usetikzlibrary{shadows}
\usetikzlibrary{calc}

\makeatletter
\pgfarrowsdeclare{crow's foot}{crow's foot}
{
  \pgfarrowsleftextend{+-.5\pgflinewidth}%
  \pgfarrowsrightextend{+.5\pgflinewidth}%
}
{
  \pgfutil@tempdima=0.5pt%
  \advance\pgfutil@tempdima by.25\pgflinewidth%
  \pgfsetdash{}{+0pt}%
  \pgfsetmiterjoin%
  \pgfpathmoveto{\pgfqpoint{0pt}{-6\pgfutil@tempdima}}%
  \pgfpathlineto{\pgfqpoint{-6\pgfutil@tempdima}{0pt}}%
  \pgfpathlineto{\pgfqpoint{0pt}{6\pgfutil@tempdima}}%
  \pgfusepathqstroke%
}
\makeatother

\tikzset{
    entity/.code={
        \tikzset{
            label=above:#1,
            name=#1,
            inner sep=0pt,
            every entity/.try,
            fill=white,
            general shadow={
                shadow xshift=0.0625in,
                shadow yshift=-0.0625in,
                opacity=0.5,
                fill=black!50
            }
        }%
        \def\entityname{#1}%
    },
    entity anchor/.style={matrix anchor=#1.center},
    every entity/.style={
            draw,
    },
    every property/.style={
        inner xsep=0.25cm, inner ysep=0.125cm, anchor=west, text width=1.5in
    },
    zig zag to/.style={
        to path={(\tikztostart) -| ($(\tikztostart)!#1!(\tikztotarget)$) |- (\tikztotarget)}
    },
    zig zag to/.default=0.5,
    one to many/.style={
        -crow's foot, % zig zag to  % disable this `zig zag to` command by mark it out
    },
    many to one/.style={
        crow's foot-, 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{tikzpicture}[every node/.style={font=\ttfamily}, node distance=1.25in]

\matrix [entity=Order Form, entity anchor=Order Form-Order ID -> PK]  {
    \properties{
        Order ID -> PK, 
        Cust ID -> FK,
        Order Date
    }
};

\matrix  [entity=Product Table, right=of Order Form-Order ID -> PK, entity anchor=Product Table-Vinyl ID -> PK]  {
    \properties{
        Vinyl ID -> PK,
        title,
        release year,
        record lbl,
        artist,
        album / single,
        cost price,
        Supplier ID -> FK,
        Retail Price,
        Reorder Lvl,
        Stock Lvl
    }
};

\matrix  [entity=Supplier Table, below=of Product Table, entity anchor=Supplier Table-Supplier ID -> PK]  {
    \properties{
        Supplier ID -> PK,
        Supplier Name,
        Sup Add 1,
        Sup Add 2,
        Sup Add 3      
    }
};

\matrix  [entity=Order Details, left=of Supplier Table, entity anchor=Order Details-Vinyl ID -> FK]  {
    \properties{
        Vinyl ID -> FK,
        Order ID -> FK,
        Quantity
    }
};


\matrix  [entity=Customer Table, below=of Supplier Table, entity anchor=Customer Table-Cust ID]  {
    \properties{
        Cust ID,
        First Name,
        Surname,
        Email,
        Postcode,
        Add. Line 1,
        Add. Line 2,
        Add. Line 3
    }
};

\draw [one to many] (Product Table-Vinyl ID -> PK) --++(-2.7,0) |-  (Order Details-Vinyl ID -> FK);
\draw [one to many] (Order Form-Order ID -> PK)   --++(-3,0) |- (Order Details-Order ID -> FK);
\draw [one to many] (Customer Table-Cust ID) --++(-2.7,0) |-(Order Form-Cust ID -> FK);
\draw [one to many] (Product Table-Supplier ID -> FK) --++(3,0) |- (Supplier Table-Supplier ID -> PK) ;
\end{tikzpicture}

\end{document}

答案2

您的zig zag to作品仅在具有不同x坐标的点之间有效。

您可以定义另一种样式,例如zig zig to,适用于相同的点x,并使用它来定义新的one to many bis

one to many通过添加对 参数的访问进行了更改zig zag to。这样边缘就不会重叠。

以下是代码:

\documentclass[border=0.25in]{standalone}

\usepackage{tikz}
\usetikzlibrary{shapes.multipart}
\usetikzlibrary{matrix}
\usetikzlibrary{positioning}
\usetikzlibrary{shadows}
\usetikzlibrary{calc}

\makeatletter
\pgfarrowsdeclare{crow's foot}{crow's foot}
{
  \pgfarrowsleftextend{+-.5\pgflinewidth}%
  \pgfarrowsrightextend{+.5\pgflinewidth}%
}
{
  \pgfutil@tempdima=0.5pt%
  \advance\pgfutil@tempdima by.25\pgflinewidth%
  \pgfsetdash{}{+0pt}%
  \pgfsetmiterjoin%
  \pgfpathmoveto{\pgfqpoint{0pt}{-6\pgfutil@tempdima}}%
  \pgfpathlineto{\pgfqpoint{-6\pgfutil@tempdima}{0pt}}%
  \pgfpathlineto{\pgfqpoint{0pt}{6\pgfutil@tempdima}}%
  \pgfusepathqstroke%
}


\tikzset{
    entity/.code={
        \tikzset{
            label=above:#1,
            name=#1,
            inner sep=0pt,
            every entity/.try,
            fill=white,
            general shadow={
                shadow xshift=0.0625in,
                shadow yshift=-0.0625in,
                opacity=0.5,
                fill=black!50
            }
        }%
        \def\entityname{#1}%
    },
    entity anchor/.style={matrix anchor=#1.center},
    every entity/.style={
            draw,
    },
    every property/.style={
        inner xsep=0.25cm, inner ysep=0.125cm, anchor=west, text width=1.5in
    },
    zig zag to/.style={
        to path={(\tikztostart) -| ($(\tikztostart)!#1!(\tikztotarget)$) |- (\tikztotarget)}
    },
    zig zag to/.default=0.5,
    zig zig to/.style={
        to path={(\tikztostart) -| ++(#1,0) |- (\tikztotarget)}
    },
    zig zig to/.default=2.5cm,
    one to many/.style={
        -crow's foot, zig zag to=#1
    },
    one to many bis/.style={
        -crow's foot, zig zig to=#1
    },
    many to one/.style={
        crow's foot-, zig zig to=#1
    },
    many to many/.style={
        crow's foot-crow's foot, zig zag to=#1
    }
}
\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{tikzpicture}[every node/.style={font=\ttfamily}, node distance=1.25in]

\matrix [entity=Order Form, entity anchor=Order Form-Order ID -> PK]  {
    \properties{
        Order ID -> PK,
        Cust ID -> FK,
        Order Date
    }
};

\matrix  [entity=Product Table, right=of Order Form-Order ID -> PK, entity anchor=Product Table-Vinyl ID -> PK]  {
    \properties{
        Vinyl ID -> PK,
        title,
        release year,
        record lbl,
        artist,
        album / single,
        cost price,
        Supplier ID -> FK,
        Retail Price,
        Reorder Lvl,
        Stock Lvl
    }
};

\matrix  [entity=Supplier Table, below=of Product Table, entity anchor=Supplier Table-Supplier ID -> PK]  {
    \properties{
        Supplier ID -> PK,
        Supplier Name,
        Sup Add 1,
        Sup Add 2,
        Sup Add 3
    }
};

\matrix  [entity=Order Details, left=of Supplier Table, entity anchor=Order Details-Vinyl ID -> FK]  {
    \properties{
        Vinyl ID -> FK,
        Order ID -> FK,
        Quantity
    }
};


\matrix  [entity=Customer Table, below=of Supplier Table, entity anchor=Customer Table-Cust ID]  {
    \properties{
        Cust ID,
        First Name,
        Surname,
        Email,
        Postcode,
        Add. Line 1,
        Add. Line 2,
        Add. Line 3
    }
};

\draw [one to many=.45 ] (Product Table-Vinyl ID -> PK) to (Order Details-Vinyl ID -> FK);
\draw [one to many bis=-3cm] (Order Form-Order ID -> PK)   to (Order Details-Order ID -> FK);
\draw [one to many] (Customer Table-Cust ID) to (Order Form-Cust ID -> FK);
\draw [one to many bis=3cm] (Supplier Table-Supplier ID -> PK)  to (Product Table-Supplier ID -> FK);
\end{tikzpicture}

\end{document}

在此处输入图片描述

相关内容