4

In the MWE below, I made a TikZ pic called bus with one argument. The argument creates nodes within the pic that will be used as connection points to other buses. I would like to align these pics by their connection points, i.e., the nodes within them. So in the picture below, the 1 on the right should be in-line with the 2 on the left (vertically centered). But I would love the flexibility of aligning that 1 on the right bus with 1, 2, or 3 on the left bus.

Is this possible? The code I tried failed I think, because the position command to pic defines the origin that the pic is made from, so there isn't any coordinate b-1 in the pic at that time. This is a very simple example, and while I'm not married to using pics, the prospect of using them for this sort of thing is enticing to make building blocks for complex diagrams.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning}
\usetikzlibrary{calc}

\begin{document}

\def\busnodespace{3mm} \tikzset{ pics/bus/.style n args={1}{ code = { % \draw[ultra thick] (0, {-0.75\busnodespace}) -- (0, {(#1-1+0.75)\busnodespace}); \foreach \y in {1,...,#1} {\node[inner sep=0pt] (-\y) at (0.0,{(\y-1)*\busnodespace}) {\color{red}{\scriptsize\y}};} }}}

\begin{tikzpicture} \pic (a) at (0,0) {bus=3}; % bus of size 3 % \pic (b) at (2,0) {bus=1}; % bus of size 1 -- is it possible to position this (elegantly, hopefully with no math) % so coordinate b1 is in line with a2? % ie I would like a flat line % \pic[right=of a-2] (b) {bus=1}; % obv this wont cut \pic[right=of a-2,anchor=b-1] (b) {bus=1}; ; this doesn't work because b isn't made in time for the position to be applied \draw (a-2) -- (b-1);

\end{tikzpicture}

\end{document}

Enter image description here

  • https://tex.stackexchange.com/q/185279/86 contains a few solutions to this problem. Obviously, I'd recommend looking at the tikzmark one. – Andrew Stacey Jan 06 '22 at 06:55
  • @AndrewStacey thanks for sharing, that is highly relevant. I've been using your tikzmark package as of recent anyhow, and the usage seems simple, so this might be a good solution. The scope key adjust pic position is not working for me though, do you know if your newest version has made its way to MiKTeX yet? – likethevegetable Jan 06 '22 at 12:53
  • 1
    It's still in the development version, I need to test it some more (or find people willing to test it) before shipping it to ctan. Current version is at https://github.com/loopspace/tikzmark – Andrew Stacey Jan 06 '22 at 21:58

1 Answers1

5

Like this?

enter image description here

Positioning of pic can be tricky, however in your case relative positioning to nodes in pic works fine. In MWE below the code for pic is simplified and a bit reorganized:

\documentclass[border=3.141592, varwidth]{standalone}
\usepackage{tikz}
\usetikzlibrary{backgrounds, % new
                positioning}

\begin{document}

\def\busnodespace{3mm} \tikzset{ pics/bus/.style ={ code = { % \foreach \i [count=\y from 0] in {1,...,#1} { \node[inner xsep=0pt, inner ysep=\busnodespace/2, font=\scriptsize, text=red] (-n\i) at (0,\y*\busnodespace) {\i}; } \scoped[on background layer] \draw[ultra thick] (-n1.south) -- (-n#1.north); } }}

\begin{tikzpicture} \pic (a) {bus=3}; % bus of size 3 \pic (b) [right=of a-n2] {bus=1}; % bus of size 1 \draw[gray] (a-n2) -- (b-n1); \end{tikzpicture}

\medskip \begin{tikzpicture} \pic (a) {bus=3}; % bus of size 3 \pic (b) [right=of a-n1] {bus=2}; % bus of size 1 \draw[gray] (a-n1) -- (b-n1); \end{tikzpicture}

\medskip \begin{tikzpicture} \pic (a) {bus=3}; % bus of size 3 \pic (b) [right=of a-n3] {bus=1}; % bus of size 1 \draw[gray] (a-n3) -- (b-n1); \end{tikzpicture}

\end{document}

Addendum: One more option. If you define anchor of ˙pic` with coordinate on the middle of it, than you can positioned second pic for example as:

\documentclass[border=3.141592]{standalone}
\usepackage{tikz}
\usetikzlibrary{backgrounds,
                positioning}

\begin{document} \begin{tikzpicture}[ node distance = 0mm and 15mm, pics/bus/.style = {code = {\foreach \i [count=\y from 0] in {1,...,#1} \node[inner xsep=0pt, inner ysep=\busnodespace/2, font=\scriptsize, text=red] (-n\i) at (0,\y\busnodespace) {\i}; \scoped[on background layer] \draw[ultra thick] (-n1.south) -- coordinate (-@c) (-n#1.north);}} % <--- ] \def\busnodespace{3mm} \pic (a) {bus=2}; \pic (b) [below right=3\busnodespace and 15mm of a-@c] {bus=3};
\draw[gray] (a-n1) -- (b-n3); \end{tikzpicture} \end{document}

enter image description here

The same result you will get with the following image body:

\pic (a)                    {bus=2};  
\pic (b) [right= of a-n1, yshift=-2*\busnodespace]    {bus=3}; 
\draw[gray] (a-n1) -- (b-n3);
Zarko
  • 296,517
  • Thanks--does @c have any special meaning or is it just a coord you made? – likethevegetable Jan 06 '22 at 12:45
  • I'm also not seeing how the addendum code is different? – likethevegetable Jan 06 '22 at 13:02
  • @likethevegetable, compare both examples and see differences, @c has not any special meaning, you can select different name. – Zarko Jan 06 '22 at 13:59
  • I'm sorry but the code is identical, I think you made a copy+paste error – likethevegetable Jan 06 '22 at 14:01
  • Ups, @likethevegetable, you are right! By mistake I overwrite original MWE with MWE in addendum. Corrected now. – Zarko Jan 06 '22 at 14:07
  • Thanks for sharing. I said previously that I would like to avoid calculation, but seeing as I have already defined busnodespace, it is a simple calculation. I will likely resort to something like [right of = a-1, yshift=-1*\busnodespace] I was actually looking for an answer in the spirit of this question, and I think it contains the actual answer I'm looking for--however you provided a nice solution for my example. https://tex.stackexchange.com/questions/185279/anchoring-tikz-pics – likethevegetable Jan 06 '22 at 14:17
  • 1
    @likethevegetable, as I said in answer, positioning of pic is tricky. Your sintay for positioning (right =f=...) is deprecated. Use ofyshift` is also valid approach. – Zarko Jan 06 '22 at 14:29