# Scaling tikzpicture to fit on page with caption

I have a full page that I have managed to scale down with a \resizebox. Unfortunately, after I discovered this in a MWE, I put it back in my document and the caption is now in the footer...

How do I account for the caption in my resize box or include the caption within the resize box?

MWE:

\documentclass{article}

\usepackage[letterpaper, margin=0.5in, includefoot]{geometry} % Advanced page geometry configuation

\usepackage{fancyhdr} % Used for header and footer creation
\pagestyle{fancy}
\fancyhf{} % clear all fields
\lfoot{Lorem\\Ipsum}\cfoot{dolor sit\\amet \\ \thepage}\rfoot{Rev. \#\\ \today}

\usepackage{tikz} % Flowcharts

\renewcommand{\headrulewidth}{0.0pt} % removes line at top that comes w/ fancyhdr

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\usepackage{graphicx}
\usepackage{tikz}

\usetikzlibrary{shapes, arrows, positioning, calc, matrix}

% Define block styles
\tikzstyle{state}   = [ rounded rectangle,
draw,
text centered,
minimum height = 3em,
minimum width = 6em,
inner sep = 5pt
]
\tikzstyle{test}    = [ diamond,
draw,
shape aspect = 2,
inner sep = 0pt,
text width = 7em,
text centered
]
\tikzstyle{action}  = [ rectangle, draw,
text width = 8em,
inner sep = 5pt,
minimum height = 5em
]
\tikzstyle{data}    = [ trapezium,
draw,
trapezium left angle = 60,
trapezium right angle = 120pt,
minimum height = 6em,
text width = 5em,
inner xsep = 0pt
]
\tikzstyle{line}    = [ draw, -triangle 45 ]

\begin{document}

\begin{figure}[H]

\begin{center}
\resizebox{\textwidth}{\textheight}{%
\input{./flowchart.tex}
}
\caption{\textbf {My Stupid Flowchart} }

\end{center}

\end{figure}

\end{document}


Flowchart.tex:

\resizebox{\textwidth}{\textheight}{%
\begin{tikzpicture}[align = flush center, font = \small]

% Place nodes
\matrix [matrix of nodes, column sep = 0.5em, row sep = 1.3em,
draw, dotted,
nodes={solid},
matrix anchor=south east,
inner sep = 1em,
ampersand replacement=\&
] (state-mtrx)  at (0,0)
{
|[data] (a)| Lorem ipsum dolor sit amet, c \\
|[test] (b)| Lorem ipsum d \\
|[action] (c)| Lorem ipsum dolor sit amet, consectetur adipiscing\\
|[test] (d)| Lorem ipsum dolor  \\
|[action] (e)| Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque tempus nisl id  \\
|[test] (f)| Lorem ipsum dolor sit amet, \\
|[action] (g)| Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque tempus nisl id lectus\\
|[action] (h)| Lorem ipsum dolor sit amet, consectetur adipiscing eli \\[1em]
|[action] (j)| Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque tempus nisl id \\
[1em]\\
};

\matrix [matrix of nodes, column sep = 0.5em, row sep = 1.3em,
nodes = {solid},
draw, dotted,
matrix anchor=south west,
inner xsep = 3em,
ampersand replacement=\&
] (state-send-response) at (0,0)
{
\\
\\
\\
\&|[test] (i)| Lorem ipsum dolor? \\
\&|[test] (k)| ILorem ipsum dolor sit amet,? \\
\&|[action] (l)| Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque \\ [1em]
\&|[data] (m)| Lorem ipsum dolor sit amet, consect \\
|[state] (n)| Lorem ipsum dolor sit
\&|[state] (p)| Lorem ipsum dolor\\
};

\node[state, above = of a] (write) {WLorem ipsu};

\path [] ([shift={(-3mm, 0)}]state-mtrx.north west) -- ([shift={(-3mm, 0)}]state-mtrx.south west) coordinate(state-line);

\path let \p1=(state-line), \p2=($(a)!0.5!(b)$ ) in (\p2) -- node [left, very near end] {Lorem ipsum dolor} (\x1,\y2);
\path let \p1=(state-line), \p2=($(c)!0.5!(d)$ ) in (\p2) -- node [left, very near end] {Lorem ipsum dolor sit am} (\x1,\y2);
\path let \p1=(state-line), \p2=($(e)!0.5!(f)$ ) in (\p2) -- node [left, very near end] {Lorem ipsum dol} (\x1,\y2);
\path let \p1=(state-line), \p2=(g) in (\p2) -- node [left, very near end] {Lorem ipsum dolor} (\x1,\y2);
\path let \p1=(state-line), \p2=(h) in (\p2) -- node [left, very near end] {Lorem ipsum dolo\\Lorem ipsum dol} (\x1,\y2);
\path let \p1=(state-line), \p2=(j) in (\p2) -- node [left, very near end] {Lorem ipsum dolo} (\x1,\y2);

\node [above = 0em of state-send-response.north] {Lorem ipsum dolor s};

% Draw edges
% Dotted separators
\path [draw, dotted] let \p1=( $(b.south)!0.5!(c.north)$ ), \p2=(state-mtrx.north west), \p3=(state-mtrx.north east) in (\x2, \y1) -- (\x3, \y1);
\path [draw, dotted] let \p1=( $(d.south)!0.5!(e.north)$ ), \p2=(state-mtrx.north west), \p3=(state-mtrx.north east) in (\x2, \y1) -- (\x3, \y1);
\path [draw, dotted] let \p1=( $(f.south)!0.5!(g.north)$ ), \p2=(state-mtrx.north west), \p3=(state-mtrx.north east) in (\x2, \y1) -- (\x3, \y1);
\path [draw, dotted] let \p1=( $(g.south)!0.5!(h.north)$ ), \p2=(state-mtrx.north west), \p3=(state-mtrx.north east) in (\x2, \y1) -- (\x3, \y1);
\path [draw, dotted] let \p1=( $(h.south)!0.3!(j.north)$ ), \p2=(state-mtrx.north west), \p3=(state-mtrx.north east) in (\x2, \y1) -- (\x3, \y1);

% left State Paths
\path [line] (write) -- (a);

\path [line] (a) -- (b);

%% (d) paths - not in order because of reference point (d-no)
\path [line] (d) -- node [right, near start] {Yes} (e);
\path [line] (d.east) -- node [above, near start] {No} +(1.5,0)coordinate(d-no) -| (i);

\path [line] (b) -- node [right, very near start] {Yes} (c);
\path [line] (b) -| node [above, pos=0.02] {No} (d-no);

\path [line] (c) -- (d);

\path [line] (e) -- (f);

\path [line] let \p1=([shift={(2mm, 0)}]state-mtrx.west), \p2=(f.west) in (\p2) -- node [above, near start] {Yes} (\x1, \y2) |- ( $(h.south)!0.5!(j.north)$ );
\path [line] (f) -- node [right, near start] {No} (g);

\path [] (b.east) -- +(1,0)coordinate(copy-no);
\path [line] (j.south) |- ([shift={(2mm, 2em)}]state-mtrx.south east) -| (d-no);

\path [line] (g) -- (h);

\path [line] (h) -- (j);

% Response State paths
\path [line] (i.east) -- node [above, near start] {Yes} +(1,0) |- ( $(l.south)!0.3!(m.north)$ );
\path [line] (i.south) -- node [right] {No} (k);

\path [line] (k) -- node [right] {Yes} (l);
\path [line] (k.west) -| node [above, very near start] {No} (n);

\path [line] (l) -- (m);

\path [line] (m) -- (p);

\end{tikzpicture}
}

-
You really want to stick to tickstyle don't you? –  percusse Sep 21 '12 at 22:01
Ha... Yeah. I've got a tikz-style.tex file that I include to keep all my flowcharts in the same style. I read over the ideology behind the \tikset and I understand keeping the settings local, but to me that encourages modifcation of the base style instead of the specific entity (for a specific issue). And since I'm trying to keep the style as consistent as possible it makes more sense to use a global settings file. That and I find \tikstyle easier to read. –  blitzvergnugen Sep 24 '12 at 14:13

The following method puts the caption inside a box and measures its height. Then the value for the height of the \resizebox can be calculated.

• In flowchart I have removed the additional \resizebox. Also I have commented the line end after \end{tikzpicture}. We are in horizontal mode, that means that space contributes to the width. Also I have removed the space after\input{./flowchart.tex} for the same reason.

• I have added option showframe for package geometry to show the borders of the text body.

• \resizebox is not too accurate. Therefore I had wrapped the contents in the figure inside an additional \vbox with a small correction inside.

• \hspace{-0.3333em} cancels the inner sep of the left most text node.
Update: I have moved it to the file flowchart.tex, because it is a property of the flowchart. Just add the following line right before \begin{tikzpicture}:

\hspace*{-.3333em}% remove left inner sep from the leftmost text node

• \nointerlineskip prevents additional glue between the picture box and the caption box.

• Update: The flow chart is only scaled, if it overflows the available width or height.

The example file:

\documentclass{article}

\usepackage[showframe,letterpaper, margin=0.5in, includefoot]{geometry} % Advanced page geometry configuation

\usepackage{fancyhdr} % Used for header and footer creation
\pagestyle{fancy}
\fancyhf{} % clear all fields
\lfoot{Lorem\\Ipsum}\cfoot{dolor sit\\amet \\ \thepage}\rfoot{Rev. \#\\ \today}

\usepackage{tikz} % Flowcharts

\renewcommand{\headrulewidth}{0.0pt} % removes line at top that comes w/ fancyhdr

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\usepackage{graphicx}
\usepackage{tikz}

\usetikzlibrary{shapes, arrows, positioning, calc, matrix}

% Define block styles
\tikzstyle{state}   = [ rounded rectangle,
draw,
text centered,
minimum height = 3em,
minimum width = 6em,
inner sep = 5pt
]
\tikzstyle{test}    = [ diamond,
draw,
shape aspect = 2,
inner sep = 0pt,
text width = 7em,
text centered
]
\tikzstyle{action}  = [ rectangle, draw,
text width = 8em,
inner sep = 5pt,
minimum height = 5em
]
\tikzstyle{data}    = [ trapezium,
draw,
trapezium left angle = 60,
trapezium right angle = 120pt,
minimum height = 6em,
text width = 5em,
inner xsep = 0pt
]
\tikzstyle{line}    = [ draw, -triangle 45 ]

\newsavebox\captionbox
\newsavebox\flowchartbox
\newdimen\flowchartmaxheight
\newcommand*{\maxminipageheight}{%
\dimexpr\ifdim\height>\textheight\textheight\else\height\fi\relax
}

\begin{document}

\begin{figure}
\begin{minipage}[b][\maxminipageheight][c]{\textwidth}%
\sbox\captionbox{%
\parbox[b]{\textwidth}{%
\centering
\caption{\textbf {My Stupid Flowchart}}%
}%
}%
\sbox\flowchartbox{\input{flowchart}}%
\pgfmathsetlength{\flowchartmaxheight}{\textheight-\ht\captionbox}%
\ifdim\ht\flowchartbox>\flowchartmaxheight
\sbox\flowchartbox{%
\resizebox{!}{\flowchartmaxheight}{\box\flowchartbox}%
}%
\fi
\ifdim\wd\flowchartbox>\textwidth
\sbox\flowchartbox{%
\resizebox{\textwidth}{!}{\box\flowchartbox}%
}%
\fi
\centerline{\box\flowchartbox}%
\vspace{0pt minus .5pt}% fix for rounding errors in \resizebox
\nointerlineskip
\centerline{\box\captionbox}%
\end{minipage}%
\end{figure}

\end{document}


## Measuring positions

The second method uses package zref-abspage to measure the positions that are written to the .aux file first. In the second run, the correct positions are known and used.
Update: This example is not updated regarding the scaling behaviour.

\documentclass{article}

\usepackage[showframe,letterpaper, margin=0.5in, includefoot]{geometry} % Advanced page geometry configuation

\usepackage{fancyhdr} % Used for header and footer creation
\pagestyle{fancy}
\fancyhf{} % clear all fields
\lfoot{Lorem\\Ipsum}\cfoot{dolor sit\\amet \\ \thepage}\rfoot{Rev. \#\\ \today}

\usepackage{tikz} % Flowcharts

\renewcommand{\headrulewidth}{0.0pt} % removes line at top that comes w/ fancyhdr

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\usepackage{graphicx}
\usepackage{tikz}

\usetikzlibrary{shapes, arrows, positioning, calc, matrix}

% Define block styles
\tikzstyle{state}   = [ rounded rectangle,
draw,
text centered,
minimum height = 3em,
minimum width = 6em,
inner sep = 5pt
]
\tikzstyle{test}    = [ diamond,
draw,
shape aspect = 2,
inner sep = 0pt,
text width = 7em,
text centered
]
\tikzstyle{action}  = [ rectangle, draw,
text width = 8em,
inner sep = 5pt,
minimum height = 5em
]
\tikzstyle{data}    = [ trapezium,
draw,
trapezium left angle = 60,
trapezium right angle = 120pt,
minimum height = 6em,
text width = 5em,
inner xsep = 0pt
]
\tikzstyle{line}    = [ draw, -triangle 45 ]

\usepackage{zref-savepos}
\providecommand*{\zsaveposy}{\zsavepos}% support older zref-savepos

\newdimen\flowheight

\begin{document}

\begin{figure}
\vbox to \textheight{%
\centering
\makeatletter
\zsaveposy{flow-beg}%
\zref@refused{flow-beg}%
\setlength{\flowheight}{-\dimexpr\zposy{flow-end}sp-\zposy{flow-beg}sp\relax}%
\resizebox{\textwidth}{%
\ifdim\flowheight>0pt \flowheight\else .75\textheight\fi
}{%
\input{flowchart}%
}\par
\vss
\nointerlineskip
\zsaveposy{flow-end}%
\caption{\textbf {My Stupid Flowchart}}%
}
\end{figure}

\end{document}


-
Wow. That goes way over my head but works great for this situation. Unfortunately I have one chart that's getting stretched horizontally. Is there a way I can make the scaling only happen when the chart overflows? –  blitzvergnugen Sep 24 '12 at 13:43
I have changed the first example accordingly. –  Heiko Oberdiek Sep 24 '12 at 15:27
Awesome. Worked for me. I changed the \minipage's 3rd parameter to align w/ the top so it will be right below text on pages that allow it. EX: \begin{minipage}[b][\textheight][t]{\textwidth}% –  blitzvergnugen Sep 24 '12 at 16:42
I thought the charts should be on a page on its own. Then \textheight should not be used as height of the minipage. I have edited the answer to introduce \maxminipageheight. The natural height is used, except if the height exceeds \textheight. That catches the rounding error of \resizebox. –  Heiko Oberdiek Sep 24 '12 at 17:37
Sorry about the confusion. One area where a MWE is not ideal. Thanks for all the help. –  blitzvergnugen Sep 24 '12 at 19:19