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.

When drawing connection lines (edge) between nodes, the lines will be drawn over the nodes (due to the drawing sequence). If having many connections, it may problematically cover the nodes, and particularly the text therein. A very basic example is

\documentclass{article}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}
   \node[fill=blue,circle,text width=3cm] (first) at (1,1) {First};
   \node[fill=green,circle,text width=3cm] (second) at (5,5) {This is the text that will be cover with the connection lines};
   \node[fill=purple,circle,text width=3cm] (third) at (1,9) {This text will be covered too};

\draw[->,thick,draw=red!50] (first.east) to [out=0,in=0] (third.east);
\draw[->,thick,draw=red!50] (first.west) to [out=180,in=75] (third.north east);
\end{tikzpicture}

\end{document}

enter image description here

Ideal Solution: Turning the connection lines around the node. In fact, the node area should be a forbidden zone for lines.

Practical Solution: Passing the lines under the nodes. At least lines will not affect readability of the text.

How to implement one of these solutions to avoid lines over nodes?

share|improve this question

2 Answers 2

up vote 13 down vote accepted

One solution (that could be put in the practical branch) is to use the backgrounds library.

The code is:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{backgrounds}
\begin{document}

\begin{tikzpicture}
\node[fill=blue,circle,text width=3cm] (first) at (1,1) {First};
\node[fill=green,circle,text width=3cm] (second) at (5,5) {This is the text that will be cover with the connection lines};
\node[fill=purple,circle,text width=3cm] (third) at (1,9) {This text will be covered too};
% insert connection lines in background 
\begin{pgfonlayer}{background}
\draw[->,thick,draw=red!50] (first.east) to [out=0,in=0] (third.east);
\draw[->,thick,draw=red!50] (first.west) to [out=180,in=75] (third.north east);
\end{pgfonlayer}
\end{tikzpicture}

\end{document}

The graphical result:

enter image description here

For details, see section 25 Background Library and section 82 Layered Graphics on the pgfmanual (version October 25, 2010).

EDIT

Following Andrew Stacey's suggestion, in the code there will be defined a new layer set before the main layer (to see it in background with respect to the main layer).

The modified code:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{backgrounds}
\pgfdeclarelayer{myback}
\pgfsetlayers{background,myback,main} 
% to still have the possibility of exploiting the background layer
\begin{document}

\begin{tikzpicture}
\node[fill=blue,circle,text width=3cm] (first) at (1,1) {First};
\node[fill=green,circle,text width=3cm] (second) at (5,5) {This is the text that will be cover with the connection lines};
\node[fill=purple,circle,text width=3cm] (third) at (1,9) {This text will be covered too};
% insert connection lines in background using myback layer
\begin{pgfonlayer}{myback}
\draw[->,thick,draw=red!50] (first.east) to [out=0,in=0] (third.east);
\draw[->,thick,draw=red!50] (first.west) to [out=180,in=75] (third.north east);
\end{pgfonlayer}
\end{tikzpicture}

\end{document}

will lead to the same graphical result shown above.

share|improve this answer
1  
very tricky and simple approach! –  All Jun 4 '12 at 11:15
4  
This would conflict with using the backgrounds library for what it was designed for - putting a background behind the whole picture. The same idea, but without this conflict, would be to declare a new layer for this purpose: \pgfdeclarelayer{back}\pgfsetlayers{back,main} then \begin{pgfonlayer}{back} instead of background. –  Loop Space Jun 4 '12 at 11:22
    
@AndrewStacey: A while ago you mentioned a sneaky badge... I think this one calls for it! :) –  Count Zero Jun 4 '12 at 11:55
    
Not tricky but very natural approach ! There are a lot of examples in the pgfmanual that use the predefined background and Andrew's remark is very important. Now if you want to add a background rectangle with for example [background rectangle/.style= {draw=blue!50,fill=blue!20,rounded corners=1ex}, show background rectangle], you need to declare \pgfsetlayers{background,myback,main} because background is not in the new list. –  Alain Matthes Jun 4 '12 at 13:10

Disclaimer: This is an overkill for this case. Please read the comments.

Another option would be to use append after command key to use the node name and location before it's drawn in the picture. Since the (second) node is not related to the (first) and (third) interaction it can be placed later.

\documentclass{article}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}
\node[fill=blue,circle,text width=3cm] (first) at (1,1) {First};
\draw[->,thick,draw=red!50] node[
     fill=purple,
     circle,
     text width=3cm,
     append after command={
           (first.west) to [out=180,in=75] (third.north east)
     }]
     (third) at (1,9) {This text will be covered too};

\draw[->,thick,draw=red!50] (first.east) to [out=0,in=0] (third.east);

\node[fill=green,circle,text width=3cm] (second) at (5,5) {This is the text that will be cover with the connection lines};
\end{tikzpicture}
\end{document}

enter image description here

share|improve this answer
    
The point here being that when a path is rendered, the path itself is drawn before the nodes so having them in the same command means that the nodes are drawn on top of the path. –  Loop Space Jun 4 '12 at 12:18
    
@AndrewStacey That's a better way of putting it. But still to able to draw the path before the node shape we need to know where the node is located and where its shape border lies. Obviously you don't need no intro but the interested can check the manual Section 75.2.3 for more info. –  percusse Jun 4 '12 at 12:24
    
Actually, in this case you don't need the append after command because you can just ... append it after the command. That is, you can write (first.west) to[out=180,in=75] (third.north east) after the (third) node is defined and the path will be drawn under the node. –  Loop Space Jun 4 '12 at 12:29
    
@AndrewStacey Bah, silly me. You are right. –  percusse Jun 4 '12 at 12:33
    
The specifics may be overkill, but the general principle is not: that as nodes are rendered after the main path, it is possible to use the node positions before they are placed to draw something underneath them. So just edit the answer to remove the unnecessary append after path and I think it's a fine answer. –  Loop Space Jun 4 '12 at 12:44

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.