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.

I'm producing some control theory flow sheets in TikZ where I have specified the node box size. Since I'm making a lot of these flow sheets, I have set global styles for them, for instance the box style I'm currently using:

box/.style={rectangle, draw, minimum width = 8ex,
            minimum height = 4ex, inner sep = 1ex}

The amount of text in the nodes varies. The problem is that if a node text is demanding more space than minimum, the rest of the nodes in that picture should keep the same size as the largest node. How can I do this? The solution in this question is one I would like to avoid, as it in my opinion is far too "manual", I need automation.

An MWE:

\documentclass[12pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}
\tikzset{
    box/.style={rectangle, draw, minimum width = 8ex,
                minimum height = 4ex, inner sep = 0},
    split/.style={circle, draw, minimum size = 2.5pt, fill=black,
                inner sep = 0},
}
\begin{document}
\begin{tikzpicture}[
    every path/.style={>={stealth}, ->, draw, node distance = 1pt, inner sep = 0pt},
    ]
    \node[split] (split)  {};
    \node[box] (I) at ($(split) + (4,0)$) {Short};
    \node[box] (P) at ($(I)+(0,1)$) {This node has long node text};
    \node[box] (D) at ($(I)+(0,-1)$) {Short};
    \draw (split.north) |-(P);
    \draw (split.east) -- (I) ;
    \draw (split.south) |-(D);

\end{tikzpicture}
\end{document}
share|improve this question
    
I'm no expert, but it sounds like you would need several passes for that... –  Jubobs Apr 6 '13 at 15:22
    
Or you have to measure the size of the largest text then use it in the minimum width declaration. Otherwise you have to read all nodes and then redraw which against automation idea. –  percusse Apr 6 '13 at 15:24
    
See my solution to a related problem that is close to what percusse is suggesting. –  Jubobs Apr 6 '13 at 15:30
    
I'll check later, but currently I'm thinking that you need fit library from tikz, I've answered about here some time ago. Maybe this helps. –  m0nhawk Apr 6 '13 at 15:40
    
@Jubobs Do you mean that I should provide the node text first, measure it, set minimum width and then produce the node with the predefined node text? –  Holene Apr 6 '13 at 16:02

1 Answer 1

up vote 11 down vote accepted

I think, this is nearly as automatic as it gets. It uses the .aux file.

You specify a family of nodes with Minimum Width which in turn measures the node from its east to its west anchor (so this works only for shapes where the minimum width equals the distance between those two anchors). Troublesome are the outer xseps (usually .5\pgflinewidth) which are added to minimum width. The work-around is to save the outer xsep in a special macro, this is done with \tikz@addmode so that you can change the line width after you specified the Minimum Width family in the options to the node.

The detour via \tikz@atend@picture is done to avoid having the .aux file filled up. The macro \csname\pgfpictureid @#1@#2@done\endcsname will vanish after the TikZ picture.

I have also used the positioning library which makes the effect more noticeable.

My node-families library also includes Minimum Height, Minimum Size as well as Text Height and Text Depth.

The code may be optimized a bit as for the example below eight additional macros are defined by the .aux file. It might be better to save all values from one family in one macro.

Code

\documentclass[12pt,tikz]{standalone}
\usetikzlibrary{positioning,node-families}
\begin{document}
\begin{tikzpicture}[
  node distance=.3cm and 1cm,
  box/.style={rectangle,draw,minimum width=+8ex,minimum height=+4ex,inner sep=+0pt},
  split/.style={circle,draw,minimum size=+2.5pt,fill=black,inner sep=+0pt}]
    \node[split] (split)  {};
    \node[box, Minimum Width=test, right=of split] (I)  {Short};
    \node[box, Minimum Width=test, above=of I]     (P)  {This node has long node text};
    \node[box, Minimum Width=test, below=of I]     (D)  {Short};
    \draw[-stealth] (split.north) |-(P);
    \draw[-stealth] (split.east) -- (I) ;
    \draw[-stealth] (split.south) |-(D);
\end{tikzpicture}
\tikz
  \foreach \cnt[count=\Cnt] in {a,...,h}
    \node[draw,circle, Minimum Height=test] at (right:\Cnt) {\cnt};
\tikz
  \foreach \cnt[count=\Cnt] in {a,...,h}
    \node[draw,circle, Text Height=test, text depth=+0pt, Minimum Height=test]
      at (right:\Cnt) {\cnt};
\begin{tikzpicture}[% http://tex.stackexchange.com/q/134983/16595
   nodes={circle, draw=black, Minimum Size=test, Text Height=test, Text Depth=test}]
  \node                 (A) {$n$};
  \node[right=0pt of A] (B) {$n+1$};
\end{tikzpicture}
\end{document}

Output

First compilation

enter image description here

Second compilation

enter image description here

Output (Examples)

enter image description here enter image description here enter image description here

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.