3

Hello (and sorry for bad English...)

I am working on a Tex document to produce algorithmic diagrams : it is quite good for me except that I would like to be able to reduce space used by leaves (it seems that tree works with a grid and some empty cells could be reused).

Here is the code (the algorithm does nothing interesting, it's only to show possible cases):

\documentclass{standalone}
\usepackage{tikz}
\usepackage{tikz-qtree}
\usetikzlibrary{shapes,arrows}
% styles
\tikzstyle{principal} = [draw,rectangle split, rectangle split horizontal=false,rectangle split parts=2,minimum height=5mm]
\tikzstyle{bloc} = [rectangle, draw, fill=blue!20,  text width=5em, text centered, rounded corners, minimum height=5mm]
\tikzstyle{decision} = [diamond, draw, fill=blue!20,    text width=4.5em, text badly centered, node distance=3cm, inner sep=0pt]
\tikzstyle{io} =[draw,trapezium,trapezium left angle=70,trapezium right angle=-70,minimum height=5mm]
\tikzstyle{op} = [rectangle, draw, text width=5em, text centered, minimum height=5mm]
\tikzstyle{sequence} = [draw, ellipse,fill=red!20, node distance=3cm, minimum height=5mm]
\tikzstyle{nop} = [ellipse,fill=red!5, node distance=3cm, minimum height=5mm]
% document
\begin{document}
\begin{tikzpicture}[level distance=3cm, 
sibling distance=2mm, thick,scale=0.9, 
every node/.style={scale=0.9, font=\large}]
\Tree 
[.\node[principal] {\nodepart{one}\shortstack{Principal}\nodepart{two}\shortstack{entier i,j\\reel j}};
     [.\node[sequence] {POUR} ;
        [.\node[decision]{\textsf{chaque i de 1 a 4 pas 1}};]
        [.\node[sequence] {\textsf{repeter}};
        [.\node [io] {\textsf{j $\leftarrow$ LIRE()}}; ]
    ]
  ] 
  [.\node[op] {\textsf{i $\leftarrow 1$}};]
 [.\node [sequence] {TQ} ;
    [.\node [decision] {\textsf{($i <= 4$)}};]
    [.\node [sequence] {\textsf{repeter}};
        [.\node [io] {\textsf{ECRIRE i}}; ]
    ]
 ] 
 [.\node[sequence] {SI} ;
    [.\node[decision] {\textsf{($i <= 10$)}};]
    [.\node[sequence] {\textsf{si vrai}};
        [.\node[op] {\textsf{j $\leftarrow 10$}};]
        [.\node[op] {\textsf{j $\leftarrow 10$}};]
        [.\node[op] {\textsf{j $\leftarrow 10$}};]
    ]
    [.\node[sequence] {\textsf{si faux}};
        [.\node[op] {\textsf{j $\leftarrow 12$}};]
        [.\node[op] {\textsf{j $\leftarrow 12$}};]
        [.\node[op] {\textsf{j $\leftarrow 12$}};]
     [.\node[sequence] {SI} ;
        [.\node[decision] {\textsf{($i <= 10$)}};]
        [.\node[sequence] {\textsf{si vrai}};
            [.\node[op] {\textsf{j $\leftarrow 10$}};]
        ]
        [.\node[sequence] {\textsf{si faux}};
            [.\node[op] {\textsf{j $\leftarrow 12$}};]
        ]
     ] 
    ]
 ] 
]  
\end{tikzpicture}
\end{document}

enter image description here Node placement could be closer to save space. Is there a possibility for some leaves to be alternatively under or above each other?

Are there special parameters that would allow that?

Many thanks for your help.

4
  • You can control the distance with the keys level distance= and sibling distance= (distance between leaves).
    – skpblack
    Jul 6 '14 at 19:25
  • Yes, you are right, I tried this, but "level distance" modify placement from a node to members, and "sibling distance" between brothers. As you can see, some nodes could be a bit more to the left to reduce the width of the entire diagram. Jul 6 '14 at 20:32
  • 1
    This is a perfect application for forest package which works on top of TikZ.
    – percusse
    Jul 7 '14 at 1:03
  • @percusse Do you know how to solve the error I found with using ellipse, child anchor=north, parent anchor=south and letting forest take care of the node sizes? (I've got an answer below but to really let forest lose, I had to take the ellipses out and I don't know why.
    – cfr
    Jul 7 '14 at 2:15
4

forest is much better at optimising the placement of nodes. Here is a comparison of the tree your code produces (on the right) and a first-pass attempt to create the tree in forest:

<code>forest</code> *vs.* <code>tikz-qtree</code>: node packing

First Pass

\documentclass{standalone}
\usepackage{forest}
\usetikzlibrary{shapes.geometric}
\begin{document}
\pgfkeys{/forest,
  principal/.append style={rectangle, minimum height=5mm},
  block/.append style={rectangle, fill=blue!20, text width=5em, rounded corners, minimum height=5mm},
  decision/.append style={diamond, fill=blue!20, text width=5em, inner sep=.5pt},
  io/.append style={trapezium, trapezium left angle=70,trapezium right angle=-70, minimum height=5mm},
  op/.append style={rectangle, text width=5em, minimum height=5mm},
  sequence/.append style={ellipse, fill=red!20, minimum height=5mm},
  nop/.append style={ellipse, fill=red!5, minimum height=5mm},
  sfstyle/.append style={font=\sffamily\large},
}
\begin{forest}
  for tree={
    thick,
    draw,
    scale=0.9,
    align=center,
    child anchor=north,
    parent anchor=south,
    every node/.style={font=\large},
  }
  [{Principal\\\hline entier i,j\\reel j}, principal
    [POUR, sequence
    [{chaque i\\de 1 a\\4 pas 1}, decision, sfstyle]
      [repeter, sequence, sfstyle
        [{j $\leftarrow$ LIRE()}, io, sfstyle ]
      ]
    ]
    [{i $\leftarrow 1$}, op, sfstyle]
    [TQ, sequence
      [{($i <= 4$)}, decision, sfstyle]
      [repeter, sequence, sfstyle
        [ECRIRE i, io, sfstyle ]
      ]
    ]
   [SI, sequence
      [{($i <= 10$)}, decision, sfstyle]
      [si vrai, sequence, sfstyle
          [{j $\leftarrow 10$}, op, sfstyle]
          [{j $\leftarrow 10$}, op, sfstyle]
          [{j $\leftarrow 10$}, op, sfstyle]
      ]
      [si faux, sequence, sfstyle
          [{j $\leftarrow 12$}, op, sfstyle]
          [{j $\leftarrow 12$}, op, sfstyle]
          [{j $\leftarrow 12$}, op, sfstyle]
       [SI, sequence
          [{($i <= 10$)}, decision, sfstyle]
          [si vrai, sequence, sfstyle
              [{j $\leftarrow 10$}, op, sfstyle]
          ]
          [si faux, sequence, sfstyle
              [{j $\leftarrow 12$}, op, sfstyle]
          ]
       ]
      ]
   ]
  ]
\end{forest}

\end{document}

first pass

Second Pass

This is not perfect but it turns more of the spacing and packing over to forest which results in a more compact tree. This did, however, throw up an error I'm unsure how to solve: the use of ellipse. If I try to tidy the tree with these styles, I get errors about exceeding TeX's maximum dimensions. If I try to delay the application of the node options (vaguely trying to follow an example on page 27), then everything goes nuts because I just get the node options literally stated in place of the node content. While I get ellipses, they are huge. I'm sure the solution will be obvious to a forest guru but for now, I've just gone with the shading. Alternatively, circles work fine. (Not clear why ellipses are problematic - trapezium: OK, diamond: OK, circle: OK, ellipse:??!!!??!!!). It seems to need minimum height etc. stated but it wants this for all the other nodes as well?!

\documentclass{standalone}
\usepackage{forest}
\usetikzlibrary{shapes.geometric}
\begin{document}
\pgfkeys{/forest,
  decision/.append style={diamond, fill=blue!20, text width=5em, inner sep=.5pt},
  io/.append style={trapezium, trapezium left angle=70,trapezium right angle=-70, minimum height=5mm},
  sequence/.append style={fill=red!20},
  nop/.append style={fill=red!5},
}
\begin{forest}
  for tree={
    child anchor=north,
    parent anchor=south,
    thick,
    draw,
    align=center,
    rounded corners,
    font=\sffamily\large,
  },
  [{Principal\\\hline \mbox{}\\[-1em]entier i,j\\reel j}
    [POUR, sequence
    [{chaque i\\de 1 a\\4 pas 1}, decision]
      [repeter, sequence
        [{j $\leftarrow$ LIRE()}, io ]
      ]
    ]
    [{i $\leftarrow 1$}, yshift=-1em]
    [TQ, sequence
      [{($i <= 4$)}, decision]
      [repeter, sequence
        [ECRIRE i, io ]
      ]
    ]
   [SI, sequence
      [{($i <= 10$)}, decision]
      [si vrai, sequence
          [{j $\leftarrow 10$}]
          [{j $\leftarrow 10$}]
          [{j $\leftarrow 10$}]
      ]
      [si faux, sequence
          [{j $\leftarrow 12$}]
          [{j $\leftarrow 12$}]
          [{j $\leftarrow 12$}]
       [SI, sequence
          [{($i <= 10$)}, decision]
          [si vrai, sequence
              [{j $\leftarrow 10$}]
          ]
          [si faux, sequence
              [{j $\leftarrow 12$}]
          ]
       ]
      ]
   ]
  ]
\end{forest}

\end{document}

second pass

If anybody knows how to use the ellipse properly, please leave a comment! Note that the conflict seems to involve the specification of child anchor, parent anchor with ellipse and without specifying height etc. for all nodes.

1
  • 1
    your solutions produce nice and clear diagram with compact code ! I will use the 2nd pass, it is more pleasant to read (code and diagram). Thanks a lot, it is perfect for me ! Jul 7 '14 at 5:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.