如何计算项目与架构图顶部的距离?

如何计算项目与架构图顶部的距离?

制作架构图

在此处输入图片描述

我使用以下代码

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

\draw[->] ([yshift=-13pt]$(instructor.east)$) -- ([yshift=1pt]$(department.west)$);我在行中创建了一个yshift。为此,请yshift多次编辑值以使输出符合预期。如果我知道图表中每个项目与顶部或底部的距离,我可以轻松做出yshift值决定,只需将项目编号和距离相乘即可。

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

或者,

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

答案1

也许最简单的方法是真正利用节点部分。更新:添加了水平线。(不幸的是,TiZ 还不接受选项的列表rectangle split draw splits,但接受的列表却接受rectangle split part fill,所以我不得不通过其他方式划清界限。)

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

在此处输入图片描述

更新: 基于Ignasi 的精彩回答这个答案. 产生相同的输出。

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

答案2

这是对 marmot 答案的补充。评论可能就够了,但有点长。

instructor在这种情况下,或下面的线department是用path picture命令绘制的,而无需\pgfextra命令。

nodes'由于我们需要知道名称,因此不可能在一般样式中使用它,因此,Line已经定义了一种样式并将其添加到instructor节点中department

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

在此处输入图片描述

更新:

感谢percusse 的答案我以前的代码可以简化并定义一种已经包含在标题上绘制线条的basic样式。path picture

由于path picture我们需要知道节点的名称,我们可以name在样式中包含该选项basic。这样,启动时就已经知道参数(节点的名称)path picture

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

相关内容