Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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?

share|improve this question

2 Answers 2

up vote 6 down vote accepted

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}
share|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

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

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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