11

I'm trying to draw a database dependency diagram, similar to the one shown below

(Gaaah! I can't upload images. ASCII art it is then...)

  +------+------+------+------+------+------+
  |      |      |      |      |      |      |
  |      v      |      v      v      v      v
+---+  +---+  +---+  +---+  +---+  +---+  +---+      Lines extend from 1 and 3,
| 1 |  | 2 |  | 3 |  | 4 |  | 5 |  | 6 |  | 7 |      join above 2, and then route
+---+  +---+  +---+  +---+  +---+  +---+  +---+      to all other blocks

I've managed to get the easy bits done, namely drawing the blocks. I assume that I need to create a number of control points that the arrows must move through to 'raise' them above the nodes. What I can't get is to have them drawn nice and square.

Source diagram

Theres also the problem of the junction point above PROJ_NAME (block 2). PROJ_NUM (block 1) and EMP_NUM (block 3) together form a junction, and this junction joins to all the others. My Tikz attempt (although visually very far from what I want) illustrates this (I think?)

Please could someone point me in the right direction? Am I on the right track, is there a way easier method of doing this?

\tikzstyle{line} = [draw, -latex']
\tikzstyle{block} = [rectangle, draw, text centered, rounded corners, 
    minimum height=1.5em,font=\tiny]
\tikzstyle{cntrl} = [node distance=2em, minimum height=0]

\begin{tikzpicture}
    [shorten >=1pt,node distance=0.1em,auto,scale=0.5]        

    \node[block]    (n1)                     {PROJ\_NUM};
    \node[block]    (n2)  [right =of n1]     {PROJ\_NAME};
    \node[block]    (n3)  [right =of n2]     {EMP\_NUM};                                         
    \node[block]    (n4)  [right =of n3]     {EMP\_NAME};
    \node[block]    (n5)  [right =of n4]     {JOB\_CLASS};
    \node[block]    (n6)  [right =of n5]     {CHG\_HOUR};
    \node[block]    (n7)  [right =of n6]     {HOURS};

    \node[cntrl]    (i1)     [above =of n1]                  {};
    \node[cntrl]    (i2)     [above =of n2]                  {};
    \node[cntrl]    (i3)     [above =of n3]                  {};
    \node[cntrl]    (i4)     [above =of n4]                  {};
    \node[cntrl]    (i5)     [above =of n5]                  {};
    \node[cntrl]    (i6)     [above =of n6]                  {};
    \node[cntrl]    (i7)     [above =of n7]                  {};

    \path [line] (n1) .. controls (i1) and (i2) .. (n2);
    \path [line] (n3) .. controls (i3) and (i2) .. (n2);
    \path [line] (i2) .. controls (i2) and (i4) .. (n4);
    \path [line] (i2) .. controls (i2) and (i5) .. (n5);
    \path [line] (i2) .. controls (i2) and (i6) .. (n6);
    \path [line] (i2) .. controls (i2) and (i7) .. (n7);

\end{tikzpicture}    

Links to diagrams that I uploaded. Hopefully the links remain active..

Attempt so far: Tikz attempt so far

10

I read about the rectangle split node yesterday, so this was a chance to experiment. The code is far from perfect, but a good starting point:

\documentclass[parskip]{scrartcl}
\usepackage[margin=15mm,landscape]{geometry}
\usepackage{tikz}
\usetikzlibrary{shapes.multipart, calc}

\begin{document}
\begin{tikzpicture}[my shape/.style={
rectangle split, rectangle split parts=#1, draw, anchor=center}]
\node [my shape=7, rectangle split horizontal,name=dedi, rectangle split part fill={olive!50, blue!70, olive!50, blue!70}]  at (0,0)
{PROJ\_NUM%
\nodepart{two}   PROJ\_NAME
\nodepart{three} EMP\_NUM
\nodepart{four}  EMP\_NAME
\nodepart{five}  JOB\_CLASS
\nodepart{six}   CHG\_HOUR
\nodepart{seven} HOURS};

\draw[latex-latex, very thick, red!70!black] (dedi.two north) -- ++(0,1) -| (dedi.four north);
\draw[latex-latex, very thick, red!70!black] (dedi.five north) -- ++(0,1) -| (dedi.four north);
\draw[latex-latex, very thick, red!70!black] (dedi.six north) -- ++(0,1) -| (dedi.four north);
\draw[latex-latex, very thick, red!70!black] (dedi.seven north) -- ++(0,1) -| (dedi.four north);
\draw[very thick, red!70!black]              (dedi.one north) -- ++(0,0.5) -| (dedi.three north);
\draw[-latex, very thick, red!70!black]      (dedi.one south) -- ++(0,-0.5) node[below right, text width=3cm] {\scriptsize partial dependancy} -| (dedi.two south);
\draw[-latex, very thick, red!70!black]      ($(dedi.five south) + (0.2,0)$) -- ++(0,-0.5) node[below right, text width=2cm] {\scriptsize Transitive dependancy} -| ($(dedi.six south) + (-0.2,0)$);
\draw[-latex, very thick, red!70!black] (dedi.three south) -- ++(0,-2) -| (dedi.four south);
\draw[-latex, very thick, red!70!black] (dedi.three south) -- ++(0,-2) -| (dedi.five south);
\draw[-latex, very thick, red!70!black] (dedi.three south) -- ++(0,-2) -| node[below left] {\scriptsize partial dependancies} (dedi.six south);
\draw[-latex, very thick, red!70!black] (dedi.three south) -- ++(0,-2) -| (dedi.seven south);

\end{tikzpicture}
\end{document}

enter image description here

8

Have you seen the announcement of the tikz-dependency package in comp.text.tex?

http://www.ctan.org/pkg/tikz-dependency

  • No, I wasn't aware of the package. Not quite want I want for this scenario, but good to know anyway. Thanks! – His Royal Redness Jan 21 '12 at 9:13
3

for fun and exercise ...

pure tikz solution:

\documentclass[tikz,margin=3mm]{standalone}
\usetikzlibrary{arrows.meta, chains, positioning, shadows}

\begin{document}
    \begin{tikzpicture}[
node distance = 7mm and 0mm,
  start chain = A going right,
   box/.style = {rectangle, draw, fill=#1,
                 minimum height=7mm, outer sep=0pt,
                 font=\bfseries\sffamily, text=white,
                 drop shadow, on chain=A},
   box/.default = black!30!blue!50,
   lbl/.style = {anchor=north, align=center, inner ysep=2pt,
                 font=\sffamily\footnotesize\linespread{0.8}\selectfont},
   arr/.style = {draw=purple, -Triangle, ultra thick},
every edge/.style = {arr}
                        ]
\node [box=olive]   {PROJ\_NUM};    % A-1
\node [box]         {PROJ\_NAME};
\node [box=olive]   {EMP\_NUM};
\node [box]         {EMP\_NAME};
\node [box]         {JOB\_CLASS};
\node [box]         {CHG\_HOUR};
\node [box]         {HOURS};        % A-7
    \coordinate[above=of A-2]   (aux1);
    \coordinate[above=of aux1]  (aux2);
    \coordinate[below=of A-2]   (aux3);
    \coordinate[below=of aux3]  (aux4);
% arrows above nodes
\draw[arr]  (A-1)   |- (aux1) -| (A-3);
\draw[arr]  (aux2) -| (A-7);
\draw       (aux2)        edge (A-2)
            (aux2 -| A-4) edge (A-4)
            (aux2 -| A-5) edge (A-5)
            (aux2 -| A-6) edge (A-6);
% arrows below nodes
\draw[arr]  (A-1) |- node[lbl,pos=0.75] {Partial\\ dependancy} (aux3) -- (A-2);
\draw[arr]  (A-3) -- (A-3 |- aux4) -| node[lbl,pos=0.25] {Partial dependancy} (A-7);
\draw       (aux4 -| A-4) edge (A-4)
            (aux4 -| A-5) edge (A-5)
            (aux4 -| A-6) edge (A-6);
\draw[arr]  ([xshift= 5mm] A-5.south) -- ([xshift= 5mm] A-5.south |- aux3) -|
        node[lbl,pos=0.25] {Transitive\\ dependancy}
            ([xshift=-5mm] A-6.south);
    \end{tikzpicture}
\end{document}

enter image description here

1

The style used in Fundamentals of Database Systems by Elmasri and Navathe (ISBN-10: 0136086209) to draw functional dependencies is the following:

enter image description here

It is relatively easy to reproduce using tikz-dependency:

\documentclass[border=20pt]{standalone}
\renewcommand\familydefault{\sfdefault}
\usepackage{tikz-dependency}
\begin{document}

\depstyle{lvl}{%
    edge height=2.5ex,
    % edge unit distance=#1*2.5ex, % Another way of controlling the appearance of the edges.
    edge below,
    edge horizontal padding=0,
    edge vertical padding=(#1-1)*3ex,
    text only label, % No need for label for functional dependencies.
    edge slant=0, % Right angles
    rounded corners=0,
    edge style={>=triangle 60} % Change the style of the arrowheads.
}
\tikzset{
    matrix/.append style={column sep=0.4cm} % Adding some distance between the attributes.
}
\tikzstyle{TxtBook}=[% Style to mimic the textbook Fundamentals of Database Systems.
    column sep=0cm, % No distance between two attributes.
    nodes={%
        fill=gray!20,
        draw=black,
        inner xsep=3ex,
        inner ysep=1ex
    }
]


\begin{dependency}
    \begin{deptext}
        Ename \& \underline{Ssn} \& BDate \& Address \& Dnumber \& Dname \& Dmgr\_ssn \\
    \end{deptext}
    \depedge[lvl=1]{2}{1}{} % Edge are organized by level.
    \depedge[lvl=1]{2}{3}{}
    \depedge[lvl=1]{2}{4}{}
    \depedge[lvl=1]{2}{5}{}
    \depedge[lvl=2]{5}{6}{}
    \depedge[lvl=2]{5}{7}{}
\end{dependency}


\begin{dependency}
    \begin{deptext}[TxtBook] % Applying the TxtBook style.
        \underline{Ssn} \& \underline{Pnumber} \& Hours \& Ename \& Pname \& Plocation \\
    \end{deptext}
    \depedge[lvl=1]{1}{3}{}
    \depedge[lvl=1]{2}{3}{}
    \depedge[lvl=2]{1}{4}{}
    \depedge[lvl=3]{2}{5}{}
    \depedge[lvl=3]{2}{6}{}
\end{dependency}

\end{document}

produces:

enter image description here

and (closer to the style used in the textbook)

enter image description here

If you are OK with editing the source code of tikz-dependency, you can even patch it as follow (compared with the version 1.2, available at http://ftp.math.purdue.edu/mirrors/ctan.org/graphics/pgf/contrib/tikz-dependency/tikz-dependency.sty ):

67a68,70
> % an explicit offset to compensate the y position of the edge
>    edge start y offset/.code = {\pgfmathsetlengthmacro{\dt@EdgeStartOffsetY}{#1}},
>    edge start y offset = 0,
281c284
<       \node (\dt@lastlabel-edge-origin) [coordinate] at ($(#2.\anchorpoint) + (\doff,\dt@startdist) + (\dt@EdgeStartOffsetX,0)$) {};
---
>       \node (\dt@lastlabel-edge-origin) [coordinate] at ($(#2.\anchorpoint) + (\doff,\dt@startdist) + (\dt@EdgeStartOffsetX,0) + (0,\dt@EdgeStartOffsetY)$) {};
283c286
<       \node (\dt@lastlabel-edge-second-corner) [coordinate] at ($(#3.\anchorpoint) + (\dt@EdgeEndOffsetX,0) + (-\dslant,\dt@enddist+\dt@startdist+\ydiff)$) {};
---
>       \node (\dt@lastlabel-edge-second-corner) [coordinate] at ($(#3.\anchorpoint) + (\dt@EdgeEndOffsetX,0) + (0,\dt@EdgeStartOffsetY) + (-\dslant,\dt@enddist+\dt@startdist+\ydiff)$) {};

and then replace in the previous example

edge vertical padding=(#1-1)*3ex,

with

edge start y offset=-(#1-1)*3ex,

to get

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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