Diagrama TikZ ER - impedindo que relações sejam desenhadas entre células

Diagrama TikZ ER - impedindo que relações sejam desenhadas entre células

Eu adaptei o códigodesta postagem

O problema que estou tendo é que as relações (linhas) entre as tabelas estão cruzando as tabelas em vez de contorná-las.

O MWE é bastante longo, mas aqui está:

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

Aqui está uma imagem do problema (que pode ser mais clara instantaneamente) -

insira a descrição da imagem aqui

Não tenho certeza de como impedir que as linhas passem pelas caixas da maneira que estão atualmente. Não consigo encontrar um valor para alterar que impeça esse comportamento.

Por outro lado - fazer isso parece bastante trabalhoso. Se houver alguma sugestão de outras pessoas para métodos alternativos, ficarei feliz em ouvir

obrigado

Responder1

Esta é uma solução possível. O zig zag toestilo é definido como um valor padrão de 0,5 por

zig zag to/.default=0.5

além disso, one to manye os dois estilos a seguir também usam esse valor padrão que causa erros. Esta proposta remove o zig zag tona one to manydefinição de estilo, portanto não utiliza

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

sintaxe nos drawcomandos. Mas, em vez disso, use aquelas habilidades de desenho de coordenadas relativas e ortogonais frequentemente vistas.

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

porque os rótulos internos (<start>)e (<end>)ainda são válidos, contendo coordenadas locais.

insira a descrição da imagem aqui

Código

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

Responder2

Você zig zag tofunciona bem apenas entre pontos com xcoordenadas diferentes.

Você pode definir outro estilo, por exemplo, zig zig toque funcione bem para pontos iguais xe usá-lo para definir new one to many bis.

Eu mudei one to manyadicionando acesso ao parâmetro de zig zag to. Desta forma, as bordas não se sobrepõem.

Aqui está o código:

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

insira a descrição da imagem aqui

informação relacionada