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.

How can I make a node with zero size and node distance, such that a node that is positioned to the right of it lies on the same spot?

My solution to the first node in a node-drawing loop was to start with an invisible node, but I can't make it smaller. I'd be happy with a better solution, too.

enter image description here

\documentclass{standalone}
\usepackage{intcalc}
\usepackage{tikz}
\begin{document}
    \tikzstyle{frame} = [rectangle, draw, fill=blue!20,
        text width=2em, text centered, minimum height=2em, node distance=1.5cm]
    \begin{tikzpicture}
        \node (f0) {}; % This one is too big
        \foreach \framenum in {1,...,7}{
            \def\frameangle{\intcalcMul{ \intcalcDec{\intcalcMod{\framenum}{3}} }{8}} % 0, 8, -8, ...
            \def\lastframenum{\intcalcDec{\framenum}}
            \node [frame, right of=f\lastframenum] (f\framenum)
                {$f_\framenum$ $\frameangle^\circ$};
        }
    \end{tikzpicture}
\end{document}

Edit: Here is the result with \coordinate (f0) {}:

enter image description here

share|improve this question
7  
Use \coordinate instead of \node –  Jake Apr 26 '13 at 11:51
    
Thanks! There still seems to be some space left, but I don't think it will be noticeable. Do you know what's causing it? –  Tim N Apr 26 '13 at 11:56
4  
The line break after the end of the \tikzstyle adds a space character, add a % at the end of that line. I.e. ... node distance=1.5cm]%. Edit: forgot a reference: tex.stackexchange.com/questions/7453 –  Torbjørn T. Apr 26 '13 at 12:01
1  
By the way, the height of the boxes are not identical, as you've probably noticed. Increasing the minimum height to 2.7em fixes that. –  Torbjørn T. Apr 26 '13 at 12:10
2  
@TorbjørnT. While we're at it, here's another reference: Should \tikzset or \tikzstyle be used to define TikZ styles? — Besides that, \tikzset and \tikzstyle should go in the preamble (where they don't create spaces), when the assignments aren't local to one TikZ picture, in this case they should be used in the optional argument of the TikZ picture. –  Qrrbrbirlbel Apr 26 '13 at 12:10
add comment

1 Answer

up vote 7 down vote accepted

There were/are certain problems in your code:

The first one, as pointed out by Jake, was that you used a node where you should use a coordinate (which is a shape-less node, namely only a point).

Then, as pointed out by TorbjørnT., you inserted a spurious space at the end of \tikzstyle assignment. The \tikzstyle macro is long deprecated and should be replaced with the more flexible \tikzset. This wouldn't have helped with the space, though. I advice you to move any global assignments in the preamble where you don't have to take care of spaces. Is this style only used in this TikZ picture in your document, move its declaration to the optional argument of \begin{tikzpicture} (or use a \tikzset inside the environment where it normally doesn’t create a space either):

\begin{tikzpicture}[frame/.style={…, …}]

Then we have the right of syntax which is also deprecated. Use the positioning library and the right=of <lastnode> syntax.

You don’t even need this auxiliary code if you check inside the \foreach loop whether you have the first node or not:

\ifnum\framenum=1
    \node[frame] (f\framenum) {…};
\else
    \node[frame, right=of f\lastframenum] (f\framenum) {…};
\fi

There is also no need for the \intCalcDec macro, you have used the remember option of the \foreach loop:

\foreach \framenum[remember=\framenum as \lastframenum] in {1,...,7}{

or you could just do the calculation with eTeX’s \numexpr:

\node [frame, right=of f\number\numexpr\framenum-1\relax] (f\framenum) {…};

Take a look at reference 5 for a small overview on this topic.

While the intcalc package is surely a great package; PGF has a lot of mathematical functions built-in, which we can use in the evaluate option of the \foreach loop:

\foreach \frameNum[
    evaluate=\frameNum as \frameAngle using {int(8*(mod(\frameNum,3)-1))}
] in {1,...,7}

But why go through all that trouble when the TikZ’ chains library does all the work for us when we starta chain at the overlaying scope level (the tikzpicture implies a scope), and then set every node on this chain.

Without the frame style definition this becomes nearly a one-liner:

\begin{tikzpicture}[start chain]
    \foreach \frameNum[
        evaluate=\frameNum as \frameAngle using {int(8*(mod(\frameNum,3)-1))}
    ] in {1,...,7}
        \node [frame, on chain] (f\frameNum){$f_\frameNum$ $\frameAngle^\circ$};
\end{tikzpicture}

I also switched to the minimum size option (which sets minimum height and minimum width, and inserted an manual linebreak.

TorbjørnT. also detected that the height of the nodes is not always the same, and in fact the minus sign seems to add a depth to the last line. We can overwrite this by setting text depth to 0pt which will only work for the last line. For other cases, you can use the \smash macro and/or (provided by the amsmath package) the b option: $\smash[b]{\frameAngle^\circ}$.

References

  1. What is the use of percent signs (%) at the end of lines?
  2. Should \tikzset or \tikzstyle be used to define TikZ styles?
  3. Difference between "right of=" and "right=of" in PGF/TikZ
  4. Package PGF Math Error: Unknown operator `o' or `of' (it’s an overview of the positioning library)
  5. How to decrease the counter in tikz foreach loop

Code

\documentclass[tikz]{standalone}
\usetikzlibrary{chains,positioning}
\tikzset{
    frame/.style={
        rectangle,
        draw,
        fill=blue!20,
        align=center,
        minimum size=2\baselineskip,
        node distance=0.5cm
    }
}
\begin{document}
    \begin{tikzpicture}[start chain]
    \foreach \frameNum[
        evaluate=\frameNum as \frameAngle using {int(8*(mod(\frameNum,3)-1))}
    ] in {1,...,7}
        \node [frame, text depth=+0pt, on chain] (f\frameNum){$f_\frameNum$\\$\frameAngle^\circ$};
    \end{tikzpicture}
\end{document}

Output

enter image description here

share|improve this answer
    
Nicely composed answer! –  Gonzalo Medina Apr 26 '13 at 17:15
    
Thank you very much! I learnt a lot from this unexpected code review. I'll try to sneak unnecessary code into my future questions, too. –  Tim N Apr 26 '13 at 19:41
add comment

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.