4

I have the following graph, whose labels are generated in a for-loop:

\documentclass[tikz,margin=5mm]{standalone}
\usetikzlibrary{graphs,graphs.standard,quotes}

\usepackage{ifthen}

\begin{document}
\begin{tikzpicture}
\tikzstyle{vertex}=[circle,fill=blue!15,draw,minimum size=17pt,inner sep=0pt]

\graph[circular placement, radius=4cm, group polar shift=(360/5:0),
nodes={circle,draw,vertex}] {
    \foreach \x [evaluate=\x as \sx using int(\x+1)] in {0,...,4} {
      \foreach \y in {0,...,4} {
        \x -- \y;
        \x --["\ifthenelse{\sx<\y}{$\mathsf{alph}(w_{\sx} \cdots w_{\y})$}
                {\ifthenelse{\sx=\y}{$\mathsf{alph}(w_{\sx})$}{}}", sloped] \y;
      };
    };
  };
\end{tikzpicture}
\end{document}

The result is, that the labels

  • cross the graphs edges
  • overlap with other labels

The only thing I found out about this is, that automatic collision avoidance seems not to be available: Label automatically positioned so that it doesn't overlap anything.

Anyway, my example graph is not uncommon and somehow I should be able to place the labels in an acceptable way.

If there is no general way, what are possible solutions for this example?

I could think of the following positioning (including some resizing of the graph)

  • place the labels of the outmost edges on the outside
  • place the other labels in the pentagon in the middle

But I would not know how to achieve this.

  • It seems to me an automatic placement option for all the labels will produce some sort of overlap (or is very complicated). I suggest the not-so-elegant approach: take the labels out of the \foreach loop, make a separate command for each one, and use pos option (as in [...,pos=.5]) to make sure none overlap. – Jānis Lazovskis Jul 06 '14 at 08:16
  • New graph library tries to address this. Did you try those options? – percusse Jul 06 '14 at 10:06
  • Which options do you mean or where can I look it up? – user905686 Jul 06 '14 at 10:21

1 Answers1

5

Maybe it is better if you would position the nodes first and connect them afterwards:

\documentclass[tikz,margin=5mm]{standalone}
\usetikzlibrary{graphs,graphs.standard,quotes}

\usepackage{ifthen}

\begin{document}
\begin{tikzpicture}[
  vertex/.style={circle,fill=blue!15,draw,minimum size=17pt,inner sep=0pt},
  myedge/.style={sloped,font=\scriptsize},
  auto
  ]
% position the nodes
\graph[circular placement, radius=6cm, group polar shift=(360/5:0),nodes={circle,draw,vertex}]{%
  \foreach \x  in {0,...,4}\x};
% draw the edges
\foreach[evaluate={\sx=int(\x+1)},evaluate={\sxx=(int(\x+2)}] \x in {0,...,4} {
  \foreach \y in {\x,...,4} {
    \ifthenelse{\sx=\y}{\graph{(\x)--["\makebox[0pt]{$\mathsf{alph}(w_{\sx})$}",',myedge](\y)};}{%
      \ifthenelse{\sx<\y}{
        \ifthenelse{\sxx=\y}{\tikzset{d/.style={'}}}{\tikzset{d/.style={}}}
        \graph{(\x)--["\makebox[0pt]{$\mathsf{alph}(w_{\sx} \cdots w_{\y})$}",d,myedge](\y)};
      }{}}}}
\end{tikzpicture}
\end{document}

enter image description here

If it should be done in one \graph command try

\documentclass[tikz,margin=5mm]{standalone}
\usetikzlibrary{graphs,graphs.standard,quotes}

\usepackage{ifthen}

\begin{document}
\begin{tikzpicture}[
  vertex/.style={circle,fill=blue!15,draw,minimum size=17pt,inner sep=0pt},
  myedge/.style={sloped,font=\scriptsize},
  ]

\graph[circular placement, radius=6cm, group polar shift=(360/5:0),
nodes={circle,draw,vertex}] {
    \foreach \x [evaluate={\sx=int(\x+1)},evaluate={\sxx=(int(\x+2)}] in {0,...,4} {
      \foreach \y in {0,...,4} {
        \x --["\ifthenelse{\sx=\y}{\makebox[0pt]{$\mathsf{alph}(w_{\sx})$}}{
          \ifthenelse{\y=\sxx}{\makebox[0pt]{$\mathsf{alph}(w_{\sx} \cdots w_{\y})$}}{}}",',myedge] \y;
        \x --["\ifthenelse{\sx<\y \AND \NOT\y=\sxx}{\makebox[0pt]{$\mathsf{alph}(w_{\sx} \cdots w_{\y})$}}{}", myedge] \y;
      }
    }
  };
\end{tikzpicture}
\end{document}
esdd
  • 85,675
  • The result looks fine and the code looks quite compact, though a little complex (but that is possibly not avoidable). I think this is a good solution! – user905686 Jul 06 '14 at 10:23
  • @user905686 if you like the solution feel free to upvote the answer. If it also solves your problem consider accepting it, too. – cgnieder Jul 06 '14 at 12:38
  • @esdd I cannot use the tikzlibrary "graphs.standard". I suspect I have an old texlive version install. What is the minimum version of pgf/tikz I need for the library "graphs.standard"? – mrsteve Aug 11 '14 at 18:35
  • @mrsteve The code requires pgf/tikz version 3.0 – esdd Aug 11 '14 at 22:26