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.

This TeX.sx question asks if is it possible to use a TikZ matrix along a chain. The error that occurs when one tries to do so is Package pgf Error: No shape named chain-3 is known., and a way to circumvent it is to manually give the matrix node that name.

If the node is already used with a name it was given before making it a matrix, it can be tempting to give it an alias, like below:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning,chains,matrix}
\begin{document}
\begin{tikzpicture}[start chain]
  \node [on chain] {XYZ};
  \node [on chain,alias=Foo] {123};
  \node [on chain,matrix of nodes,alias=Bar]  (chain-3) {    A \\    B \\    C \\  };
  \node [on chain] {$\alpha\beta\gamma$};
  \fill (Foo) circle (2pt);
  \fill (Bar) circle (2pt);
\end{tikzpicture}
\end{document}

Alas, this doesn't work, as it seems matrix nodes simply ignore the alias option -- which probably explains why they don't get the chain-i name when used in a chain.

Is there a way to give a matrix node an alias? Note: I'm using PGF version 2.10, which is rather up-to-date. If this behaviour is fixed in a later release, please let me know.

MWE:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{matrix}
\begin{document}
\begin{tikzpicture}
  \node [alias=Foo] (regularnode) {123};
  \node [matrix of nodes,alias=Bar] (matrixnode) {A\\B\\C\\};
  \fill (Foo) circle (2pt);
  \fill (Bar) circle (2pt);
\end{tikzpicture}
\end{document}

This works perfectly for Foo (the regular node), but the last \fill command gives ERROR: Package pgf Error: No shape named Bar is known.

share|improve this question

2 Answers 2

up vote 5 down vote accepted

Updated solution

A more general solution defining the matrix on chain style to fix the naming bug with matrix on chain (the result is the same as below).

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning,chains,matrix,fit}
\tikzset{
  matrix on chain/.style={
    on chain=#1,
    append after command={
      \pgfextra{\node[fit=(\tikzlastnode),inner sep=0] (\tikzchaincurrent){};}
    },
  },
}
\begin{document}
\begin{tikzpicture}[start chain=foo going below,start chain=bar going right]
  \node [on chain] {ooo};
  \node [on chain, alias=Foobar] {123};
  \node [matrix on chain, matrix of nodes,name=Bar] {A\\B\\C\\};
  \node [on chain] {$\alpha\beta\gamma$};
  \node [on chain=foo] {XXX};
  \node [matrix on chain=foo,matrix of nodes,name=Foo] {A\\B\\C\\};
  \node [on chain=foo] {XXX};
  \node [on chain] {$\alpha\beta\gamma$};
  \fill[red] (Foo) circle (2pt);
  \fill[red] (Bar) circle (2pt);
  \fill[blue] (Bar-1-1) circle (2pt);
  \draw[green!50!black] (Bar.south west) -- (Bar.south east);
  \draw[red!50!black,very thick] (Foo.south west) -- (Foo.south east);
\end{tikzpicture}
\end{document}

First solution

Here is a solution (a mix between JLDiaz's answer, percusse's comment and my idea) using automatically the fit library (the example is more complex to test with two chains).

enter image description here

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning,chains,matrix,fit}
\tikzset{
  chainalias/.style={name=#1,append after command={
      \pgfextra{\node[fit=(\tikzlastnode),inner sep=0] (\tikzchaincurrent){};}
    },
  },
}
\begin{document}
\begin{tikzpicture}[start chain=foo going below,start chain=bar going right]
  \node [on chain] {ooo};
  \node [on chain, alias=Foo] {123};
  \node [on chain, matrix of nodes,chainalias=Bar] {A\\B\\C\\};
  \node [on chain] {$\alpha\beta\gamma$};
  \node [on chain=foo] {XXX};
  \node [on chain=foo, matrix of nodes,chainalias=Foo] {A\\B\\C\\};
  \node [on chain=foo] {XXX};
  \node [on chain] {$\alpha\beta\gamma$};
  \fill[red] (Foo) circle (2pt);
  \fill[red] (Bar) circle (2pt);
  \fill[blue] (Bar-1-1) circle (2pt);
  \draw[green!50!black] (Bar.south west) -- (Bar.south east);
  \draw[red!50!black,thick] (Foo.south west) -- (Foo.south east);
\end{tikzpicture}
\end{document}
share|improve this answer
1  
Using fit to "clone" a node is a smart move! –  JLDiaz Dec 11 '12 at 8:39

A silly idea:

\documentclass{article}
\usepackage{tikz}
\begin{document}
\thispagestyle{empty}
\usetikzlibrary{positioning,chains,matrix}
\begin{tikzpicture}[
  start chain
]
  \node [on chain] {XYZ};
  \node [on chain, alias=Foo] {123};
  \node [on chain, matrix of nodes ] (chain-3) {  A \\    B \\    C \\  };
  \coordinate (Bar) at (chain-3);
  \node [on chain] {$\alpha\beta\gamma$};
  \fill[red] (Foo) circle (2pt);
  \fill[red] (Bar) circle (2pt);
\end{tikzpicture}
\end{document}
\end{tikzpicture}
\end{document}

Result

UPDATE: Since the OP requested to be able to access Bar anchors, I had another silly idea: give the name Bar to the matrix, and the name chain-3 to the "alias" coordinate. This works because the name chain-3 is required only to position the next element of the chain, and knowing the center is enough. Then:

\begin{tikzpicture}[
  start chain
]
  \node [on chain] {XYZ};
  \node [on chain, alias=Foo] {123};
  \node [on chain, matrix of nodes ] (Bar) {  A \\    B \\    C \\  };
  \coordinate (chain-3) at (Bar);
  \node [on chain] {$\alpha\beta\gamma$};
  \fill[red] (Foo) circle (2pt);
  \fill[red] (Bar) circle (2pt);
  \fill[blue] (Bar-1-1) circle (2pt);
  \draw[green!50!black] (Bar.south west) -- (Bar.south east);
\end{tikzpicture}

Result

share|improve this answer
    
Yup, that works when you access the center of the node, but not if you need to access its anchors: \fill[red] (Bar.north east) circle (2pt); or \fill[red] (Bar.73) circle (2pt); won't work. I don't know if there is a way to create a "clone" node, that works like a coordinate, but also copies all the anchors from the original node. Basically an "alias" shape. If that existed, using it instead of your coordinate would solve the problem indeed. –  Georges Dupéron Dec 10 '12 at 23:23
    
@GeorgesDupéron Updated answer :-) –  JLDiaz Dec 10 '12 at 23:40
1  
Sneaky! You can automate it via \tikzset{mychainalias/.style={append after command={coordinate (chain-#1) at (\tikzlastnode)}}} then add the option mychainalias=3 to the matrix for sweeping it under the rug. But if the matrix is wide enough you might get into trouble. –  percusse Dec 10 '12 at 23:46
1  
@percusse As a more general solution, for the case of wide matrices, the "alias" should be \coordinate (chain-3) at (Bar.east); but unfortunately the cardinal point depends on the growth direction of the chain. –  JLDiaz Dec 11 '12 at 0:10

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.