How to fit a tikz node to a latex table containing multirows?
You can place the baseline correctly using [baseline=(#3.text)]
. You can make all the nodes the same height by including a \strut
inside the node. The [anchor=base]
has no effect here since there is only one node in each tikzpicture
.
\documentclass{standalone}
\usepackage{tikz,forloop,tabularx,tabulary,multicol,multirow,pgfmath}
\usetikzlibrary{positioning,arrows,chains,matrix,scopes,fit,calc}
\makeatletter
% 1. cols
% 2. pos
% 3. node name
% 4. text
\newcommand{\multicolx}[4]{
\multicolumn{#1}{#2}{\tikz[remember picture,baseline=(#3.text)]{\node[anchor=base,inner sep=0pt, draw, color=red, minimum width=#1*4mm] (#3) {\strut #4};}}
}
\makeatother
\begin{document}
\begin{tikzpicture}
\node[] (tableipv4) at (0,0)
{
\setlength{\tabcolsep}{0.0pt}
\begin{tabular}{|*{32}{m{4mm}}|}
\multicolumn{32}{|c|}{IPv4 Header}\\\hline
\multicolx{4}{|c}{tbl-ver}{Version} & \multicolx{4}{|c}{tbl-ihl}{IHL} & \multicolx{8}{|c}{tbl-tos}{Type of Service} & \multicolx{16}{|c|}{tbl-len}{Total Length}\\\hline
\multicolumn{16}{|c}{Identification} & \multicolumn{3}{|c}{Flags} & \multicolumn{13}{|c|}{Fragment Offset} \\\hline
\multicolumn{32}{|c|}{Source Address}\\\hline
\multicolumn{32}{|c|}{Destination Address}\\\hline
\multicolumn{24}{|c}{Options} & \multicolumn{8}{|c|}{Padding}\\\hline
\end{tabular}
};
\end{tikzpicture}
\end{document}
The problem with the revised MWE has to do with the width of the lines being drawn not being included in the calculation. The following isn't a perfect fit since the correction should differ for {|c|} and {c|}.
\documentclass{standalone}
\usepackage{tikz,forloop,tabularx,tabulary,multicol,multirow,pgfmath}
\usetikzlibrary{positioning,arrows,chains,matrix,scopes,fit,calc}
\makeatletter
% 1. cols
% 2. pos
% 3. node name
% 4. text
\newcommand{\multicolx}[4]{
\multicolumn{#1}{#2}{\tikz[remember picture,baseline=(#3.text)]{ \node[inner sep=0pt,draw, color=red,minimum width={#1*4mm-.75pt}] (#3) {\strut #4};}}
}
\makeatother
\begin{document}
\begin{tikzpicture}
\node[] (tableipv4) at (0,0)
{
\setlength{\tabcolsep}{0.0pt}
\begin{tabular}{|*{32}{m{4mm}}|}
\multicolumn{32}{|c|}{IPv4 Header}\\\hline
\multicolx{4}{|c}{tbl-ver}{Version} & \multicolx{4}{|c}{tbl-ihl}{IHL} & \multicolx{8}{|c}{tbl-tos}{Type of Service} & \multicolx{16}{|c|}{tbl-len}{Total Length}\\\hline
\multicolx{16}{|c}{tbl-id}{Identification} & \multicolx{3}{|c}{tbl-flag}{Flags} & \multicolx{13}{|c|}{tbl-frag}{Fragment Offset} \\\hline
\multicolx{32}{|c|}{tbl-src}{Source Address}\\\hline
\multicolx{32}{|c|}{tbl-dest}{Destination Address}\\\hline
\multicolx{24}{|c}{tbl-opts}{Options} & \multicolx{8}{|c|}{tbl-pad}{Padding}\\\hline
\end{tabular}
};
\end{tikzpicture}
\end{document}
Far more simple is drawn your table/image:
For example, your MWE (with correct IP v4 header structure ... consider RFC 1122, RFC 2474 and RFC 2481) as pure TikZ image:
\documentclass[tikz,margin=3mm]{standalone}
\usetikzlibrary{chains, positioning}
\begin{document}
\begin{tikzpicture}[
node distance = 0mm,
start chain = going right,
N/.style = {draw,
minimum width=#1 mm,
outer sep=0pt,
text height=2ex, text depth=0.5ex,
on chain},
]
%--- 1
\node (n11) [N=20,right] at (0,0) {version};
\node (n12) [N=20] {IHL};
\node (n13) [N=30] {DS fiesld};
\node (n14) [N=10] {ECN};
\node (n15) [N=80] {Total Length};
%--- 2
\node (n21) [N=80,
below right=of n11.south west] {Identification};
\node (n22) [N=15] {Flags};
\node (n23) [N=65] {Fragment Offset};
%--- 3
\node (n31) [N=40,
below right=of n21.south west] {Time to Leave};
\node (n32) [N=40] {Protocol};
\node (n33) [N=80] {Header Checksum};
%--- 4,5,6
\node (n41) [N=160,
below right=of n31.south west] {Source Address};
\node (n51) [N=160,below=of n41] {Destination Address};
\node (n61) [N=160,below=of n51] {Options + Padding (if any)};
%----------------
\foreach \i in {0,4,8,14,16,19,32}
\draw (5*\i/10,0.4) -- ++ (0,0.2)
\ifnum\i<31
node[midway,right=-1pt,font=\tiny] {\i}
\else
node[midway,left=-1pt,font=\tiny] {31}
\fi;
\node (00) [above=4mm of n14.north east] {IPv4 Header};
%---
\end{tikzpicture}
\end{document}