重新绘制内核方案图

重新绘制内核方案图

我正在尝试重新绘制大学讲义的内核方案图。这是我的成果:

\documentclass{article}

\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[magyar]{babel}

\usepackage{tikz}
\usetikzlibrary{positioning,fit}

\usepackage[active,tightpage]{preview}
\PreviewEnvironment{tikzpicture}


\begin{document}

\begin{tikzpicture}[font=\sffamily]
    \tikzstyle{title}=[rectangle]
    \tikzstyle{wrapper}=[anchor=west, draw]
    \tikzstyle{bigblock}=[rectangle, minimum width=10cm, minimum height=1cm, anchor=west, draw]
    \tikzstyle{Nbigblock}=[rectangle, minimum width=10cm, minimum height=1cm, anchor=north, draw]
    \tikzstyle{Sbigblock}=[rectangle, minimum width=10cm, minimum height=1cm, anchor=south, draw]
    \tikzstyle{medblock}=[rectangle, minimum width=6cm, minimum height=1cm, anchor=south, draw]
    \tikzstyle{smallblock}=[rectangle, minimum width=3cm, minimum height=1cm, anchor=west, draw]

    \node (kernel) [title] {Kernel};
    \node (syscalls) [bigblock, below=of kernel] {Rendszerhívások};
    \node (filesystems) [smallblock, below=of syscalls.west] {Fájlrendszerek};
    \node (networklayer) [smallblock, below=of filesystems] {Hálózati réteg};

    \node (processhandling) [title,below=of syscalls.east] {Processzkezelés};
    \node (scheduler) [smallblock, below=of processhandling] {Ütemező};
    \node (memhandling) [smallblock, below=of scheduler] {Memóriakezelés};
    \node (IPC) [smallblock, below=of memhandling] {IPC};

    \node (processhandlingwrapper) [wrapper, fit={(processhandling) (scheduler) (memhandling) (IPC)}] {};

    \node (periphhandling) [bigblock, below=of processhandlingwrapper.south east] {Perifériák kezelése};
    
    \node (kernelwrapper) [wrapper, fit={(kernel) (filesystems) (syscalls) (networklayer) (processhandling) (periphhandling)}] {};

    \node (hardver) [below=of kernelwrapper.south, Nbigblock] {Hardver};

    \node (syslibs) [above=of kernelwrapper, medblock] {Rendszerkönyvtárak};

    \node (usrprocesses) [above=of syslibs, Sbigblock] {Felhasználói processzek};
\end{tikzpicture}

\end{document}

在左边你可以看到我想要使用 TikZ 重新绘制的图表,右边是我的方法,你可以从中看到错误的定位和缺少箭头。

内核方案 内核方案

您能帮我纠正定位并将箭头画到正确的位置吗?谢谢!

答案1

anchor示例中的定位无法按预期工作的原因在于,在相对位置之前或之后指定节点的 存在差异(例如below=of)。举个简单的例子:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning}
\begin{document}
\begin{tikzpicture}[demo/.style={anchor=west,draw}]
\node (A) [draw] {lorem};
\node [below=of A.south east,demo] {ipsum};
\node [yshift=-2em,demo,below=of A.south east] {ipsum};
\end{tikzpicture}
\end{document}

在此处输入图片描述

如您所见,当在相对位置(顶部“ipsum”)之后指定锚点时,结果可能符合预期。相反的情况不起作用的原因是,anchor当您使用类似 的内容时, 会自动设置below=of somenode。因此,当您的anchor=west参数在定位之前时,它将被覆盖。

下面是或多或少重现了您的图表的代码。有点老套,因为有一些手动节点移动。此外,顶部和底部节点没有那么宽kernelwrapper。您可以简单地稍微增加minimum width这些节点的宽度,我不知道还有更好的方法。

我还添加了箭头。也许不是最漂亮的方法,但 Stefan 的方法可能更好。我没有移动箭头的起点,而是使用了语法<node name>.<angle>。虽然它有效,但对于矩形节点来说可能不是最好的。

\documentclass{article}

\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[magyar]{babel}

