# TikZ. Is there a way to alternate path to be drawn basing on some condition?

What I want is to connect nodes by stepped (horizontal-vertical-horizontal, hvh) path if they have different y-coordinate, and by straight line if they are on the same level.

Costruction of the only hvh-path in any case gives unwanted deviation of curve in the point where should stepping have happened as if nodes had different y-coordinate.

See below the LaTeX-code I try (there are also different ways I've tested that are commented out by now):

\documentclass[landscape]{article}

\usepackage{etoolbox, ifthen}
\usepackage{tikz}
\usetikzlibrary{scopes,chains,shapes.multipart,backgrounds,positioning,fit,calc}

\newcommand{\setup}{
\tikzset{
node distance=5mm and 3cm,
block/.style={rectangle, draw, thick},
every edge/.style={->, rounded corners, thick, draw,
to path={
let \p1=(\tikztostart.east),
\p2=($(\tikztostart.east) + (1cm,0)$),
\p3=(\tikztotarget.west) in
%\ifnumequal{\y1}{\y2}{(\p1) -- (\p3)}{(\p1) -- (\p2) |- (\p3)}
%(\p1) -- (\p2) \ifnumcomp{\y2}{=}{\y3}{-- (\p3)}{|- (\p3)}
%\ifthenelse{\equal{\y1}{\y2}}{(\p1) -- (\p3)}{(\p1) -- (\p2) |- (\p3)}
(\p1) -- (\p2) |- (\p3)
\tikztonodes
}
}
}
}

\begin{document}

\begin{tikzpicture}
\setup

\node[block] (A) {System A};
\node[block] (B) [above right=of A] {System B};
\node[block] (C) [right=of A] {System C};
\node[block] (D) [below right=of A] {System D};

\path
(A) edge (B)
edge (C)
edge (D);
\end{tikzpicture}

\end{document}


It is important that I want to keep the conciseness of the main code in tikzpicture environment. So the test of nodes being on the same level should be incapsulated somewhere inside the edge style (posibly .code?). There shouldn't be any such logic exposed in picture's main code, because I tend it to be declarative.

EDIT: Thanks to Altermundus and Martin Scharrer. I've ended up with following variant:

(\p1) -- (\p2) \ifdim\y2=\y3  -- \else |- \fi (\p3)

-
I feel like this would be a good use of a pgf decoration. But when I started to code it up I realized it would take more code then the answers you've already got. – Matthew Leingang Apr 7 '11 at 2:47

Perhaps this : (I don't know etoolbox) I modified the code with the help of Martin !

\newcommand{\setup}{
\tikzset{
node distance=5mm and 3cm,
block/.style={rectangle, draw, thick},
every edge/.style={->, rounded corners, thick, draw,
to path={
let \p1=(\tikztostart.east),
\p2=($(\tikztostart.east) + (1cm,0)$),
\p3=(\tikztotarget.west) in
\ifdim\y1=\y2   (\p1) -- (\p3) \else (\p1) -- (\p2) |- (\p3)\fi
(\p1) -- (\p2)
\ifdim\y2=\y3  -- (\p3) \else |- (\p3)\fi
(\p1) -- (\p2) |- (\p3)
\tikztonodes
}
}
}
}

-
You are comparing \y with 1 here. Note that \y, \x and \p are all macros which take the index as argument. The \y1 is short for \y{1} and you can also take any other label you want (within reason). Replace \ifx with \ifdim and put an = between the \yns and it might work. – Martin Scharrer Apr 6 '11 at 9:01
@Martin You are right ! I never use the facility \p1 ... I need to memorize your comment !! – Alain Matthes Apr 6 '11 at 9:06
@Altermundus your suggestion, concerning @Martin Scharrer's remarks, did the trick! – Dmitry Volosnykh Apr 6 '11 at 9:27
Well, I'm new to StackExchange, so I'm unsure whether should I accept Altermundus's solution or, contrary, having no needed result after direct application of his answer, it should be marked as unuseful? – Dmitry Volosnykh Apr 6 '11 at 9:33
Yeah, you got it :) – Dmitry Volosnykh Apr 6 '11 at 10:44