There's a good chance some more elegant solution will appear soon, but here goes:
By using the calc
library you can add node halfway between sensors
and resources
, and position information
with relation to this. I actually used the corners of these, resources.south west
and sensors.north west
, and put the new node midway between these.
One way is to use relative coordinates to first go a little right of processing
, then up, left to planning
. By using |-
/-|
you can access coordinates that lie on the intersection of the horizontal line from one node and vertical line from another. That way you can end the arrow directly above sensors.north east
, for example.
I first add a new node, lowerright
while drawing the line from resources
to planning
. (lowerright |- container.east)
is the point that lies on the vertical line from lowerright
and the horizontal line from container.east
. Similar for (container.east -| resources.south east)
.
You can add a node above the top left corner of container
.
Add inner sep=<dimension>
to the container node, instead of defining width and height. This sets the distance from the contents of the node to the edge of the node.
![enter image description here](https://i.stack.imgur.com/adECb.png)
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{fit,arrows,calc,positioning}
\begin{document}
\tikzstyle{b} = [rectangle, draw, fill=blue!20, node distance=3cm, text width=6em, text centered, rounded corners, minimum height=4em, thick]
\tikzstyle{c} = [rectangle, draw, inner sep=0.5cm, dashed]
\tikzstyle{l} = [draw, -latex',thick]
\begin{tikzpicture}[auto]
\node [b] (planning) {Planning};
\node [b, below=of planning] (resources) {Resources};
\node [b, below=of resources] (sensors) {Sensors};
\coordinate (RSmid) at ($(resources.south west)!0.5!(sensors.north west)$);
\node [b, left=of RSmid, node distance=4cm] (information) {Information system};
\node [b, below=of sensors] (processing) {Processing};
\node [c,fit=(resources) (sensors)] (container) {};
\path [l] (planning) -- (resources);
\path [l] (resources) -- (sensors);
\path [l] (sensors) -- (processing);
\path [l] (information) |- (planning);
\path [l] (information) |- (processing);
\node at (container.north west) [above right] {Desc};
\draw [l] (processing.east) -- ++(2,0) node(lowerright){} |- (planning.east);
\draw [l] (lowerright |- container.east) -- (container.east -| resources.south east);
\end{tikzpicture}
\end{document}
I had to do something similar myself so it was a good exercise.
Tikz experts will find more elegant code I'm sure, but
based on the example http://www.texample.net/tikz/examples/labs-schema/ this is what I've achieved:
![enter image description here](https://i.stack.imgur.com/SHDEj.png)
\documentclass[11pt]{article}
\usepackage{tikz}
\usetikzlibrary{shadows,arrows,positioning}
% Define the layers to draw the diagram
\pgfdeclarelayer{background}
\pgfdeclarelayer{foreground}
\pgfsetlayers{background,main,foreground}
% Define block styles
\tikzstyle{materia}=[draw, fill=blue!20, text width=6.0em, text centered,
minimum height=1.5em,drop shadow]
\tikzstyle{etape} = [materia, text width=8em, minimum width=10em,
minimum height=3em, rounded corners, drop shadow]
\tikzstyle{texto} = [above, text width=6em, text centered]
\tikzstyle{linepart} = [draw, thick, color=black!50, -latex', dashed]
\tikzstyle{line} = [draw, thick, color=black!50, -latex']
\tikzstyle{ur}=[draw, text centered, minimum height=0.01em]
% Define distances for bordering
\newcommand{\blockdist}{1.3}
\newcommand{\edgedist}{1.5}
\newcommand{\etape}[2]{node (p#1) [etape]
{#2}}
% Draw background
\newcommand{\background}[5]{%
\begin{pgfonlayer}{background}
% Left-top corner of the background rectangle
\path (#1.west |- #2.north)+(-0.5,0.25) node (a1) {};
% Right-bottom corner of the background rectanle
\path (#3.east |- #4.south)+(+0.5,-0.25) node (a2) {};
% Draw the background
\path[fill=yellow!20,rounded corners, draw=black!50, dashed]
(a1) rectangle (a2);
\path (#3.east |- #2.north)+(0,0.25)--(#1.west |- #2.north) node[midway] (#5-n) {};
\path (#3.east |- #2.south)+(0,-0.35)--(#1.west |- #2.south) node[midway] (#5-s) {};
\path (#3.east |- #2.north)+(0.7,0)--(#3.east |- #4.south) node[midway] (#5-w) {};
\end{pgfonlayer}}
\newcommand{\transreceptor}[3]{%
\path [linepart] (#1.east) -- node [above]
{\scriptsize #2} (#3);}
\begin{document}
\begin{tikzpicture}[scale=0.7,transform shape]
% Draw diagram elements
\path \etape{1}{Raw signal};
\path (p1.south)+(0.0,-1.5) \etape{2}{Pre-1};
\path (p2.south)+(0.0,-1.0) \etape{3}{Pre-2};
\path (p3.south)+(0.0,-1.5) \etape{4}{Feature extract};
\path (p4.south)+(0.0,-1.0) \etape{5}{Model fitting};
\path (p5.south)+(-3.0,-2.0) \etape{6}{training};
\path (p5.south)+(3.0,-2.0) \etape{7}{testing};
\node [below=of p5] (p6-7) {};
\path (p6.south)+(0.0,-2.0) \etape{8}{normal};
\path (p7.south)+(0.0,-2.0) \etape{9}{abnormal};
\node [below=of p6-7] (p8-9) {};
% Draw arrows between elements
\path [line] (p1.south) -- node [above] {} (p2);
\path [line] (p2.south) -- node [above] {} (p3);
\path [line] (p3.south) -- node [above] {} (p4);
\path [line] (p4.south) -- node [above] {} (p5);
\background{p2}{p2}{p3}{p3}{bk1}
\background{p4}{p4}{p5}{p5}{bk2}
\background{p6}{p6}{p7}{p7}{bk3}
\path [line] (p5.south) -- node [above] {} (bk3-n);
\path [line] (bk3-s) -- node [above] {} (p8);
\path [line] (bk3-s) -- node [above] {} (p9);
\path (bk1-w)+(+6.0,0) node (ur1)[ur] {};
\path (bk2-w)+(+6.0,0) node (ur2)[ur] {};
\path (bk3-w)+(+3.0,0) node (ur3)[ur] {};
\transreceptor{bk1-w}{pre processing}{ur1};
\transreceptor{bk2-w}{Feature selection}{ur2};
\transreceptor{bk3-w}{classification}{ur3};
\end{tikzpicture}
\end{document}
Best Answer
The way i use to solve problems like this is by adding an additional control point to guide the line on. The following code shows how to do this by your given vertical example:
The value
++(-0.5,0)
sets the relative control point coordinates the backarrow has to go through. Edit them to your needs or add some more.The code results in:
Hope this helps.