6

I am using TikZ to draw some graph drawings (with nodes and directed edges/paths). I have two nodes and an arrow pointing from one node to another. I have made a macro called \pathedge so I can use these arrows repeatedly, but its giving me some trouble. Whenever I put an xshift or a yshift option before any of the nodes on the \draw command it gives me an error. I am pretty sure it has something to do with using brackets '[' ']' in a \def macro but I don't know how to fix it. Here's the minimal code example:

\documentclass{article}

\usepackage{etoolbox}
\usepackage{tikz}

\def\conn{\draw[arrows=->, black!50, thick]}
\newcommand{\pathedge}[4]{
  \def\startn{#1}
  \def\endn{#2}
  \def\startnopts{}
  \def\endnopts{}

  \ifstrequal{#4}{NE_TO_SW} {
    \def\startn{[yshift=-1ex]#1.west} 
    \def\endn{[xshift=1ex]#2.north}
  } {}

  \conn (\startn) to node[shape=circle, fill=white, inner sep=0.5pt, font=\sffamily\footnotesize]{#3} (\endn);
}

\begin{document}
\begin{tikzpicture}[scale=1,innode/.style={draw, shape=circle,ultra thick,black}]
\node[innode] (1) at (2,2) {1};
\node[innode] (2) at (4,4) {2};

\pathedge{2}{1}{A}{NE_TO_SW}
\end{tikzpicture}
\end{document}
0

1 Answer 1

6

If I understand you correctly (and this is what the error messages suggest) you want a path from ([yshift=-1ex]#1.west) to ([xshift=1ex]#2.north). The error messages are

! Package pgf Error: No shape named [yshift=-1ex]2 is known.
! Package pgf Error: No shape named [xshift=1ex]1 is known.

The problem is expansion that is done by TikZ but too late. The TikZ path parser needs to see a literal [ which can be solved for the start coordinate with \expandafter(\startn) but that doesn’t work for the target node (because TikZ allows only nodes, coordinates, cycle and plot after -- as well as of course a coordinate).

Though, you can do

\newcommand{\pathedge}[4]{
  \def\startn{#1}
  \def\endn{#2}
  \def\startnopts{}
  \def\endnopts{}

  \ifstrequal{#4}{NE_TO_SW} {
    \def\startn{#1.west} 
    \def\endn{#2.north}
    \def\startnopts{yshift=-1ex}
    \def\endnopts{xshift=1ex}
  } {}
  \conn ([style/.expand once=\startnopts]\startn)
    to node[shape=circle, fill=white, inner sep=0.5pt, font=\sffamily\footnotesize]{#3}
      ([style/.expand once=\endnopts]\endn);
}

(Why don’t you use the .north east and .south west anchors directly?)

But to be honest, I would do this entirely different.

Code

\documentclass[tikz]{standalone}
\tikzset{
  conn/.style={arrows=->, black!50, thick,
    every to/.append style={edge node={
      node[shape=circle, fill=white, inner sep=0.5pt, font=\sffamily\footnotesize]{#1}}}},
  ne to sw/.style={
    to path={([yshift=-1ex]\tikztostart.west) --
             ([xshift=1ex]\tikztotarget.north)\tikztonodes}}}
\makeatletter
\tikzset{% from CVS version
  edge node/.code={\expandafter\def\expandafter\tikz@tonodes\expandafter{\tikz@tonodes #1}}}
\makeatother
\begin{document}
\begin{tikzpicture}[innode/.style={draw,shape=circle,ultra thick}]
\node[innode] (1) at (2,2) {1};
\node[innode] (2) at (4,4) {2};
\draw[conn=A] (2) to (1);
\end{tikzpicture}

\begin{tikzpicture}[innode/.style={draw,shape=circle,ultra thick}]
\node[innode] (1) at (2,2) {1};
\node[innode] (2) at (4,4) {2};
\draw[conn=A, ne to sw] (2) to (1);
\end{tikzpicture}
\end{document}
3
  • I really like the second solution ... thanks :)
    – ahmadh
    Sep 29, 2013 at 22:10
  • Can you explain to me the \makeatletter part?
    – ahmadh
    Sep 29, 2013 at 22:16
  • @ahmadh For \makeatletter and \makeatother, see What do \makeatletter and \makeatother do? The edge node key simply adds the code for a node to the internal macro that collects the nodes on an edge so that you can add nodes with a key. Sep 29, 2013 at 22:19

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .