3

To make schema diagram

enter image description here

I use following code

\documentclass[tikz,border=5pt]{standalone}
\usetikzlibrary{calc,positioning,shapes.multipart,shapes}
\begin{document}
\tikzset{basic/.style={
        draw,
        rectangle split,
        rectangle split parts=2,
        rectangle split part fill={blue!20,white},
        minimum width=2.5cm,
        text width=2cm,
        align=left,
        font=\itshape
    },
    Diamond/.style={ diamond, 
                        draw, 
                        shape aspect=2, 
                        inner sep = 2pt,
                        text centered,
                        fill=blue!10!white,
                        font=\itshape
                      }}
\begin{tikzpicture}
\node[basic] (instructor) {instructor
\nodepart{second}
\underline{ID}\\
name\\
dept\_name\\
salary};
\node[basic,right=5cm of instructor] (department) {department
\nodepart{second}
\underline{dept\_name}\\
building\\
budget};
\draw[->] ([yshift=-13pt]$(instructor.east)$) -- ([yshift=1pt]$(department.west)$);
\end{tikzpicture}
\end{document}

In line \draw[->] ([yshift=-13pt]$(instructor.east)$) -- ([yshift=1pt]$(department.west)$); I make a yshift. To do this edit the yshift value several time to fit the output with expectation. If I know the distance of each item in the diagram from the top or bottom I can easily make decision for yshift value just multiplication item no and distance.

