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 am very new to TikZ and I have trouble making a diagram similar to the one here:

enter image description here

My problems are specifically making MUX to get to inputs which would be on 1/3 and 2/3 of the width. Taking sigma signal outside of the border while still being above and to the right from the X block. Making all the lines bend with 90% to get to the final nodes. Adding the dX labels next to the operators.

My current code is:

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{positioning,intersections,shapes.geometric,fit,arrows,decorations.shapes,decorations.markings}

\begin{document}
\tikzstyle{register} = [rectangle, draw, text centered]
\tikzstyle{multiplexor} = [rectangle, draw, text centered, minimum width = 4em, minimum height = 2em]
\tikzstyle{operation} = [circle, draw, text centered, minimum size=3em]
\tikzstyle{port} = [pin edge={to->,thin,black}]

\begin{tikzpicture}[node distance = 5em, auto]

    \node (mux)     [multiplexor] {MUX};
    \node (delay)   [register, on grid, below of = mux] {Delay};
    \node (add_one) [operation, right of = mux] {$+1$};
    \node (mult)    [operation, on grid, below right of = add_one] {$\times$};
    \node (exp)     [operation, below of = mult] {$\exp$};
    \node (xmin)    [port, above of =  mux, xshift=-1em] {$x_{min}$};
    \node (sigma)   [port, above of = border, above right of = mult] {$sigma$};
    \node (addr)    [port, below of = border, below of = delay] {$address$};
    \node (data)    [port, below of = border, below of = mult] {$data$};

    \node (border) [draw,  dashed,inner sep=3pt,fit = (xmin) (exp)] {}; 

    \draw [->] (sigma)  |-  (mult);
    \draw [->] (xmin)   ->  ([xshift=-2em] mux);
    \draw [->] (add_one) -> (mux);
    \draw [->]  (mux) -> (delay);
    \draw [->] (mux) |- (add_one);
    \draw [->] (add_one) |- (mult);
    \draw [->] (delay) -> (addr);
    \draw [->] (mult) -> (exp);
    \draw [->] (exp) -> (data);

\end{tikzpicture}
\end{document}

which outputs:

enter image description here

Any help would be appreciated.

share|improve this question
3  
Hi azyzio and welcome to TeX.sx!. Please add a minimal working example (MWE) of what you have already tried. This is much easier than starting from scratch. –  Alexander Apr 23 '13 at 9:49
    
Thank you for the recommendation Alexander. I have added my MWE and the result I'm currently getting. –  azyzio Apr 23 '13 at 10:15

2 Answers 2

up vote 21 down vote accepted

For these kinds of drawings I'd first inspect which is the most convenient way to locate nodes: you positioned manually the nodes, but in this case I think the matrix library and consequently to position the nodes in a matrix fashion is really convenient.

But let's start first with the styles:

\tikzset{multiplexor/.style={rectangle, draw, align=center, minimum width = 6em, minimum height = 3em}}
\tikzset{register/.style={multiplexor,fill=gray!30}}
\tikzset{operation/.style={circle, draw, align=center, minimum size=3em}}
\tikzset{port/.style={pin edge={to->,thin,black}}}

\tikzset{matrix aspect/.style={matrix of nodes, nodes={outer sep=0pt,inner sep=3pt},column sep=3em,row sep=5ex}}

The first four are more or less yours styles (some differences are: changed a bit the dimensions, used the same base for multiplexor and register and convert \tikzstyle into \tikzset as per Should \tikzset or \tikzstyle be used to define TikZ styles?). The fifth style, instead, concerns the matrix aspect: remember to load the library with \usetikzlibrary{matrix}.

The matrix is the following:

\begin{tikzpicture}[every label/.style={font=\scriptsize}]
\matrix(dig-scheme) [matrix aspect]{
|[multiplexor]|MUX & |[operation]|$+1$ & \\
|[register]|Delay  &                                 & |[operation]|$\times$\\
                   &                                 & |[operation]|exp\\};
\end{tikzpicture}

Consider that with the option matrix of nodes each element has automatically a name in the form: matrix name - row number - column number. Each element, then inherits its own style with the syntax |[style]| and it is possible to omit each time \node{---}; again thanks to the option matrix of nodes.

Now, to locate the labels dx, where x is a,m,e, it is possible to exploit labels: in this case they are positioned with an angle of 10 degrees out of the node; if you want them exactly on the right, use the key right.

The label position phase goes like:

\foreach \name/\place in {da/1-2,dm/2-3,de/3-3}
\node[minimum size=2.5em,label={10:\name}] at (dig-scheme-\place){};

To reduce the labels' font size, in the option of the tikzpicture there's a way to set it in \scriptsize.

Until now, the diagram looks more or less like:

enter image description here

Before starting to connect the elements, I'd go to box the matrix: since its aspect has already been set within the style matrix aspect, the box can be introduced there without changing the picture's code.

\tikzset{matrix aspect/.style={
  matrix of nodes,   
  column sep=3em,
  row sep=5ex,
  draw,
  loosely dashed,
  inner xsep=2em,
  inner ysep=10ex,
  nodes={outer sep=0pt,inner sep=3pt,solid},
  }
}

The new options are:

  • draw: obvious;
  • loosely dashed: to customize the border aspect;
  • inner xsep=2em,inner ysep=10ex: to customize in a different way the horizontal and vertical distance of the matrix border from its content;
  • solid otherwise the internal elements of the matrix will inherit the dashed option.

The result is:

enter image description here

Let's pass now to depict the connections. They require the calc library, so load it.

I'd start with x_min:

\draw[<-] ($(dig-scheme-1-1.north west)!0.3!(dig-scheme-1-1.north east)$)
 --++(0,1) coordinate[label=above:$x_{\min}$];

This is saying that the starting point is the position of the element 1-1 of the matrix placed at 1/3 (from left to right -> north west to north east) going up for 1 cm from there. The text is written through the "label syntax" such that no sort of customization on the font size should be done since it has already been done before with every label/.style={font=\scriptsize}.

Instead, to connect the multiplexer with the element on his right, the following style is needed:

% adapted code from Azetina:
% http://tex.stackexchange.com/questions/76060/combine-two-tikzmark-solutions
\tikzset{square arrow/.style={to path={-- ++(0,1) -| (\tikztotarget)}}}

while the actual connection is:

\draw[<-,square arrow] ($(dig-scheme-1-1.north east)!0.3!(dig-scheme-1-1.north west)$)to (dig-scheme-1-2);

To get exactly the point, 2/3 from left to right, I just inverted the anchors of the multiplexer in the previous connection.

Now it looks:

enter image description here

Proceeding a bit faster, to locate the x and then connect this midway point to the +1 node, one could do:

\draw[->] (dig-scheme-1-1)--(dig-scheme-2-1) node[coordinate,midway,label={left:$x$}](x){};
\draw[->] (x) -| (dig-scheme-1-2) node[coordinate,inner sep=0pt, pos=0.45](y){};

Notice the (y) is the other midway point; with:

\draw[->] (y) |- (dig-scheme-2-3);
\draw[->] (dig-scheme-2-3)--(dig-scheme-3-3);
\draw[->] (dig-scheme-3-3)--($(dig-scheme-3-3 |- dig-scheme.south east)-(0,1)$) coordinate[label=below:data];

it is possible to connect it to \times node and to set also the connection from \times to exp and from exp to the bottom adding the label data. Notice the syntax:

($(dig-scheme-3-3 |- dig-scheme.south east)-(0,1)$)

This says that the final point is computed as the intersection of the element and the south east anchor of the matrix; after that, it is shifted down by 1cm.

Another important thing to be highlighted is that both "middle" points are defined through node[coordinate,...,]: this is because coordinates do not introduce additional space (for a more detailed explanation see TikZ: difference between \node and \coordinate?).

enter image description here

Replicating this concept to:

\draw[->] (dig-scheme-2-1)--($(dig-scheme-2-1 |- dig-scheme.south west)-(0,1)$) coordinate[label=below:address];

allows to have both data and address on the same level.

Finally, we missed just sigma:

\draw[<-] (dig-scheme-2-3.east) -| ($(dig-scheme-2-3.east |- dig-scheme.north east)+(0.5,1)$) coordinate[label=above:sigma];

This is similar to what did before, but we need some horizontal space, the 0.5 to have exactly the connection desired.

BTW: just realize that we need some more horizontal space between the matrix content and border, so the inner xsep=2em should become inner xsep=3em.

enter image description here

The complete code for reference:

\documentclass[tikz,png,border=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc,matrix}

\tikzset{multiplexor/.style={rectangle, draw, align=center, minimum width = 6em, minimum height = 3em}}
\tikzset{register/.style={multiplexor,fill=gray!30}}
\tikzset{operation/.style={circle, draw, align=center, minimum size=3em,outer sep=0pt}}
\tikzset{port/.style={pin edge={to->,thin,black}}}

% code from Azetina:
% http://tex.stackexchange.com/questions/76060/combine-two-tikzmark-solutions
\tikzset{square arrow/.style={to path={-- ++(0,1) -| (\tikztotarget)}}}

\tikzset{matrix aspect/.style={
  matrix of nodes,   
  column sep=3em,
  row sep=5ex,
  draw,
  loosely dashed,
  inner xsep=3em,
  inner ysep=10ex,
  nodes={outer sep=0pt,inner sep=3pt,solid},
  }
}

\begin{document}
\begin{tikzpicture}[every label/.style={font=\scriptsize},>=stealth]
\matrix(dig-scheme) [matrix aspect]{
|[multiplexor]|MUX & |[operation]|$+1$ & \\
|[register]|Delay  &                                 & |[operation]|$\times$\\
                   &                                 & |[operation]|exp\\};
\foreach \name/\place in {da/1-2,dm/2-3,de/3-3}
\node[minimum size=2.5em,label={10:\name}] at (dig-scheme-\place){};

\draw[<-] ($(dig-scheme-1-1.north west)!0.3!(dig-scheme-1-1.north east)$)
 --++(0,1) coordinate[label=above:$x_{\min}$];
\draw[<-,square arrow] ($(dig-scheme-1-1.north east)!0.3!(dig-scheme-1-1.north west)$)to (dig-scheme-1-2);

\draw[->] (dig-scheme-1-1)--(dig-scheme-2-1) node[coordinate,midway,label={left:$x$}](x){};
\draw[->] (x) -| (dig-scheme-1-2) node[coordinate,inner sep=0pt, pos=0.45](y){};
\draw[->] (y) |- (dig-scheme-2-3);
\draw[->] (dig-scheme-2-3)--(dig-scheme-3-3);
\draw[->] (dig-scheme-3-3)--($(dig-scheme-3-3 |- dig-scheme.south east)-(0,1)$) coordinate[label=below:data];

\draw[->] (dig-scheme-2-1)--($(dig-scheme-2-1 |- dig-scheme.south west)-(0,1)$) coordinate[label=below:address];

\draw[<-] (dig-scheme-2-3.east) -| ($(dig-scheme-2-3.east |- dig-scheme.north east)+(0.5,1)$) coordinate[label=above:sigma];
\end{tikzpicture}
\end{document}
share|improve this answer
    
note that x_{min} should probably be x_{\min}. –  pluton Apr 23 '13 at 14:39
5  
+1 for Claudio, who turns every answer into a full-blown tutorial :-) –  Daniel Apr 23 '13 at 16:28
    
@pluton: yes, probably looks better: revising the answer I'll used that way. Thanks :) –  Claudio Fiandrino Apr 23 '13 at 16:55
1  
@Daniel: thank you :) I think for these kind of drawings explaining a bit more the work is really beneficial for new users. –  Claudio Fiandrino Apr 23 '13 at 16:57
    
Thank you very much for this answer / tutorial. I think it made internet a better place :) –  azyzio Apr 23 '13 at 23:53

Only a partial answer: getting the "1/3" and "2/3" anchors is tricky as things stand, but, if you don't mind hacking (and I would like to encourage it), it is fairly straightforward to add anchors to the rectangle shape.

Hopefully it is obvious what must be changed to rename the anchors to something more catchy.

\documentclass{standalone}
\usepackage{tikz}

\makeatletter

\expandafter\def\csname pgf@anchor@rectangle@one third north west\endcsname{%
    % The \southwest and \northeast macros are automatically defined.
    % We need to set \pgf@x and \pgf@y (which are both TeX dimensions)
    % to the approriate coordinates for the anchor.
    %
    % For the X coordinate this is simply 2/3*SW_X + 1/3*NE_X,
    % (where SW_X is the X coordinate of the south west point and
    % NE_X is the coordinate of the north west point).
    %
    % The Y coordinate is provided by the \northeast macro.
    %
    \pgf@process{\southwest}%
    \pgf@xa=0.66666\pgf@x%
    \pgf@process{\northeast}%
    \pgf@x=0.33333\pgf@x
    \advance\pgf@x by\pgf@xa
}

\expandafter\def\csname pgf@anchor@rectangle@one third north east\endcsname{%
    % Similar to above except the X coordinate is 1/3*SW_X + 2/3*NE_X.
    \pgf@process{\southwest}%
    \pgf@xa=0.33333\pgf@x%
    \pgf@process{\northeast}%
    \pgf@x=0.66666\pgf@x%
    \advance\pgf@x by\pgf@xa
}

\makeatother
\begin{document}
\begin{tikzpicture}

\draw [help lines] grid (3, 2);
\node [draw, shape=rectangle, minimum width=3cm]  at (1.5,1)(rectangle) {A rectangle};

\draw [->] (0,1.75) -| (rectangle.one third north west);
\draw [->] (3,1.75) -| (rectangle.one third north east);

\end{tikzpicture}

\end{document}

enter image description here

I should also add a caveat: if you set the outer xsep to something large this will mess up the positioning. But! With more hacking (a bit more involved this time), we can take this into account (the result is the same as before).

    \documentclass{standalone}
\usepackage{tikz}

\makeatletter

\expandafter\def\csname pgf@anchor@rectangle@one third north west\endcsname{%
    \pgf@process{\southwest}%
    % Add the outer xsep
    \advance\pgf@x by\outerxsep\relax%
    \pgf@xa=0.66666\pgf@x%
    \pgf@process{\northeast}%
    % Subtract the outer xsep
    \advance\pgf@x by-\outerxsep\relax%
    \pgf@x=0.33333\pgf@x
    \advance\pgf@x by\pgf@xa
}

\expandafter\def\csname pgf@anchor@rectangle@one third north east\endcsname{%
    % Similar to above except the X coordinate is 1/3*SW_X + 2/3*NE_X.
    \pgf@process{\southwest}%
    % Add the outer xsep
    \advance\pgf@x by\outerxsep\relax%
    \pgf@xa=0.33333\pgf@x%
    \pgf@process{\northeast}%
    % Subtract the outer xsep
    \advance\pgf@x by-\outerxsep\relax%
    \pgf@x=0.66666\pgf@x%
    \advance\pgf@x by\pgf@xa
}
\pgfutil@g@addto@macro\pgf@sh@s@rectangle{\pgf@sh@resaveddimen{\outerxsep}{\pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/outer xsep}}}}

\makeatother
\begin{document}
\begin{tikzpicture}

\draw [help lines] grid (3, 2);
\node [draw, shape=rectangle, minimum width=3cm, outer xsep=1cm]  at (1.5,1)(rectangle) {A rectangle};

\draw [->] (0,1.75) -| (rectangle.one third north west);
\draw [->] (3,1.75) -| (rectangle.one third north east);

\end{tikzpicture}

\end{document}
share|improve this answer
    
Thank you for the answer mark. I have tried it and it works perfectly fine. I cannot however place nodes directly above the anchors. I.e. \node (xmin) [port, above of = mux.input1] $x_{min}$}; doesn't work. Am I doing something wrong? –  azyzio Apr 23 '13 at 12:19
1  
As long as you have \usetikzlibrary{positioning} in your preamble, then you can say above=of mux.input1 (i.e., with of the other side of =). See "Advanced Placement Options" in the manual (section 16.5.3 in the 2.10 manual). –  Mark Wibrow Apr 23 '13 at 12:39

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.