TikZ: edge should not interfere with other elements in the graph and label positioning

I'm quite new to TikZ and I created the following graph:

\begin{tikzpicture}

\node[draw,circle] (n4) at (2, -3) {4};
\node[draw,circle] (n5) at (2, -4) {5};
\node[draw,circle] (n6) at (1, -5) {6};
\node[draw,circle] (n7) at (3, -5) {7};
\node[draw,circle] (n8) at (1, -6) {8};
\node[draw,circle] (n9) at (3, -6) {9};
\node[draw,circle] (n10) at (2, -7) {10};

\draw[->] (n4)--(n5) node[midway, right] {lengthy edge label 1};
\draw[->] (n5)--(n6) node[midway, left] {lengthy edge label 2};
\draw[->] (n5)--(n7) node[midway, right] {lengthy edge label 3};
\draw[->] (n6)--(n8) node[midway, left] {edge label 4};
\draw[->] (n7)--(n9) node[midway, right] {edge label 5};
\draw[->] (n9)--(n10) node[midway, right] {label 6};
\draw[->] (n8)--(n10) node[midway, left] {label 7};

\draw[->] (n10) -| +(4,0) -- +(4,0) node[midway, right]  {edge label 8} |- (n4);

\end{tikzpicture}


An image of the output can be found here:

It took me quite a while for this graph to build. However, I couldn't come up with a solution for the following questions:

• Is it possible to set the path of the edge from node 10 to node 4 in such a way that it automatically bypasses the rightmost "inner" label? In the example above I have to adjust the value in \draw to something like +(5,0) so that it doesn't interfere with "lengthy edge label 3", but this seems quite cumbersome if the graph changes frequently
• How can I place "edge label 8" in the middle of the vertical path segment?
• Is it possible to increase the distances between the nodes without having to assign new coordinate points to each node?

Any hint is appreciated.

-
Hi @moeso, welcome to TeX.sx!! :) –  Paulo Cereda Jun 7 '12 at 12:03
Hi @Paulo, Thank you both for including the image and for welcoming me :) –  moeso Jun 7 '12 at 12:05

I used another node (c) and I added sme styles.

\documentclass[11pt]{scrartcl}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}[y=1.5cm]

\begin{scope} [every node/.style={draw,circle}]
\node (n4) at (2, -3) {4};
\node (n5) at (2, -4) {5};
\node (n6) at (1, -5) {6};
\node (n7) at (3, -5) {7};
\node (n8) at (1, -6) {8};
\node (n9) at (3, -6) {9};
\node (n10)at (2, -7) {10};
\end{scope}

\begin{scope}[->,every node/.style={ right}]
\draw (n4)-- node{lengthy edge label 1} (n5);
\draw (n5)-- node[left] {lengthy edge label 2}(n6)  ;
\draw (n5)-- node (c) {lengthy edge label 3}(n7) ;
\draw (n6)-- node[left] {edge label 4}(n8)  ;
\draw (n7)-- node {edge label 5}(n9)  ;
\draw (n9)-- node {label 6}(n10) ;
\draw (n8)-- node[left] {label 7}(n10) ;
\end{scope}

\draw[->] (n10) -| (c.east) coordinate (d)  |-  (n4);
\node [right,anchor=west]  at (n7-|d) {edge label 8} ;

\end{tikzpicture}
\end{document}


update

The problem with positioning is to scale the picture. A possibility is to use

\begin{scope} [every node/.style={draw,circle}]
\path
( 2 ,-3)  node  (n4)  {4}
++  ( 0 ,-1)  node  (n5)  {5}
++  (-1 ,-1)  node  (n6)  {6}
++  ( 0 ,-1)  node  (n8)  {8}
++  ( 1 ,-1)  node  (n10) {10}
++  ( 1 , 1)  node  (n9)  {9}
++  ( 0 , 1)  node  (n7)  {7};
\end{scope}


and if you don't like the coordinates

 \def\dn{++( 0 ,-1)}   \def\up{++( 0 ,1)}
\def\rdn{++( 1 ,-1)}  \def\rup{++( 1 ,1)}
\def\ldn{++( -1 ,-1)} \def\lup{++( -1 ,1)}
\begin{scope} [every node/.style={draw,circle}]
\path
( 2 ,-3)  node  (n4)  {4}
\dn   node  (n5)  {5}
\ldn  node  (n6)  {6}
\dn   node  (n8)  {8}
\rdn  node  (n10) {10}
\rup  node  (n9)  {9}
\up   node  (n7)  {7};
\end{scope}

