17

I'm trying to calculate the size of a tikzpicture using the current bounding box, but every time I try to extract the coordinates I get 0pt (for everything).

enter image description here

\documentclass{article}
\usepackage{tikz}

\newlength{\mywidth}
\newlength{\myheight}

% computes width and height of tikzpicture

\newcommand{\pgfsize}[2]{ % #1 = width, #2 = height
 \pgfextractx{#1}{\pgfpointdiff{\pgfpointanchor{current bounding box}{south west}}
 {\pgfpointanchor{current bounding box}{north east}}}
 \pgfextracty{#2}{\pgfpointdiff{\pgfpointanchor{current bounding box}{south west}}
 {\pgfpointanchor{current bounding box}{north east}}}
}

\begin{document}

\noindent
\begin{tikzpicture}
\draw node[rotate=90]{
 \framebox{
 \begin{tabular}{c|c}
 first column & second column\\
 \hline
 1 & A\\
 2 & B\\
 $\vdots$ & $\vdots$
 \end{tabular}
}};
\draw[color=red] (current bounding box.south west) -- (current bounding box.north east);
\pgfsize{\mywidth}{\myheight}
\end{tikzpicture}

\noindent
Width = \the\mywidth \\
Height = \the\myheight
\end{document}

As you can see, one can draw a line across the bounding box, so it exists and is non-trivial. I'm thinking I may have to use \pgfgettransformentries, but when?

3
  • 1
    I think this issue is that you're setting \mywidth and \myheight locally, not globally. So outside of the tikzpicture, they'll both be 0pt. Commented Oct 11, 2013 at 6:49
  • Somehow related: How can I save the bounding box of a TikZpicture and use in other TikZpicture. In particular this answer seems relevant. Commented May 2, 2017 at 18:43
  • @anderstood - Actually, these days I just stick something is a savebox to measure it. Commented May 2, 2017 at 20:03

1 Answer 1

15

A. Ellet's comment is correct: it is a scope problem. Yes, \mywidth and \myheight are assigned a nonzero value within the scope of the tikzpicture environment, but, because those assignments are local, their value remains 0pt outside the scope of that environment.

You can fix the problem by making the assignments of \pgfsize's arguments global (rather than local) in the definition of that macro; see below. This post by Andrew Swan should also be of interest.

enter image description here

\documentclass{article}
\usepackage{tikz}
\show\pgfextractx

\newlength{\mywidth}
\newlength{\myheight}

% computes width and height of tikzpicture
\makeatletter
\newcommand{\pgfsize}[2]{ % #1 = width, #2 = height
 \pgfextractx{\@tempdima}{\pgfpointdiff{\pgfpointanchor{current bounding box}{south west}}
 {\pgfpointanchor{current bounding box}{north east}}}
 \global#1=\@tempdima
 \pgfextracty{\@tempdima}{\pgfpointdiff{\pgfpointanchor{current bounding box}{south west}}
 {\pgfpointanchor{current bounding box}{north east}}}
 \global#2=\@tempdima
}
\makeatother

\begin{document}

\noindent
\begin{tikzpicture}
\draw node[rotate=90]{
 \framebox{
 \begin{tabular}{c|c}
 first column & second column\\
 \hline
 1 & A\\
 2 & B\\
 $\vdots$ & $\vdots$
 \end{tabular}
}};
\draw[color=red] (current bounding box.south west) -- (current bounding box.north east);
\pgfsize{\mywidth}{\myheight}
\end{tikzpicture}

\noindent
Width = \the\mywidth \\
Height = \the\myheight
\end{document}
5
  • I don't understand why juggling with \mytemplength. Just saying \global#1=#1 is exactly the same. But I'd use a scratch register such as \@tempdima: \pgfextractx{\@tempdima}{...}\global#1=\@tempdima that avoids the bad practice of using both local and global assignments to a variable. Commented Oct 11, 2013 at 15:48
  • @egreg I used an intermediary variable because I though I would have trouble with recursion. Thanks for letting me know that my fears were unfounded. I'll improve my answer. Commented Oct 11, 2013 at 15:55
  • If you say \let\mytemplength\mywidth and \mywidth is allocated the skip register 43 (as in your example), doing \show\mytemplength will output \mytemplength=\skip43 and you simply end up with \global\skip43=\skip43. Commented Oct 11, 2013 at 15:59
  • @egreg Why skip register 43? What is so special about 43? Commented Oct 11, 2013 at 16:00
  • 1
    When you say \newlength\mywidth, TeX allocates to \mywidth a skip register. It's 43 just because the last allocated skip register was number 42; but the number is of no concern for the end user: it may change if you load a new package, for instance; the important thing is that it's fixed during a run of (La)TeX. You find the allocated registers in the .log file. Commented Oct 11, 2013 at 16:04

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.