6

What is the best way to draw one arrow surrounded by two circular arrows (see image below). This is very easy to do when you have a small number of nodes, especially so when the arrows go from one anchor (ie. south east) to another anchor (ie. north west). Things become more complex when you have >10 incoming arrow triples. What's the most painless way to have the desired affect, without having to hard code the coordinates.


Here is a diagram I have drawn (MWE below) and you can see of the ones I have manually connected, nodes 2 and 4 look the best, but they are still a little too close. Nodes 1 and 3 I have intentionally botched to make a point: if one does not explicitly state the source coordinates, the line will be automatically placed at some location (in this case south of node 1, slightly east, or vice versa for Node 3). Node 5 shows how the default configuration is less than ideal, and node 6 shows that it completely failed.

Are there any experts out there that could tell me what I am doing wrong?

Diagram of different curved arrows

MWE:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{arrows,decorations.pathmorphing,backgrounds,positioning,fit,petri,calc,shadows}

\begin{document}

\begin{tikzpicture}[
    parent/.style={%
        rounded corners,
        thick,
        draw=red!75,
        fill=red!20,
        thick,
        inner ysep=2pt,
        inner xsep=2pt,
        minimum width = 4cm,
        minimum height = 1.5cm,
        align=center
    },
    child/.style={%
        rounded corners,
        thick,
        draw=blue!90,
        fill=blue!35,
        thick,
        inner ysep=2pt,
        inner xsep=2pt,
        minimum width = 4cm,
        minimum height = 1.5cm,
        align=center
    },
    grandchild/.style={%
        rounded corners,
        thick,
        draw=green!90,
        fill=green!35,
        thick,
        inner ysep=2pt,
        inner xsep=2pt,
        minimum width = 4cm,
        minimum height = 1.5cm,
        align=center
    },
    line/.style={%
        semithick,
        ->,
        shorten >=1pt,
        >=stealth'
    },
    call/.style={%
        blue,
        semithick,
        ->,
        shorten >=1pt,
        >=stealth'
    },
    return/.style={%
        red,
        semithick,
        ->,
        shorten >=1pt,
        >=stealth'
    }]
    \node[child] (child) {Child};
    \node[parent] at (-6,3) (parent 1) {Node 1\\I have manually\\connected this one};
    \node[parent] at (0,3) (parent 2) {Node 2\\I have manually\\connected this one};
    \node[parent] at (6,3) (parent 3) {Node 3\\I have manually\\connected this one};
    \node[parent] at (-6,-3) (grandchild 1) {Node 4\\I have manually\\connected this one};
    \node[parent] at (0,-3) (grandchild 2) {Node 5\\I have NOT manually\\connacted this one};
    \node[parent] at (6,-3) (grandchild 3) {Node 6\\I have NOT manually\\connacted this one};

    %draw three lines from each parent to each child
    \draw [line] (parent 1) -- (child.north west);
    \draw [line] (parent 2) -- (child);
    \draw [line] (parent 3) -- (child.north east);

    %draw three lines from each parent to each child
    \draw [line] (grandchild 1.north east) -- (child.south west);
    \draw [line] (grandchild 2) -- (child);
    \draw [line] (grandchild 3.north west) -- (child.south east);

    %Arrows to and from the child class to parent 1
    %This denotes the call (green) and return (red) flows
    \draw [call] (child.north west) to [auto,bend left] (parent 1.south) ;
    \draw [return] (parent 1.east) to [bend left] (child.north west);

    %Arrows to and from the child class to parent 2
    %This denotes the call (green) and return (red) flows
    \draw [call] (child.north) to [auto,bend left] (parent 2.south) ;
    \draw [return] (parent 2.south) to [bend left] (child.north);

    %Arrows to and from the child class to parent 3
    %This denotes the call (green) and return (red) flows
    \draw [call] (child.north east) to [auto,bend left] (parent 3.west) ;
    \draw [return] (parent 3.south) to [bend left] (child.north east);

    %Arrows to and from the child class to first grandchild
    %This denotes the call (green) and return (red) flows
    \draw [call] (child.south west) to [auto,bend left] (grandchild 1.north east) ;
    \draw [return] (grandchild 1.north east) to [bend left] (child.south west);

    %Arrows to and from the child class to second grandchild
    %This denotes the call (green) and return (red) flows
    \draw [call] (child) to [auto,bend left] (grandchild 2) ;
    \draw [return] (grandchild 2) to [bend left] (child);

    %Arrows to and from the child class to third grandchild
    %This denotes the call (green) and return (red) flows
    \draw [call] (child) to [auto,bend left] (grandchild 3) ;
    \draw [return] (grandchild 3) to [bend left] (child);

