5

I would like to have a TikZ node with a few lines of text inside. The node should be a rectangle, wider than the text, and the text should be aligned to the left. After each line of text I'd like to put arrows going out to other nodes. This is what I got so far:

\documentclass{standalone}

\usepackage{tikz}
\usetikzlibrary{matrix,positioning,calc}

\makeatletter
\newcommand{\gettikzxy}[3]{%
  \tikz@scan@one@point\pgfutil@firstofone#1\relax
  \edef#2{\the\pgf@x}%
  \edef#3{\the\pgf@y}%
}
\makeatother



\begin{document}

\begin{tikzpicture}[innode/.style={inner sep=0pt, minimum width=1pt},
                    env/.style={draw,rectangle,align=left,inner sep=0.3cm}]
  \node[env,text width=4cm,matrix](q1){\node[innode](sp){first item};\\
                                       \node[innode](at){and the second item};\\};
  %
  \node(c1)[below=of q1.south west,anchor=north]{\ttfamily code for 2};
  \node(c2)[below=of c1.south east,anchor=east]{\ttfamily code for 1 goes here};
  %
  \gettikzxy{(c1)}{\xcu}{\ycu}
  \gettikzxy{(c2)}{\xcd}{\ycd}
  \gettikzxy{(at.east)}{\xate}{\yate}
  \gettikzxy{(sp.east)}{\xspe}{\yspe}
  %
  \draw[->] (sp.east) -- ++(3,0)
                      -- ($ (\xspe,\ycd) + (3,0) $)
                      -- (c2.east);
  \draw[->] (at.east) -- ++(2,0)
                      -- ($ (\xate,\ycu) + (2,0) $)
                      -- (c1.east);
\end{tikzpicture}

\end{document}

enter image description here

However, the arrows start a bit too far from the end of the lines. Is there a better way to do what I'm trying to do, and how do I keep the arrows starting closer to the text?

6

If you set nodes={anchor=west} in the matrix options, the cells in the matrix will be left-aligned without setting the text width explicitly. That way, the line will start close to the text even if the texts have different lengths.

Note that for the connecting lines, you can simply use the |- syntax to get an orthogonal connection, instead of using the calc syntax.

\documentclass[border=5mm]{standalone}

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

\makeatletter
\newcommand{\gettikzxy}[3]{%
  \tikz@scan@one@point\pgfutil@firstofone#1\relax
  \edef#2{\the\pgf@x}%
  \edef#3{\the\pgf@y}%
}
\makeatother



\begin{document}

\begin{tikzpicture}[innode/.style={inner sep=0pt, minimum width=1pt},
                    env/.style={draw,rectangle,align=left,inner sep=0.3cm}]
  \node[env,matrix, nodes={anchor=west}](q1){\node[innode](sp){first item};\\
                                       \node[innode](at){and the second item};\\};
  %
  \node(c1)[below=of q1.south west,anchor=north]{\ttfamily code for 2};
  \node(c2)[below=of c1.south east,anchor=east]{\ttfamily code for 1 goes here};
  %
  \gettikzxy{(c1)}{\xcu}{\ycu}
  \gettikzxy{(c2)}{\xcd}{\ycd}
  \gettikzxy{(at.east)}{\xate}{\yate}
  \gettikzxy{(sp.east)}{\xspe}{\yspe}
  %
  \draw[->] (sp.east) -- ++(3,0) |- (c2.east);
  \draw[->] (at.east) -- ++(1,0) |- (c1.east);
\end{tikzpicture}

\end{document}
| improve this answer | |
  • 1
    Thank you! And I can further align the start of arrows with the longest line by using a 2x2 matrix of nodes, with an empty node after each text node. Great! – Jay Jul 6 '12 at 11:18
3

It's possible to use here tkz-linknodes

\documentclass{scrartcl}
\usepackage{tkz-linknodes}
\usetikzlibrary{matrix,positioning}


\begin{document}
\hspace*{3cm}
\begin{NodesList}
\begin{tikzpicture}[innode/.style={inner sep=0pt, minimum width=1pt},
                    env/.style={draw,rectangle,align=left,inner sep=0.3cm}]
  \node[env,matrix, nodes={anchor=west}](q1){%
                                \node[innode](sp){first item\AddNode};  \\
                                \node[innode](at){and the second item\AddNode[2]};\\};

  \node(c1)[below=of q1.south west,anchor=north]{\ttfamily code for 2\AddNode };
  \node(c2)[below=of c1.south east,anchor=east]{\ttfamily code for 1 goes here\AddNode[2]};
\LinkNodes[margin=9cm]{}
\LinkNodes[margin=10cm]{}   

\end{tikzpicture}
\end{NodesList}

\end{document}

enter image description here

| improve this answer | |

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.