Shifting a path horizontally between nodes

With the following extract, how can I x-shift the second edge (edge2) between n1 and n2 so that it doesn't overlap with the first? Also, is there a way to add text to each of the edges so that they don't overlap?

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{chains}
\usetikzlibrary{arrows}

\begin{document}
\begin{tikzpicture}
[node distance=0mm, text height=1.5ex, text depth=.25ex,
attribute/.style={rectangle,minimum size=8mm,very thin,draw=black!50,font=\ttfamily},
link/.style={thin, to path={-- ++(0,8mm) -| (\tikztotarget)}, >= triangle 45, shorten >= 0pt}]
\node (n1) [attribute] {\small NODE1};
\node (n2) [attribute, right=of n1] {\small NODE2};
\path (n1) edge [->, link] (n2);
\path (n1) edge [->, link] (n2); %this edge to x-shift
\end{tikzpicture}
\end{document}

-
In this cases its best to add a full but minimal example, i.e. here the \documentclass and the required packages etc., so that people can just copy&paste it to check if their solutions work properly and are able to provide example code and output. Especially TikZ code might require many libraries and it's not always clear which. –  Martin Scharrer Apr 9 '11 at 17:01

Shifting something in the x direction is done with the xshift option. However, by default, points referencing nodes are not shifted. For that one needs transform canvas:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{chains,arrows}

\begin{document}
\begin{tikzpicture}
[node distance=0mm, text height=1.5ex, text depth=.25ex,
attribute/.style={rectangle,minimum size=8mm,very thin,draw=black!50,font=\ttfamily},
link/.style={thin, to path={-- ++(0,8mm) -| (\tikztotarget)}, >= triangle 45, shorten >= 0pt}]
\node (n1) [attribute] {\small NODE1};
\node (n2) [attribute, right=of n1] {\small NODE2};
\path (n1) edge [->, link,transform canvas={xshift=-3mm}](n2);
\path (n1) edge [->, link,transform canvas={xshift=3mm}] (n2);
\end{tikzpicture}
\end{document}


Adding a description to an edge is usually done with just a node {...} after edge. However, your link style changes the to path and so TikZ doesn't know anymore where to put nodes. Thus one has to change the to path to include \tikztonodes at the right place (see section 14.14 “The To Path Operation” in the (v2.10) manual). To get correct placement it is also necessary to slightly change the way the path is drawn:

to path={-- ++(0,8mm) -- ($(\tikztotarget)+(0,8mm)$) \tikztonodes -- (\tikztotarget)}


Now, one can just add nodes as usual. To avoid overlapping, it might be necessary to add additional shifts:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{chains,arrows,calc}

\begin{document}
\begin{tikzpicture}
[node distance=0mm, text height=1.5ex, text depth=.25ex,
attribute/.style={rectangle,minimum size=8mm,very thin,draw=black!50,font=\ttfamily},
link/.style={thin, to path={-- ++(0,8mm) -- ($(\tikztotarget)+(0,8mm)$) \tikztonodes -- (\tikztotarget)}, >= triangle 45, shorten >= 0pt}]
\node (n1) [attribute] {\small NODE1};
\node (n2) [attribute, right=of n1] {\small NODE2};
\path (n1) edge [->, link,transform canvas={xshift=-3mm}] node[above,xshift=-1.5mm] {\small test} (n2);
\path (n1) edge [->, link,transform canvas={xshift=3mm}] node[above, xshift=1.5mm] {\small test 2} (n2);
\end{tikzpicture}
\end{document}


-

(A second and a third solution that I found later follow)

One solution (but I'm not sure it is the best) is to shift the starting points of the edge, as in this modified version of your code :

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{chains}
\usetikzlibrary{arrows}

\begin{document}
\begin{tikzpicture}
[node distance=0mm, text height=1.5ex, text depth=.25ex,
attribute/.style={rectangle,minimum size=8mm,very thin,draw=black!50,font=\ttfamily},
link/.style={thin, to path={-- ++(0,8mm) -| (\tikztotarget)}, >= triangle 45, shorten >= 0pt}]
\node (n1) [attribute] {\small NODE1};
\node (n2) [attribute, right=of n1] {\small NODE2};
\path (n1) edge [->, link] (n2);
\path[blue] (n1) edge [->,link, to path={($(\tikztostart)+(0.2,0.4)$) -- ++(0,5mm) -| ($(\tikztotarget)+(0.2,0.4)$)}, >= triangle 45] (n2);
\end{tikzpicture}
\end{document}


A second solution is to use transform canvas : (only the path to be modified is included in my code)

\path[blue, transform canvas={shift={(0.2,0)}}] (n1) edge [->,link, >= triangle 45] (n2);


The third solution is

\path (n1.70) edge [->,link, >= triangle 45] (n2.70);


the notation n1.70 indicates a point along the boundary obtained by rotation of 70 degrees from the east (counterclockwise).

(the last two solutions where obtained from parallel arrows)

The three solutions do not give exactly the same result.

-

I agree with the transform canvas solution, but another solution is :

1) to modify the use of the link style (the edge begins from a.north and finishes to b.north;

2) to add two arguments for this style #1 (pos=#1 for a label) and #2 the "height" of the edges and to add (mid) a coordinate on the edge (problem : pos=0 puts hte label at the first corner);

3) to use xshift.

\documentclass{scrartcl}
\usepackage{tikz}
\usetikzlibrary{arrows,positioning}

\begin{document}

\begin{tikzpicture}
[node distance=0mm, text height=1.5ex, text depth=.25ex,
attribute/.style 2 args={rectangle,minimum size=8mm,%
very thin,draw=black!50,font=\ttfamily},
link/.style 2 args={thin, to path={--++(0,#2) -| (\tikztotarget)%
coordinate[pos=#1] (mid)}, >= triangle 45, shorten >= 0pt}]
\node (n1) [attribute] {NODE 1};
\node (n2) [attribute, right=of n1] { NODE 2};
\path (n1.north) edge [->, link={0}{4mm}]  (n2.north)  ;
\node[above] at (mid){\footnotesize test 1};
\path[blue] ([xshift=.3cm]n1.north) edge [->, link={.5}{4mm}] ([xshift=.3cm]n2.north);
\node[blue,above] at (mid){\footnotesize test 2};
\end{tikzpicture}
\end{document}


-

You will find useful this example. Study it for the arm option.

-
Note that answers should be mostly self-contained. You could add the arm option into the above code to demonstrate how it solves the problem. –  Martin Scharrer Apr 9 '11 at 18:01