[Tex/LaTex] Line up nested tikz enviroments or how to get rid of them

diagramstikz-pgf

In my diagram I have a few components I reuse a lot, thus making "macros" in tikz for them. The current code I have is using nested tikzpicture environments and is not exactly working as expected. Do you have any suggestions how to improve this?

I found other questions, but none seem to help me?

My code

\documentclass[]{article}

% tikz
\usepackage{tikz}
\usetikzlibrary{positioning} %relative positioning
\usetikzlibrary{fit} %box around multiople nodes
\usetikzlibrary{calc} %complex positioning
\usepackage{pgfplots}
\pgfplotsset{compat=1.12}

\begin{document}

\begin{tikzpicture}[
block/.style={draw},
container/.style={inner sep=0,},
]

\def\EDFA{
\begin{tikzpicture}[scale=0.25]
\draw (-1,1) --  (1,0) --  (-1,-1) -- (-1,1);
\node[anchor=north,inner sep=2pt] at (0,-1) {$1$};
\end{tikzpicture}
}


\node[block] (source) {Source};

\node[container,right= of source] (edfa) {\EDFA};

\node[block, right= of edfa] (sink) {Sink};

\draw[->] (source) -- (edfa);
\draw[->] (edfa) -- (sink);

\end{tikzpicture}

\end{document}

Update
I now have this code, is there a tex-ninja way to get rid of the helper coordinates?

\documentclass[]{standalone}

% tikz
\usepackage{tikz}
\usetikzlibrary{positioning} %relative positioning

\begin{document}

\tikzset{%
    EDFA/.pic={
        \begin{scope}[scale=.5, shift={(1,0)}]
        \draw (-1,0) coordinate (-in) --  (-1,1) -- (1,0) coordinate (-out) --  (-1,-1) -- cycle;
        \node[anchor=north,inner sep=2pt] at (0,-1) {EDFA};
        \end{scope}
    },
    Coupler/.pic={
        \begin{scope}[scale=.5, shift={(1,-1)}]
        \draw (-1,1) coordinate (-in1) to[out=0,in=180] (0,0) to[out=0,in=180] (1,1) coordinate (-out1);
        \draw (-1,-1) coordinate (-in2) to[out=0,in=180] (0,0) to[out=0,in=180] (1,-1) coordinate (-out2);
        \end{scope}
    }
}

\begin{tikzpicture}[
block/.style={draw},
]


\node[block] (source) {Source};

\path coordinate[right=of source] (helper a);
\draw (helper a) pic (edfa) {EDFA};

\path coordinate[right=of edfa-out] (helper b);
\draw (helper b) pic (coupler) {Coupler};


\node[block, right= of coupler-out1] (sink) {Sink};

\draw[->] (source) -- (edfa-in);
\draw (edfa-out) -- (coupler-in1);
\draw[->] (coupler-out1) -- (sink);

\end{tikzpicture}

\end{document}

Best Answer

As is explained in How do I draw shapes inside a tikz node? pics can be used for defining new objects. My main problem using pics is how to place where you want because they aren't nodes and positioning them is not so easy.

Following code shows how to define EDFA block.

    EDFA/.pic={
        \begin{scope}[scale=.5]
        \draw (-1,0) coordinate (in) --  (-1,1) -- (1,0) coordinate (out) --  (-1,-1) -- cycle;
        \node[anchor=north,inner sep=2pt] at (0,-1) {$1$};
        \end{scope}

In this case, coordinate (-1,0) will act as west anchor and 1,0 as east. Both point will have an special name for further reference. Every pic is placed according its own origin (0,0). You can use Claudio's answer to Anchoring TiKZ pics for better positioning.

As your example was simple, I'd prefer to star with EDFA and place Source and Sink after it.

\documentclass[]{article}

% tikz
\usepackage{tikz}
\usetikzlibrary{positioning} %relative positioning

\begin{document}

\tikzset{%
    EDFA/.pic={
        \begin{scope}[scale=.5]
        \draw (-1,0) coordinate (in) --  (-1,1) -- (1,0) coordinate (out) --  (-1,-1) -- cycle;
        \node[anchor=north,inner sep=2pt] at (0,-1) {$1$};
        \end{scope}
    }
}

\begin{tikzpicture}[
block/.style={draw},
]

\draw pic (edfa) {EDFA};

\node[block, left=of edfain] (source) {Source};

\node[block, right= of edfaout] (sink) {Sink};

\draw[->] (source) -- (edfain);
\draw[->] (edfaout) -- (sink);

\end{tikzpicture}

\end{document}

enter image description here

I understand that your components are more complex than EDFA because for this particular case an isosceles triangle node with a label will do the work and it can be used as a node and not as a pic:

\documentclass[]{article}

% tikz
\usepackage{tikz}
\usetikzlibrary{positioning} %relative positioning
\usetikzlibrary{shapes.geometric}

\begin{document}

\begin{tikzpicture}[
    block/.style={draw},
    edfa/.style={isosceles triangle, minimum width=1cm, 
         draw, anchor=west, isosceles triangle stretches, 
         minimum height=1cm, label=-80:#1}
]

\node[block] (source) {Source};

\node[edfa=1, right=of source] (edfa) {};

\node[block, right= of edfa] (sink) {Sink};

\draw[->] (source) -- (edfa);
\draw[->] (edfa) -- (sink);

\end{tikzpicture}

\end{document}