Диаграмма 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}

введите описание изображения здесь

Связанный контент