2

I have a tikz picture where I would like draw an arrow from a cell in a table contained in a node to an anchor of another node: (the arrow is added using Microsoft Paint)

enter image description here

I attempted to draw the arrow using tikzmark, which, as far as I know, works perfectly outside a tikzpicture:

\documentclass{article}

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

\begin{document}

\begin{tikzpicture}[font = \ttfamily]
  \node (s) {
    \begin{tabular}{|c|c|}
      \hline
      ptr & \tikzmark{s ptr} \\
      \hline
      len & 5 \\
      \hline
    \end{tabular}
  };

  \node [right = of s.north east] (content north west) {};
  \node [below right] (content) at (content north west) {
    \begin{tabular}{|c|c|}
      \hline
      "hello" \\
      \hline
    \end{tabular}
  };

  \draw [->] (s ptr) -- (content.west);
\end{tikzpicture}

\end{document}

only to be greeted with a puzzling error:

! Package tikz Error: Cannot parse this coordinate.

See the tikz package documentation for explanation.
Type  H <return>  for immediate help.
 ...

l.12       ptr & \tikzmark{s ptr} \\

Unclear what to do, I changed \tikzmark to \tikzmarknode:

\documentclass{article}

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

\begin{document}

\begin{tikzpicture}[font = \ttfamily]
  \node (s) {
    \begin{tabular}{|c|c|}
      \hline
      ptr & \tikzmarknode{s ptr}{} \\
      \hline
      len & 5 \\
      \hline
    \end{tabular}
  };

  \node [right = of s.north east] (content north west) {};
  \node [below right] (content) at (content north west) {
    \begin{tabular}{|c|c|}
      \hline
      "hello" \\
      \hline
    \end{tabular}
  };

  \draw [->] (s ptr) -- (content.west);
\end{tikzpicture}

\end{document}

which eliminated the error. However, compiling the code several times, the arrow keeped moving among strange places, and finally converged to:

enter image description here

which is undesirable.

Currently, I work around this issue by hard-coding the coordinate via (s.north east) - (10pt, 10pt). Is there a more elegant solution to this problem?

1 Answer 1

2

enter image description here

With use of the matrix libraries is simple:

\documentclass[tikz, margin=3mm]{standalone}
\usetikzlibrary{arrows.meta,
                matrix,
                positioning}

\begin{document}
    \begin{tikzpicture}[
every node/.append style = {minimum size=1.5em,
                            inner sep=1mm,  outer sep=0mm,
                            font=\sffamily}
                        ]   
\node (m) [matrix of nodes,
           nodes in empty cells, 
           nodes= {anchor=center},
           column sep=-\pgflinewidth,
           row sep=-\pgflinewidth,
           draw, 
           inner sep=0pt
           ]
{
ptr     &   \\
length  & 5 \\
};
\draw   (m.west) -- (m.east)
        (m-1-2.north -| m-2-1.east) -- (m-2-2.south west);
\node [draw, right = of m-1-2.east] (n) {"hello"};
%
\draw [-Straight Barb] (m-1-2.center) -- (n);
    \end{tikzpicture}
\end{document}

Addendum: there is no way to add lines with features if \hline and vertical lines known from tables. However, it is possible to do semi automatic, meaning that you not draw them separately, however, you need to determine columns width with minimum width of cells in any column:

\documentclass[tikz, margin=3mm]{standalone}
\usetikzlibrary{arrows.meta,
                matrix,
                positioning}

\begin{document}
    \begin{tikzpicture}[
every node/.append style = {draw, minimum size=1.5em,
                            inner sep=1mm,  outer sep=0mm,
                            font=\sffamily}
                        ]
\node (m) [matrix of nodes,
           nodes in empty cells,
           nodes= {anchor=center},
           column sep=-\pgflinewidth,
           row sep=-\pgflinewidth,
           column 1/.append style = {nodes={minimum width=4em}}, % width of the wides cell in column 2
           column 2/.append style = {nodes={minimum width=2em}}, % with of the widest cell in column 2
           draw,
           inner sep=0pt
           ]
{
ptr     &   \\
length  & 5 \\
};
\node [draw, right = of m-1-2.east] (n) {"hello"};
%
\draw [-Straight Barb] (m-1-2.center) -- (n);
    \end{tikzpicture}
\end{document}

Similar solution also propose @leandriis in his comment.

enter image description here

4
  • Thanks for the matrix suggestion! Is there a way to automate drawing the separation lines of the table for more cells?
    – L. F.
    Dec 14, 2020 at 12:17
  • @L.F., as far as i know, no.
    – Zarko
    Dec 14, 2020 at 15:12
  • @L.F.: You could try the following variant: \begin{tikzpicture}[every node/.append style = {minimum size=1.5em,inner sep=1mm,outer sep=0mm,font=\sffamily}] \node (m) [matrix of nodes,nodes in empty cells, nodes= {anchor=center, draw},column sep=-\pgflinewidth, row sep=-\pgflinewidth,column 1/.style = {nodes={minimum width=1.2cm}},] {ptr & \\ length & 5 \\ }; \node [draw, right = of m-1-2.east] (n) {"hello"}; \draw [-Straight Barb] (m-1-2.center) -- (n); \end{tikzpicture}. I however had to fix the width of teh first column with this approach.
    – leandriis
    Dec 14, 2020 at 22:00
  • @L.F., one way is to determine columns width by minimum width of nodes in each column and than add to nodes option draw. So this is only *semiautomatic` ... I will to answer add this asap.
    – Zarko
    Dec 14, 2020 at 22:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.