\end{tikzpicture}

\end{document}
4
  • I think the reason that it fails is because the style choice is not pleasing (personal opinion obviously). You can try to make the child a hexagon and use chamfered rectangle shape option for parents and grandchilds. Also I would not use reserved keys if I won't be using the tree structure explicitly. Lastly you are loading almost every possible library out there and you might not need most of them for this purpose.
    – percusse
    Feb 10, 2012 at 0:27
  • @percusse what are reserved keys? I think it's because I have copy pasted from other examples. Wrt. the libraries, It's because I am copy pasting the one from my main .tex file and I forgot to edit it for the MWE.
    – puk
    Feb 10, 2012 at 0:38
  • If you look at the manual Section 18.1 you will see that the names that you use for the styles etc. are also used for the tree structures. So if you happen to have some sort of a tree( which seems so) the name clash can cause further problems. That's what I wanted to draw your attention to.
    – percusse
    Feb 10, 2012 at 0:42
  • @percusse I see what you mean. I will prepend a letter/symbol to them.
    – puk
    Feb 10, 2012 at 0:44

1 Answer 1

4

you can create a node at each end of the lines and then connect these nodes. by adjusting the minimum size of node you can improve aesthetics.

(sorry for my google english)


\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{arrows,decorations.pathmorphing,backgrounds,positioning,fit,petri,calc,shadows}

\begin{document}

\begin{tikzpicture}[
    parent/.style={%
        rounded corners,
        thick,
        draw=red!75,
        fill=red!20,
        thick,
        inner ysep=2pt,
        inner xsep=2pt,
        minimum width = 4cm,
        minimum height = 1.5cm,
        align=center
    },
    child/.style={%
        rounded corners,
        thick,
        draw=blue!90,
        fill=blue!35,
        thick,
        inner ysep=2pt,
        inner xsep=2pt,
        minimum width = 4cm,
        minimum height = 1.5cm,
        align=center
    },
    grandchild/.style={%
        rounded corners,
        thick,
        draw=green!90,
        fill=green!35,
        thick,
        inner ysep=2pt,
        inner xsep=2pt,
        minimum width = 4cm,
        minimum height = 1.5cm,
        align=center
    },
    line/.style={%
        semithick,
        ->,
        shorten >=1pt,
        >=stealth'
    },
    call/.style={%
        blue,
        semithick,
        ->,
        shorten >=1pt,
        >=stealth'
    },
    return/.style={%
        red,
        semithick,
        ->,
        shorten >=1pt,
        >=stealth'
    }]
    \node[child] (child) {Child};
    \node[parent] at (-6,3) (parent 1) {Node 1\\I have manually\\connected this one};
    \node[parent] at (0,3) (parent 2) {Node 2\\I have manually\\connected this one};
    \node[parent] at (6,3) (parent 3) {Node 3\\I have manually\\connected this one};
    \node[parent] at (-6,-3) (grandchild 1) {Node 4\\I have manually\\connected this one};
    \node[parent] at (0,-3) (grandchild 2) {Node 5\\I have NOT manually\\connacted this one};
    \node[parent] at (6,-3) (grandchild 3) {Node 6\\I have NOT manually\\connacted this one};

    %draw three lines from each parent to each child
    \draw [line] (parent 1.south east)node[above left](p1){} -- (child.north west)node[below right](c1){};
    \draw [line] (parent 2.south)node[above](p2){} -- (child.north)node[below](c2){};
    \draw [line] (parent 3.south west)node[above right](p3){} -- (child.north east) node[below left](c3){};

    %draw three lines from each parent to each child
    \draw [line] (grandchild 1.north east)node[below left,minimum size=2em](p4){} -- (child.south west)node[above right,minimum size=2em](c4){};
    \draw [line] (grandchild 2.north)node[below,minimum size=2em](p5){} -- (child.south)node[above,minimum size=2em](c5){};
    \draw [line] (grandchild 3.north west)node[below right](p6){} -- (child.south east)node[above left](c6){};


\foreach \nn in{1,2,3,4,5,6}{
    \draw [call] (p\nn) to [bend right=15] (c\nn);
    \draw [return] (c\nn) to [bend right=15] (p\nn);
    }

\end{tikzpicture}

\end{document}!


the result

You must log in to answer this question.

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