[Tex/LaTex] Flow (or block) diagram tips

diagramstikz-pgf

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}

Best Answer

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