Tikz: Draw simplified BLE-Stack
With use of TikZ libraries fit
and positioning
, for all positioning distances are used only values defined in node distance
. This enables to write clear, concise and consistent code:
Edit:
if you like to change distances of nodes' labels from nodes (on consistent way), you only need to add label distance = <desired amount>
to tikzpicture
options (added now to MWE below.
Also, if you like to change distance between nodes and doted nodes around it, for example have different in horizontal direction from vertical, you only need to add inner xsep
and inner ysep
in style for node FIT
. For example:
FIT/.style = {draw, semithick, dotted, fit=#1,
inner xsep=4mm, inner ysep=2mm}, % here you can adjust inner distance of node},
All aforementioned I now added to my 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}
Result is:
Everything here is placed with respect to the components in the diagram. With the comments, the logic is very easy to follow.
\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}
- For the first question, simply name the node where the text is written, then draw the pattern from this node to the edges.
\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
- The second question is more complex, so I suggest that you make it another question in its own right.
\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}