我正在尝试重新绘制大学讲义的内核方案图。这是我的成果:
\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);