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.

Consider this MWE:

\documentclass[varwidth]{standalone}

\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{positioning}

\pagecolor{yellow!15}
\begin{document}
\begin{tikzpicture}
\makeatletter
\pgfdeclareshape{testshape}{ %
  \inheritsavedanchors[from={rectangle}] %
  \inheritbackgroundpath[from={rectangle}] %
  \inheritanchorborder[from={rectangle}] %
  \foreach \x in {center,north,north east,north west,south,south east,south west,east,west}{ %
    \inheritanchor[from={rectangle}]{\x} %
  } %
  %\backgroundpath{} %
  \foregroundpath{ %
    \draw[] (\tikz@fig@name.south west) -- (\tikz@fig@name.north east)
      (\tikz@fig@name.north west) -- (\tikz@fig@name.south east);
  }
}
\makeatother

\tikzstyle{mynode} = [testshape,draw=gray,line width=2pt,inner sep=2pt, outer sep=5pt, minimum width=2cm,minimum height=0pt,align=center]

\node[mynode] (Starter) {Testing the node\\(a bit)};
\node[mynode] (Ender) [right=2cm of Starter] {Also test\\(even more)};

\node[mynode,draw=none] (tester) [below=2pt of Starter] {\phantom{Trying to measure this one}};

\path let \p1=(tester.north east), \p2=(tester.south west)
  in coordinate (testerSize) at (\x1-\x2,\y1-\y2);

\pgfpointanchor{testerSize}{center} % "returns"/sets a (last) pgfpoint
\pgfgetlastxy{\testerWidth}{\testerHeight} % ... and globalize:
\global\let\testerWidth\testerWidth
\global\let\testerHeight\testerHeight

\typeout{tester size is: \testerWidth\space X \testerHeight}

\end{tikzpicture}

tester size is: \testerWidth\ X \testerHeight

\end{document}

Here I'm trying to output the tester node invisibly, because I'm trying to measure its final size (btw, is there a more straightforward way to do that, than coordinate -> pgfpointanchor -> pgfgetlastxy?); however, as you can see on the output image:

test02.png

... I can't really hide it with draw=none, because it's a custom node - and if I try to draw it "offscreen" - the tikzpicture simply stretches and its dimensions are changed.

So is there a way to "draw" a node with all its styling "invisibly" for purposes of measurement, even if it is a custom shape in general, without these artefacts -- a "phantom" environment for TikZ nodes, so to speak?

share|improve this question

2 Answers 2

up vote 4 down vote accepted

In section 101.2.3 ("Deferred Node Positioning") of the manual for the latest PGF release is a set of commands for creating nodes and saving them for later. In this case you don't have to do anything with the node but can still get some properties of the node.

\documentclass[tikz,margin=3pt]{standalone}

\begin{document}

\newbox\mybox
\def\mysaver{%
\pgfmathparse{\pgfpositionnodelatermaxx-\pgfpositionnodelaterminx}%
\xdef\savednodewidth{\pgfmathresult pt}%
\pgfmathparse{\pgfpositionnodelatermaxy-\pgfpositionnodelaterminy}%
\xdef\savednodeheight{\pgfmathresult pt}%
}

\begin{tikzpicture}

\draw [help lines] (0,0) grid (3,2);

{
\pgfpositionnodelater{\mysaver}
% This node is clearly outside the grid
\node [minimum width=150pt, minimum height=75pt] at (20,20) {};
}

\node [align=left, fill=black!20, font=\ttfamily] at (1.5,1)
{
  \savednodewidth \\
  \savednodeheight
};
\end{tikzpicture}

\end{document}

enter image description here

share|improve this answer
    
Many thanks for the answer, @MarkWibrow ; that looks like a much better alternative to invisible layers. Cheers! –  sdaau Jun 26 at 5:36

Well, turned out it was easy - thanks to the Tex.SE auto-suggestion link TikZ Layer Invisible ; there, of course, it's a problem - but here it turned out to be solution :)

Basically - just declare a pgf layer, but don't set it - and it will keep everything you draw on it invisible; so with that, I get the output image:

test02a.png

... which is what I wanted. Here is the code:

\documentclass[varwidth]{standalone}

\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{positioning}

\pagecolor{yellow!15}
% just declare the layer, and don't do
% \pgfsetlayers ; then it will be invisible:
\pgfdeclarelayer{invisible}
\begin{document}
\begin{tikzpicture}
\makeatletter
\pgfdeclareshape{testshape}{ %
  \inheritsavedanchors[from={rectangle}] %
  \inheritbackgroundpath[from={rectangle}] %
  \inheritanchorborder[from={rectangle}] %
  \foreach \x in {center,north,north east,north west,south,south east,south west,east,west}{ %
    \inheritanchor[from={rectangle}]{\x} %
  } %
  %\backgroundpath{} %
  \foregroundpath{ %
    \draw[] (\tikz@fig@name.south west) -- (\tikz@fig@name.north east)
      (\tikz@fig@name.north west) -- (\tikz@fig@name.south east);
  }
}
\makeatother

\tikzstyle{mynode} = [testshape,draw=gray,line width=2pt,inner sep=2pt, outer sep=5pt, minimum width=2cm,minimum height=0pt,align=center]

\node[mynode] (Starter) {Testing the node\\(a bit)};
\node[mynode] (Ender) [right=2cm of Starter] {Also test\\(even more)};

\begin{pgfonlayer}{invisible}
\node[mynode] (tester) [at=(current bounding box.center)] {Trying to measure this one};
\end{pgfonlayer}

\path let \p1=(tester.north east), \p2=(tester.south west)
  in coordinate (testerSize) at (\x1-\x2,\y1-\y2);

% \pgfpointanchor{testerSize}{center} % "returns"/sets a (last) pgfpoint
\path(testerSize.center); % a bit easier than \pgfpointanchor: http://tex.stackexchange.com/a/33706/2595

\pgfgetlastxy{\testerWidth}{\testerHeight} % ... and globalize:
\global\let\testerWidth\testerWidth
\global\let\testerHeight\testerHeight

\typeout{tester size is: \testerWidth\space X \testerHeight}

\end{tikzpicture}

tester size is: \testerWidth\ X \testerHeight

\end{document}
share|improve this answer

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.