谁能给我一个例子说明如何用 tikz 绘制这个 BLE-Stack?
编辑
现在,我离我想要的结果已经很接近了:)
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{arrows}
\usetikzlibrary{positioning}
\begin{document}
\begin{tikzpicture}[align=center,>=latex',font=\sffamily]
\tikzstyle{Dotted} = [draw=black,dashed,thick,rectangle,minimum width=120mm,minimum height=33mm]
\tikzstyle{Normal} = [draw=black,thick,rectangle,minimum width=108mm,minimum height=12mm]
\node[label=left:Controller,label={[label distance=5.5mm]},Dotted](Controller){};
\node[above left = 3mm and 6mm of Controller.south east,anchor=south east,Normal](PHY){LE Physical Layer\\(PHY)};
\node[above = 3mm of PHY,Normal](LL){Link Layer\\(LL)};
\node[above = 10mm of Controller.north west,anchor=north west](HCI0){};
\node[above = 10mm of Controller.north east,anchor=north east](HCI1){};
\draw[dash pattern={on 5mm off 3mm},line width=1.2mm,](HCI0) -- (HCI1) node[midway,fill=white]{Host Controller Interface\\(HCI)};
\node[above = 18mm of Controller,label=left:Host,label={[label distance=5.5mm]},Dotted,minimum height=48mm](Host){};
\node[above left = 3mm and 6mm of Host.south east,anchor=south east,Normal](L2CAP){Logical Link Control and Adaption Protocol\\(L2CAP)};
\node[above =15mm of L2CAP.north east,anchor=north east,Normal,minimum width=51mm](ATT){Attribute Protocol\\(ATT)};
\node[above = 15mm of ATT.east,anchor=east,Normal,minimum width=51mm](GATT){Generic Attribute Profile\\(GATT)};
\node[above = 15mm of L2CAP.north west,anchor=north west,Normal,minimum width=51mm](GAP){Generic Access Profile\\(GAP)};
\node[above = 15mm of GAP.north west,anchor=north west,Normal,minimum width=51mm](SMP){Security Manager Protocol\\(SMP)};
\node[above = 3mm of Host,label=left:Application,label={[label distance=5.5mm]},Normal,minimum width=120mm](Application){Application\\(APP)};
\end{tikzpicture}
\end{document}
此代码产生以下输出
仅有两个问题:
- 如何从左边界和右边界开始绘制虚线以得到对称虚线?
- 如何删除虚线左右两侧的插入?
答案1
此处所有元素均根据图表中的组件放置。通过注释,逻辑非常容易理解。
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{fit}
\usetikzlibrary{positioning}
\tikzset{
nopadding/.style={
inner sep=0pt, outer sep=0pt
},
textBlock/.style={
draw, text width=12em, text centered, minimum height=2em,
nopadding, inner ysep=3pt
},
longTextBlock/.style={
text width=24em, text centered, minimum height=2em,
nopadding, inner ysep=3pt
}
}
\begin{document}
\begin{tikzpicture}[font=\small\sffamily]%
\node[draw=none,minimum width=25em, nopadding] (start) at (0,0) {}; % Starting point
% Host
% Row 1, col 1
\node[textBlock, below=of start.south west, anchor=west]
(SMP){Security Manager Protocol\\(SMP)};
% Row 1, col 2
\node[textBlock, below=of start.south east, anchor=east]
(GATT){Generic Attribute Profile\\(GATT)};
% Row 2, col 1
\node[textBlock, below of=SMP](GAP){Generic Access Profile\\(GAP)};
% Row 2, col 2
\node[textBlock, below of=GATT](ATT){Attribute Protocol\\(ATT)};
% Row 3, col 1&2
\node[fit=(SMP) (GATT), below=of GAP.west, anchor=west, draw, nopadding](L2CAP){};
% Row 3, col 1&2 text
\node[longTextBlock]
(L2CAPText)at(L2CAP.center){Logical Link Control and Adaption Protocol\\(L2CAP)};
% Host dashed line and label
\node[fit=(L2CAP) (SMP) (GAP) (GATT) (ATT),
draw, dashed, label={[black, xshift=-5pt]left:Host} ](hostFit){};
% Application label
\node[fit=(hostFit.west) (hostFit.east)(GAP),
above=of hostFit.north west, anchor=north west,
draw, nopadding, label={[black, xshift=-5pt]left:Application}](appFit){};
% Application text
\node[longTextBlock] (appText) at (appFit.center){Application\\(APP)};
% Controller dashed lines fit
\node[fit=(hostFit.west) (hostFit.east)(GAP),
below=of hostFit.south west, anchor=south west,
nopadding,draw=none](controllerDashed){};
% Controller actual lines and text.
\draw[dash pattern={on 7pt off 3pt}, line width=3pt]
(controllerDashed.west) -- (controllerDashed.east)
node[textBlock, midway,fill=white, draw=none]
{Host Controller Interface\\(HCI)};
% Controller
% Row 1
\node[fit=(L2CAP), below=of controllerDashed.south, anchor=south,
nopadding, draw, yshift=-5pt](controllerRow1){};
% Row 1 text
\node[longTextBlock]
(controlRow1Text) at (controllerRow1.center){LE Physical Layer\\(PHY)};
% Row 2
\node[fit=(controllerRow1), below of = controllerRow1, draw,
nopadding,draw](controllerRow2){};
% Row 2 text
\node[longTextBlock]
(controlRow2Text) at (controllerRow2.center){Link Layer\\(LL)};
% Controller dashed lines and label
\node[fit=(controllerRow1)(controllerRow2), draw, dashed,
label={[black, xshift=-5pt]left:Control}](controlFit){};
\end{tikzpicture}
\end{document}
答案2
使用 TikZ 库fit
和positioning
,所有定位距离仅使用 中定义的值node distance
。这样可以编写清晰、简洁和一致的代码:
编辑:
如果您想更改节点标签与节点的距离(以一致的方式),您只需要添加label distance = <desired amount>
到tikzpicture
选项(现在添加到下面的 MWE)。
另外,如果你想改变节点和它周围的点节点之间的距离,例如在水平方向和垂直方向上有所不同,你只需要在节点的样式中添加inner xsep
和。例如:inner ysep
FIT
FIT/.style = {draw, semithick, dotted, fit=#1,
inner xsep=4mm, inner ysep=2mm}, % here you can adjust inner distance of node},
我现在将上述所有内容添加到我的 MWE 中。
\documentclass[tikz, border=3mm]{standalone}
\usetikzlibrary{fit,
positioning}
\begin{document}
\begin{tikzpicture}[
node distance = 2mm and 0mm,
box/.style = {draw, text width=#1, inner sep=2mm, align=center},
box/.default = 98mm,
FIT/.style = {draw, semithick, dotted, fit=#1,
inner xsep=4mm, inner ysep=2mm}, % here you can adjust inner distance of node
% this adjust you need to consider at defining the width of the top nodes
label distance = 2mm,
font = \sffamily
]
\node (phy) [box] {LE Physical Layer\\(PHY)};
\node (lll) [box, above = of phy] {Link Layer\\(LL)};
\node (cntrl) [FIT=(phy) (lll), label=left:Control] {};
%
\node (hci) [box=12em,draw=none,
above=of cntrl] {Host Controller Interface\\(HCI)};
\draw[line width=1.2mm, dash pattern=on 5mm off 3mm] % solve your first question
(lll.west |- hci) -- (hci)
(lll.east |- hci) -- (hci);
%
\node (cap) [box, above=of hci] {Logical Link Control and Adaption Protocol\\(L2CAP)};
\node (gap) [box=44mm,
above right=of cap.north west] {Generic Access Profile\\(GAP)};
\node (att) [box=44mm,
above left=of cap.north east] {Attribute Protocol\\(ATT)};
\node (smp) [box=44mm,
above=of gap] {Security Manager Protocol\\(SMP)};
\node (gap) [box=44mm,
above=of att] {Generic Attribute Profile\\(GATT)};
\node (host) [FIT=(cap) (smp), label=left: Host] {};
%
\node (app) [box=106mm, above= of host,
label=left:Application] {Application\\(APP)};
\end{tikzpicture}
\end{document}
结果是:
答案3
- 对于第一个问题,只需命名写有文本的节点,然后从该节点向边缘绘制图案。
\path[](HCI0) -- (HCI1) node[midway,fill=white](aux){Host Controller Interface\\(HCI)};%<--- auxiliary node (aux)
\draw [dash pattern={on 5mm off 3mm},line width=1.2mm](aux)--(HCI0)(aux)--(HCI1);% pattern from center to edges
- 第二个问题比较复杂,因此我建议你将其作为另一个独立的问题。
\documentclass[border=5mm,tikz]{standalone}
\usetikzlibrary{arrows}
\usetikzlibrary{positioning}
\begin{document}
\begin{tikzpicture}[align=center,>=latex',font=\sffamily]
\tikzstyle{Dotted} = [draw=black,dashed,thick,rectangle,minimum width=120mm,minimum height=33mm]
\tikzstyle{Normal} = [draw=black,thick,rectangle,minimum width=108mm,minimum height=12mm]
\node[label=left:Controller,label={[label distance=5.5mm]},Dotted](Controller){};
\node[above left = 3mm and 6mm of Controller.south east,anchor=south east,Normal](PHY){LE Physical Layer\\(PHY)};
\node[above = 3mm of PHY,Normal](LL){Link Layer\\(LL)};
\node[above = 10mm of Controller.north west,anchor=north west](HCI0){};
\node[above = 10mm of Controller.north east,anchor=north east](HCI1){};
% new node (aux)
\path[](HCI0) -- (HCI1) node[midway,fill=white](aux){Host Controller Interface\\(HCI)};%<--- auxiliary node (aux)
\draw [dash pattern={on 5mm off 3mm},line width=1.2mm](aux)--(HCI0)(aux)--(HCI1);% pattern from center to edges
\node[above = 18mm of Controller,label=left:Host,label={[label distance=5.5mm]},Dotted,minimum height=48mm](Host){};
\node[above left = 3mm and 6mm of Host.south east,anchor=south east,Normal](L2CAP){Logical Link Control and Adaption Protocol\\(L2CAP)};
\node[above =15mm of L2CAP.north east,anchor=north east,Normal,minimum width=51mm](ATT){Attribute Protocol\\(ATT)};
\node[above = 15mm of ATT.east,anchor=east,Normal,minimum width=51mm](GATT){Generic Attribute Profile\\(GATT)};
\node[above = 15mm of L2CAP.north west,anchor=north west,Normal,minimum width=51mm](GAP){Generic Access Profile\\(GAP)};
\node[above = 15mm of GAP.north west,anchor=north west,Normal,minimum width=51mm](SMP){Security Manager Protocol\\(SMP)};
\node[above = 3mm of Host,label=left:Application,label={[label distance=5.5mm]},Normal,minimum width=120mm](Application){Application\\(APP)};
\end{tikzpicture}
\end{document}
答案4
这个答案显示了我在问题中第一次尝试的解决方案与最终解决方案之间的差异。差异位于标签定义中,请参阅我的评论。
代码
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{arrows}
\usetikzlibrary{positioning}
\begin{document}
% First try mentioned in the question
\begin{tikzpicture}[align=center,>=latex',font=\sffamily]
\tikzstyle{Dotted} = [draw=black,dashed,thick,rectangle,minimum width=120mm,minimum height=33mm]
\tikzstyle{Normal} = [draw=black,thick,rectangle,minimum width=108mm,minimum height=12mm]
\node[label=left:Controller,label={[label distance=5.5mm]},Dotted](Controller){};
\node[above left = 3mm and 6mm of Controller.south east,anchor=south east,Normal](PHY){LE Physical Layer\\(PHY)};
\node[above = 3mm of PHY,Normal](LL){Link Layer\\(LL)};
\node[above = 10mm of Controller.north west,anchor=north west](HCI0){};
\node[above = 10mm of Controller.north east,anchor=north east](HCI1){};
\draw[dash pattern={on 5mm off 3mm},line width=1.2mm,](HCI0) -- (HCI1) node[midway,fill=white]{Host Controller Interface\\(HCI)};
\node[above = 18mm of Controller,label=left:Host,label={[label distance=5.5mm]},Dotted,minimum height=48mm](Host){};
\node[above left = 3mm and 6mm of Host.south east,anchor=south east,Normal](L2CAP){Logical Link Control and Adaption Protocol\\(L2CAP)};
\node[above =15mm of L2CAP.north east,anchor=north east,Normal,minimum width=51mm](ATT){Attribute Protocol\\(ATT)};
\node[above = 15mm of ATT.east,anchor=east,Normal,minimum width=51mm](GATT){Generic Attribute Profile\\(GATT)};
\node[above = 15mm of L2CAP.north west,anchor=north west,Normal,minimum width=51mm](GAP){Generic Access Profile\\(GAP)};
\node[above = 15mm of GAP.north west,anchor=north west,Normal,minimum width=51mm](SMP){Security Manager Protocol\\(SMP)};
\node[above = 3mm of Host,label=left:Application,label={[label distance=5.5mm]},Normal,minimum width=120mm](Application){Application\\(APP)};
% Just to demonstrate the outlines
\draw(current bounding box.south east) rectangle(current bounding box.north west);
\end{tikzpicture}
% Second try with improved outlines
\begin{tikzpicture}[align=center,>=latex',font=\sffamily]
\tikzstyle{Dotted} = [draw=black,dashed,thick,rectangle,minimum width=120mm,minimum height=33mm]
\tikzstyle{Normal} = [draw=black,thick,rectangle,minimum width=108mm,minimum height=12mm]
% Edited label configuration
\node[label={[label distance=3mm]left:Controller},Dotted](Controller){};
\node[above left = 3mm and 6mm of Controller.south east,anchor=south east,Normal](PHY){LE Physical Layer\\(PHY)};
\node[above = 3mm of PHY,Normal](LL){Link Layer\\(LL)};
\node[above = 10mm of Controller.north west,anchor=north west](HCI0){};
\node[above = 10mm of Controller.north east,anchor=north east](HCI1){};
\path[](HCI0) -- (HCI1) node[midway,fill=white](aux){Host Controller Interface\\(HCI)};
\draw [dash pattern={on 5mm off 3mm},line width=1.2mm](aux)--(HCI0)(aux)--(HCI1);
% Edited label configuration
\node[above = 18mm of Controller,label={[label distance=3mm]left:Host},Dotted,minimum height=48mm](Host){};
\node[above left = 3mm and 6mm of Host.south east,anchor=south east,Normal](L2CAP){Logical Link Control and Adaption Protocol\\(L2CAP)};
\node[above =15mm of L2CAP.north east,anchor=north east,Normal,minimum width=51mm](ATT){Attribute Protocol\\(ATT)};
\node[above = 15mm of ATT.east,anchor=east,Normal,minimum width=51mm](GATT){Generic Attribute Profile\\(GATT)};
\node[above = 15mm of L2CAP.north west,anchor=north west,Normal,minimum width=51mm](GAP){Generic Access Profile\\(GAP)};
\node[above = 15mm of GAP.north west,anchor=north west,Normal,minimum width=51mm](SMP){Security Manager Protocol\\(SMP)};
% Edited label configuration
\node[above = 3mm of Host,label={[label distance=3mm]left:Application},Normal,minimum width=120mm](Application){Application\\(APP)};
% Just to demonstrate the outlines
\draw(current bounding box.south east) rectangle(current bounding box.north west);
\end{tikzpicture}
\end{document}
结果
- 左侧:第一次尝试
- 右侧:最终解决方案