-
I added y=1.5cm to get some vertical space –  Alain Matthes Jun 7 '12 at 12:27
Awesome! Exactly what I was looking for. Thanks a lot. –  moeso Jun 7 '12 at 12:33

Also positioning library is suitable for such tasks...

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning}
\begin{document}
\begin{tikzpicture}[node distance=6mm and 5mm,] %You can individually assign x and y distances

\node[draw,circle] at (2, -3)         (n4) {4};
\node[draw,circle,below= of n4]       (n5) {5};
\node[draw,circle,below left= of n5]  (n6) {6};
\node[draw,circle,below right= of n5] (n7) {7};
\node[draw,circle,below= of n6]       (n8) {8};
\node[draw,circle,below= of n7]       (n9) {9};
\node[draw,circle,below left= of n9]  (n10) {10};

\draw[->] (n4)--(n5) node[midway, right] {lengthy edge label 1};
\draw[->] (n5)--(n6) node[midway, left] {lengthy edge label 2};
\draw[->] (n5)--(n7) node[midway, right] (l1) {lengthy edge label 3};
\draw[->] (n6)--(n8) node[midway, left] {edge label 4};
\draw[->] (n7)--(n9) node[midway, right] {edge label 5};
\draw[->] (n9)--(n10) node[midway, right] {label 6};
\draw[->] (n8)--(n10) node[midway, left] {label 7};

\draw[->] (n10) -| (l1.east)  node[midway,right]  {edge label 8} |- (n4);
\end{tikzpicture}
\end{document}


-
Thank you too, @percusse. I really like the way of the relative positioning of the nodes instead of assigning coordinate points. –  moeso Jun 7 '12 at 12:48
Why not simplify your code with styles and scopes? –  Alain Matthes Jun 7 '12 at 13:42
@Altermundus I think you have covered that with your answer, this is just to complement yours. –  percusse Jun 7 '12 at 13:45

Since the point How can I place "edge label 8" in the middle of the vertical path segment? wasn't fixed so far, my answer tries to address it.

Your initial midway in this case does not holds thus you can made use of the manual pos=.

For example:

% Basic code taken from percusse's answer
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning}
\begin{document}
\begin{tikzpicture}[node distance=6mm and 5mm]

\node[draw,circle] at (2, -3)         (n4) {4};
\node[draw,circle,below= of n4]       (n5) {5};
\node[draw,circle,below left= of n5]  (n6) {6};
\node[draw,circle,below right= of n5] (n7) {7};
\node[draw,circle,below= of n6]       (n8) {8};
\node[draw,circle,below= of n7]       (n9) {9};
\node[draw,circle,below left= of n9]  (n10) {10};

\draw[->] (n4)--(n5) node[midway, right] {lengthy edge label 1};
\draw[->] (n5)--(n6) node[midway, left] {lengthy edge label 2};
\draw[->] (n5)--(n7) node[midway, right] (l1) {lengthy edge label 3};
\draw[->] (n6)--(n8) node[midway, left] {edge label 4};
\draw[->] (n7)--(n9) node[midway, right] {edge label 5};
\draw[->] (n9)--(n10) node[midway, right] {label 6};
\draw[->] (n8)--(n10) node[midway, left] {label 7};

\draw[->] (n10) -| (l1.east)  node[pos=0.9,right]  {edge label 8} |- (n4);
\end{tikzpicture}
\end{document}


Of course, the positioning thanks to pos=0.9 also applies to the method shown by Altermundus in his answer.

-
I'm impressed - all my questions have been answered in a matter of minutes. Thank you too for your helpful contribution, @Claudio. –  moeso Jun 7 '12 at 13:00
Why not simplify your code with styles and scopes? –  Alain Matthes Jun 7 '12 at 13:41
@Altermundus: my answer actually just tries to address the edge positioning. I could have answered simply saying use node[pos=0.9,right], but I thought was better show the complete example. I chose @percusse's answer making there my small change and I saw that he answered you on motivations. –  Claudio Fiandrino Jun 7 '12 at 16:52
@ClaudioFiandrino: Nice! And if you use \draw[->] (n10) -- (n10-|l1.east) |- (n4) node[pos=0.25,right] {edge label 8}; (i.e. draw a straight line to the bottom right corner first, and only one |- line), the label is actually centered vertically, and not just approximately. –  Jake Jun 7 '12 at 17:06
@Jake: you are right. :) To be honest, this would never have come in my mind: many thanks. And you are right: I compared the two pictures with the two cases discovering that yours has really the perfect alignment (mine is slightly below). –  Claudio Fiandrino Jun 7 '12 at 17:21