\usepackage{tikz}
\usetikzlibrary{positioning,fit}

\usepackage[active,tightpage]{preview}
\PreviewEnvironment{tikzpicture}


\begin{document}

\begin{tikzpicture}[font=\sffamily]
    \tikzstyle{title}=[rectangle]
    \tikzstyle{wrapper}=[anchor=west, draw]
    \tikzstyle{bigblock}=[rectangle,minimum width=10cm, minimum height=1cm, anchor=west, draw]
    \tikzstyle{Nbigblock}=[rectangle, minimum width=10cm, minimum height=1cm, anchor=north, draw]
    \tikzstyle{Sbigblock}=[rectangle, minimum width=10cm, minimum height=1cm, anchor=south, draw]
    \tikzstyle{medblock}=[rectangle, minimum width=6cm, minimum height=1cm, draw]
    \tikzstyle{smallblock}=[rectangle, minimum width=3cm, minimum height=1cm, anchor=west, draw,node distance=.2cm]

    \node (kernel) [title,below=of syslibs] {Kernel};
    \node (syscalls) [bigblock, below=of kernel] {Rendszerhívások};
    \node (filesystems) [below=of syscalls.south west,smallblock] {Fájlrendszerek};
    \node (networklayer) [smallblock, below right=of filesystems,anchor=north,yshift=-1cm] {Hálózati réteg};

    \node (processhandling) [title,below=of syscalls.south east,anchor=east,xshift=-2.5ex] {Processzkezelés};
    \node (scheduler) [smallblock, below=of processhandling] {Ütemező};
    \node (memhandling) [smallblock, below=of scheduler] {Memóriakezelés};
    \node (IPC) [smallblock, below=of memhandling] {IPC};

    \node (processhandlingwrapper) [wrapper, fit={(processhandling) (scheduler) (memhandling) (IPC)}] {};

    \node (periphhandling) [below=of processhandlingwrapper.south east,bigblock,anchor=east] {Perifériák kezelése};

    \node (kernelwrapper) [wrapper, fit={(kernel) (filesystems) (syscalls) (networklayer) (processhandling) (periphhandling)}] {};

    \node (hardver) [below=of kernelwrapper, Nbigblock] {Hardver};
    \node (usrprocesses) [Sbigblock,above=2cm of kernelwrapper] {Felhasználói processzek};
    \node (syslibs) [above=of kernelwrapper.north west, medblock,anchor=west] {Rendszerkönyvtárak};

    \begin{scope}[latex-latex]
        \draw (usrprocesses.350) -- (usrprocesses.350 |- processhandlingwrapper.north);
        \draw (syslibs) -- (syslibs |- usrprocesses.south);
        \draw (syslibs) -- (syslibs |- syscalls.north);
        \draw (filesystems) -- (filesystems |- syscalls.south);
        \draw (filesystems) -- (filesystems -| processhandlingwrapper.west);
        \draw (filesystems.240) -- (filesystems.240 |- periphhandling.north);
        \draw (networklayer) -- (networklayer -| processhandlingwrapper.west);
        \draw (networklayer.150) -- (networklayer.150 |- filesystems.south);
        \draw (networklayer.60) -- (networklayer.60 |- syscalls.south);
        \draw (networklayer) -- (networklayer |- periphhandling.north);
        \draw (hardver) -- (periphhandling);
    \end{scope}
\end{tikzpicture}
\end{document}

在此处输入图片描述

答案2

你可以使用

  • \draw使用可选的箭头参数,例如\draw[<->],为其定义一种样式
  • 指定带有锚点的节点,例如syslibs.north用于连接
  • 在节点规范中使用|-以获得正交箭头
  • 用于xshift水平移动箭头

例如:

\tikzstyle{doublearrow}=[draw, thick, latex-latex] 
...
\draw[doublearrow] (syslibs.north)--(usrprocesses.south);
\draw[doublearrow] (syslibs.south) --(syscalls.north-|syslibs.south);
\draw[doublearrow] ([xshift=-1.5cm]syscalls.north) -- 
                   ([xshift=-1.5cm]usrprocesses.south-|syscalls);

画箭头

相关内容