9

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}

2
  • define a /.pic
    – percusse
    Commented Feb 10, 2016 at 18:31
  • Wlecom to SE! It seems that the small pictures pic, described are in TikZ manual (v3.0.1a), chapter 18, page 251, is what you looking for. About it use as well number of different application you can find here, on SE.
    – Zarko
    Commented Feb 10, 2016 at 18:31

1 Answer 1

7

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}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .