7

I've been working on a flow diagram or block diagram using Tikz to show a simplified camera transfer function. I've gotten as far as the code below, but I have a few questions remaining.

I started with this example, which uses a matrix for node layout. Please let me know if that was a bad starting point.

My questions are as follows

  1. How on earth do you make a simple square that won't deform when you put stuff in it, or at least will stay square. For the first block, I just wanted a square with a horizontal line through it. This turned complicated and I couldn't do it without a new tikz picture within the matrix, and even then there was some extra space after the node before the beginning of the arrow leaving it so I had to use negative space to remove it. Is there an easier way to do this?

  2. I found I couldn't just scale the Integral symbol because it's a math symbol which wants to resize itself. I had to use bigints package to do this. Is there some way via Tikz to just scale a symbol or text like that? So I could use a normal $\int$ and scale it with Tikz?

  3. In the the second-last block (empty right now), I would like a line similar to the first block, but that goes up in little steps like a stairway (specifically, like an ADC transfer function). Is there a way to do this? I thought maybe a sawtooth wave rotated 90 degrees or something.

  4. Why do the connecting lines seem to continue slightly past the end of the arrows so that the arrow tips are not sharp?

Thanks.

\documentclass{article}
\usepackage[a4paper, landscape]{geometry}
\usepackage{tikz}
\usepackage{bigints}
\usetikzlibrary{shapes.geometric,shapes.arrows,decorations.pathmorphing}
\usetikzlibrary{matrix,chains,scopes,positioning,arrows,fit}

\begin{document}

\begin{tikzpicture}[
tip/.style={->,shorten >=0.007pt}
]

  % Place all element in a matrix of nodes, called m
  \matrix (m) [matrix of nodes, 
    column sep=5mm,
    row sep=1cm,
    nodes={draw, % General options for all nodes
      line width=1pt,
      anchor=center, 
      text centered,
      sharp corners,
            minimum width=1.5cm, 
            minimum height=1.5cm,
            inner sep=0em,
    }, 
    % Define styles for some special nodes
    right iso/.style={isosceles triangle,scale=0.5,sharp corners, anchor=center, xshift=-4mm},
    txt/.style={text width=1.5cm,anchor=center},
    empty/.style={draw=none},
        noborder/.style={ draw=none,text width=1.5cm,anchor=center}     
    ]
  {
  % First row of symbols
            |[noborder]| {Input} 

  & 
|[empty]|{\begin{tikzpicture}[inner sep=0em]
                \node[draw, rectangle, minimum size=1.5cm]{};
                \draw (-.75,-.75) -- (.75,.75);
                    %\draw (0,0) -- (1.5,1.5);
            \end{tikzpicture}
        }
        \!\!\!\!
    & |[noborder]| {Output 1} 

    &   
    {$\bigints$}

    & |[noborder]| {Output 2} 

    & |[empty]|{\begin{tikzpicture}[inner sep=0em]
                \node[draw, rectangle, minimum size=1.5cm]{};
                \draw (-.75,-.75) -- (.3,.3) -- (.75,.3);
            \end{tikzpicture}
        }
        \!\!\!\!

    & % m-1-7
    |[noborder]| {Output 3} 

    & % m-1-8
    |[empty]|{\begin{tikzpicture}[inner sep=0em]
                \node[draw, rectangle, minimum size=1.5cm]{};
                \draw (-7.5mm,-7.5mm) -- (-6.5mm,-7.5mm);
                \draw (-6.5mm,-7.5mm) -- (-6.5mm,-6.5mm);
                \end{tikzpicture}
        }
        \!\!\!\!

    & |[noborder]| {Ouput 4} 

    & % m-1-10
    |[empty]|{\begin{tikzpicture}[inner sep=0em]
                \node[draw, rectangle, minimum size=1.5cm]{};
                \draw (-7.5mm,-6.5mm)  .. controls (-1.5mm,-7.5mm) and (1.5mm,7.5mm) ..  (7.5mm,6.5mm);
                \end{tikzpicture}
        }
        \!\!\!\!

    & |[noborder]| {Final \\ Output} 
  \\
  };  % End of matrix

  % Now, connect all nodes in a chain.
{ [start chain,every on chain/.style={join}, every join/.style={line width=1pt}]
        \chainin (m-1-1);
        \chainin (m-1-2) [join=by tip];
        \chainin (m-1-3) [join=by tip];
        \chainin (m-1-4) [join=by tip];
        \chainin (m-1-5) [join=by tip];
        \chainin (m-1-6) [join=by tip];
        \chainin (m-1-7) [join=by tip];
        \chainin (m-1-8) [join=by tip];
        \chainin (m-1-9) [join=by tip];
        \chainin (m-1-10) [join=by tip];
        \chainin (m-1-11) [join=by tip];
        };

\end{tikzpicture}
\end{document}
1
  • OK, I figured out the ADC stair-step at least. It can be done with the line decoration zigzag, as follows (in the second-last block's code): \draw [decorate, decoration=zigzag](-.75,-.75) -- (.75,.75);
    – SSilk
    May 6, 2011 at 1:08

1 Answer 1

12

Here's some answers:

  1. Use the regular polygon shape (with regular polygon sides=4) from the shapes.geometric library (which I see you are already using). Using this, I could draw the squares as you (presumably) wanted. I drew the extras in afterwards using the node anchors for positioning.

  2. You can scale nodes wholesale by specifying the scaling on the node itself. In this particular case you want to scape the contents but not the node shape. One way to do this is to double-up the node: draw an empty node initially and then go back later and put the contents in (scaled appropriately).

  3. You found the answer to this yourself. Excellent!

  4. I don't know why, but it's something to do with specifying the by option on the joins. I found that by putting the style in to the every join/.style={->} then the arrows were correct again. It's also nothing to do with the tip style as \draw[tip] (0,0) -- (1,0); works as it should. So presumably something in how the joins are rendered is preventing the automatic shortening that ought to happen when an arrow tip is added. If you can isolate this behaviour, it might be worth submitting it as a bug.

Here's my version of your code.

\documentclass{article}
\usepackage[a4paper, landscape]{geometry}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric,decorations.pathmorphing,matrix,chains,calc}

\begin{document}

\begin{tikzpicture}[
  % Define styles for some special nodes
  square/.style={
    draw,
    regular polygon,
    regular polygon sides=4,
    text width=1cm,
    minimum width=1cm,
    minimum height=1cm,
    inner sep=0em
  },
  line width=1pt,
  every on chain/.style={join},
  every join/.style={line width=1pt,->}
]

  % Place all element in a matrix of nodes, called m
  \matrix (m) [matrix of nodes, 
    column sep=5mm,
    row sep=1cm,
    nodes={ % General options for all nodes
      text centered,
      anchor=center,
      text width=1.5cm,
      sharp corners,
      minimum width=1.5cm, 
      minimum height=1.5cm,
      inner sep=.5ex,
      outer sep=0pt
    }, 
    ]
  {
  % First row of symbols
     {Input} 
  & 
|[square]|
    &  {Output 1} 

    & |[square]|

    &  {Output 2} 

    & |[square]|

    & % m-1-7
     {Output 3} 

    & % m-1-8
    |[square]|
    &  {Output 4} 

    & % m-1-10
    |[square]|
    &  {Final \\ Output} 
  \\
  };  % End of matrix

% Additional decorations

\draw (m-1-2.south west) -- (m-1-2.north east);
\draw (m-1-6.south west) -- ($(m-1-6.south west)!.7!(m-1-6.north east)$) -- ($(m-1-6.north east)!($(m-1-6.south west)!.7!(m-1-6.north east)$)!(m-1-6.south east)$);
\draw[decorate,decoration=zigzag] (m-1-8.south west) -- (m-1-8.north east);
\draw (m-1-10.south west) ++(0,1mm) .. controls +(6mm,-1mm) and +(-6mm,1mm) .. ($(m-1-10.north east)+(0,-1mm)$);

\node[scale=2] at (m-1-4) {$\int$};

  % Now, connect all nodes in a chain.
\begin{scope}[start chain]
\chainin (m-1-1);
\chainin (m-1-2);
\chainin (m-1-3);
\chainin (m-1-4);
\chainin (m-1-5);
\chainin (m-1-6);
\chainin (m-1-7);
\chainin (m-1-8);
\chainin (m-1-9);
\chainin (m-1-10);
\chainin (m-1-11);
\end{scope}
\end{tikzpicture}
\end{document}

With result

flowchart

2
  • This looks awesome, thanks very much. Now if I want to take that whole diagram and fit it into the linewidth in portrait mode (e.g. if I change the second line of your code to \usepackage[a4paper]{geometry} ), is there an easy way to do that? Ideally I'd like to be able to scale the non-text portions of the drawing separately from the text. Right now, I'm just familiar with resizebox, but shrinking it like that makes the labels difficult to read.
    – SSilk
    May 20, 2011 at 13:26
  • 1
    @SSilk: Try experimenting with scale factors in the tikzpicture environment itself: \begin{tikzpicture}[scale=.8] for example. (To clarify: this scales the picture without scaling the text.) May 20, 2011 at 16:45

You must log in to answer this question.

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