Something like \draw[->] ([yshift=-((3.5*distance)pt]$(instructor.north)$) -- ([yshift=-(1.5*distance)pt]$(department.north)$);;

Or,

\draw[->] ([yshift=-((1.5*distance)pt]$(instructor.south)$) -- ([yshift=-(2.5*distance)pt]$(department.south)$);;

alhelal
  • 2,451

2 Answers2

2

The perhaps simplest way is to really make use of the node parts. UPDATE: Added the horizontal line. (Unfortunately, TikZ does not yet accept a list for the option rectangle split draw splits, while it does for rectangle split part fill, so I had to draw the line by other means.)

\documentclass[tikz,border=5pt]{standalone}
\usetikzlibrary{calc,positioning,shapes.multipart,shapes,backgrounds}
\pgfdeclarelayer{background}
\pgfdeclarelayer{foreground}
\pgfsetlayers{background,main,foreground}
\begin{document}
\tikzset{basic/.style={
        draw,alias=nahh,
        rectangle split,
        rectangle split parts=2,
        rectangle split part fill={blue!20,white},
        rectangle split draw splits=false,
        minimum width=2.5cm,
        text width=2cm,
        align=left,
        font=\itshape,
        draw,
        append after command={\pgfextra{\begin{pgfonlayer}{foreground}
        \draw(\tikzlastnode.text split west) -- (\tikzlastnode.text split  east);
        \end{pgfonlayer}
        }
        }
        },
    Diamond/.style={ diamond, 
                        draw, 
                        shape aspect=2, 
                        inner sep = 2pt,
                        text centered,
                        fill=blue!10!white,
                        font=\itshape,
                      }}

\begin{tikzpicture}
\node[basic,rectangle split parts=5] (instructor) {instructor
\nodepart[rectangle split draw splits=false]{second}
\underline{ID}
\nodepart{third}
name
\nodepart{fourth}
dept\_name
\nodepart{five} salary
};
\node[basic,right=5cm of instructor,rectangle split parts=4] (department) {department
\nodepart{second}
\underline{dept\_name}
\nodepart{third}
building
\nodepart{fourth}
budget};
\draw[->] (instructor.four east) -- (department.two west);
\end{tikzpicture}
\end{document}

enter image description here

UPDATE: Based on Ignasi's great answer and this answer. Yields the same output.

\documentclass[tikz,border=5pt]{standalone}
\usetikzlibrary{calc,positioning,shapes.multipart,shapes,backgrounds}
\makeatletter % from https://tex.stackexchange.com/a/88336/121799
\newcommand{\GetCurrentNodeName}{\tikz@fig@name}
\makeatother
\begin{document}
\tikzset{basic/.style={
        draw,
        rectangle split,
        rectangle split parts=2,
        rectangle split part fill={blue!20,white},
        rectangle split draw splits=false,
        minimum width=2.5cm,
        text width=2cm,
        align=left,
        font=\itshape,
        draw,
        },
    Line/.style={
        path picture={
            \draw (\GetCurrentNodeName.text split west) -- (\GetCurrentNodeName.text split east);
        }
        },  
    Diamond/.style={ diamond, 
                        draw, 
                        shape aspect=2, 
                        inner sep = 2pt,
                        text centered,
                        fill=blue!10!white,
                        font=\itshape,
                      }
        }

\begin{tikzpicture}
\node[basic, rectangle split parts=5, Line] (instructor) {instructor
\nodepart[rectangle split draw splits=false]{second}
\underline{ID}
\nodepart{third}
name
\nodepart{fourth}
dept\_name
\nodepart{five} salary
};
\node[basic,right=5cm of instructor,rectangle split parts=4, Line] (department) {department
\nodepart{second}
\underline{dept\_name}
\nodepart{third}
building
\nodepart{fourth}
budget};
\draw[->] (instructor.four east) -- (department.two west);
\end{tikzpicture}
\end{document}
  • I like this solution. Just add the horizontal line under the table name. It seems me better look. – alhelal Mar 30 '18 at 17:36
  • No problem. I am going to bed as it is mid-night. – alhelal Mar 30 '18 at 17:39
  • line under header you should draw separately. there (so far) not exist a way to incorporate it in basic style – Zarko Mar 30 '18 at 18:29
  • @Zarko I guess this is one more point on which we disagree. Still not too bad, 2 out of over one hundred ;-) Please see my update, everything is in basic style... ;-) –  Mar 31 '18 at 00:15
  • @marmot, bravo for foreground! i'm glad that we disagree :-). you solve some my old problem where i stuck since due to respect to percusse (https://tex.stackexchange.com/questions/231285/why-fill-covers-append-after-command-elements) i didn't start to search a solution. +1 :-) :-) :-). however, i hope that ones will done more native solution. this feature is really missing. – Zarko Mar 31 '18 at 00:24
  • @Zarko Well, I guess that we agree here? ;-) Anyway, thanks a lot! (I actually have used this trick already before but I don't remember where or if I posted an answer with that.) Anyway, thanks!!! ;-) –  Mar 31 '18 at 00:44
  • @marmot, of course wee agree. if you will have some spare time please see https://tex.meta.stackexchange.com/questions/7600/how-to-politely-tell-someone-that-his-choice-of-answer-is-poor. i had some problems with them, but i learned a lesson ;-). on the end all is up to op, what (s)he liked more no matter what I think about it. – Zarko Mar 31 '18 at 01:00
2

This is a complement to marmot's answer. May be a comment could be enough, but a little bit long.

In this case the line under instructor or department are drawn with a path picture command without \pgfextra commands.

It's not possible to use it inside a general style because we need to know nodes' name, therefore, a Line style has been defined and added to instructor and department nodes.

\documentclass[tikz,border=5pt]{standalone}
\usetikzlibrary{calc,positioning,shapes.multipart,shapes,backgrounds}
\pgfdeclarelayer{background}
\pgfdeclarelayer{foreground}
\pgfsetlayers{background,main,foreground}
\begin{document}
\tikzset{basic/.style={
        draw,alias=nahh,
        rectangle split,
        rectangle split parts=2,
        rectangle split part fill={blue!20,white},
        rectangle split draw splits=false,
        minimum width=2.5cm,
        text width=2cm,
        align=left,
        font=\itshape,
        draw,
        },
    Line/.style={
        path picture={
            \draw (#1.text split west) -- (#1.text split east);
        }
        },  
    Diamond/.style={ diamond, 
                        draw, 
                        shape aspect=2, 
                        inner sep = 2pt,
                        text centered,
                        fill=blue!10!white,
                        font=\itshape,
                      }
        }

\begin{tikzpicture}
\node[basic, rectangle split parts=5, Line=instructor] (instructor) {instructor
\nodepart[rectangle split draw splits=false]{second}
\underline{ID}
\nodepart{third}
name
\nodepart{fourth}
dept\_name
\nodepart{five} salary
};
\node[basic,right=5cm of instructor,rectangle split parts=4, Line=department] (department) {department
\nodepart{second}
\underline{dept\_name}
\nodepart{third}
building
\nodepart{fourth}
budget};
\draw[->] (instructor.four east) -- (department.two west);
\end{tikzpicture}
\end{document}

enter image description here

Update:

Thank you to one of percusse's answers my previous code can be simplified and define a basic style which already includes de path picture that draws the line on header.

As in path picture we need to know the name of the node, we can include the name option in the basic style. This way the parameter (node's name) is already known when path picture starts.

\documentclass[tikz,border=5pt]{standalone}
\usetikzlibrary{calc,positioning,shapes.multipart,shapes,backgrounds}
\pgfdeclarelayer{background}
\pgfdeclarelayer{foreground}
\pgfsetlayers{background,main,foreground}
\begin{document}
\tikzset{
    basic/.style={
        draw, 
      rectangle split,
      rectangle split parts=2,
      rectangle split part fill={blue!20,white},
      rectangle split draw splits=false,
      minimum width=2.5cm,
      text width=2cm,
      align=left,
      font=\itshape,
      name=#1,     %<-------- Node's name
      path picture={
            \draw (#1.text split west) -- (#1.text split east);
        }
    },
   Diamond/.style={ 
        diamond, 
      draw, 
      shape aspect=2, 
      inner sep = 2pt,
      text centered,
      fill=blue!10!white,
      font=\itshape,
    }
}

\begin{tikzpicture}
%There's no explicit name like in "\node (name) {}"
%Node's name is introduced as a parameter in basic style.
\node[basic=instructor, rectangle split parts=5] {instructor
\nodepart{second}
    \underline{ID}
\nodepart{third}
    name
\nodepart{fourth}
    dept\_name
\nodepart{five} salary
};

\node[basic=department, right=5cm of instructor, rectangle split parts=4] 
{department
\nodepart{second}
    \underline{dept\_name}
\nodepart{third}
    building
\nodepart{fourth}
    budget};

\draw[->] (instructor.four east) -- (department.two west);
\end{tikzpicture}
\end{document}
Ignasi
  • 136,588
  • Nice! +1. The only part I don't understand is why you pass the node name to Line=.... Wouldn't it be better to pass some information on where you want to draw the line, e.g. between one and two or between two and three, say? –  Apr 11 '18 at 19:29
  • @marmot Just because I don't know how to make reference to a certain anchor of current node without knowing node's name. I need to know node's name to say \draw(instructor.text split west). – Ignasi Apr 12 '18 at 07:24
  • @marmot I think the updated answer solve's the problem with node's name. – Ignasi Apr 12 '18 at 07:57
  • I added a simplified version to my answer but will be happy to remove it from there if you want to use it in yours. (I guess the background stuff is also not needed in your answer.) –  Apr 12 '18 at 14:50
  • @marmot No problem, leave it in yours. You discovered this nice trick. For sure I will use it. – Ignasi Apr 12 '18 at 17:39
  • Well, it was discovered by @Jake. Anyway, I'll refer to him and you if I ever use this again. –  Apr 12 '18 at 17:43