# add label at fit block top left corner

I wish to move the label at the top left corner of the fit block, but now it seems at the center.

\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning,fit,calc}
\begin{document}
\begin{tikzpicture}[
box/.style={draw,minimum width=2.5cm,align=center},
node distance=0.5cm and 3cm
]
\node[box] (N1) {Source};
\node[box,below=of N1] (N2) {Destination};

\node[draw,dashed,inner sep=8pt,fit={(N1) (N2)}] (fit) {label};
\end{tikzpicture}
\end{document}


I wish to use the same fit node but don't want to add another node for label purpose!

• Why do you not want another node? What's the exact wanted location for "label"? There is a label option, e.g. label={above left:label}. – Heiko Oberdiek May 25 '15 at 5:46

It is possible to put text on the upper left corner in the inside without another explicit or implicit node:

\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning,fit,calc}

\makeatletter
\newcommand*{\MoveFitHeight}[1]{%
\pgfmathsetlengthmacro\fit@inner@sep{%
\pgfkeysvalueof{/pgf/inner xsep}%
}%
\pgfmathsetlengthmacro\fit@text@height{%
\tikz@text@height
}%
\kern-\fit@inner@sep\relax
\raisebox{\fit@text@height}[0pt][0pt]{#1}%
}
\makeatother

\begin{document}
\begin{tikzpicture}[
box/.style={draw,minimum width=2.5cm,align=center},
node distance=0.5cm and 3cm
]
\node[box] (N1) {Source};
\node[box,below=of N1] (N2) {Destination};

\node[
draw,
dashed,
inner sep=8pt,
fit={(N1) (N2)},
align=left,
] (fit) {\MoveFitHeight{label}};
\end{tikzpicture}
\end{document}


The documentation says:

The above means that, generally speaking, if the node contains text like box in the above example, it will be centered inside the box. It will be difficult to put the text elsewhere, in particular, changing the anchor of the node will not have the desired ffect. Instead, what you should do is to create a node with the fit option that does not contain any text, give it a name, and then use normal nodes to add text at the desired positions. Alternatively, consider using the label or pin options.

Another node is IMHO the cleanest way:

\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning,fit,calc}

\begin{document}
\begin{tikzpicture}[
box/.style={draw,minimum width=2.5cm,align=center},
node distance=0.5cm and 3cm
]
\node[box] (N1) {Source};
\node[box,below=of N1] (N2) {Destination};

\node[
draw,
dashed,
inner sep=8pt,
fit={(N1) (N2)},
] (fit) {};
\node[above right, inner sep=0pt] at (fit.north west) {above right};
\node[below right, inner sep=0pt] at (fit.north west) {below right};
\end{tikzpicture}
\end{document}


Fine tuning can be done via options inner sep, xshift, or yshift.

For those who are interested, here is a quick way you can do it with MetaPost.

\documentclass[border=2mm]{standalone}
\usepackage{luamplib}
\begin{document}
\begin{mplibcode}
input boxes
beginfig(1);
boxit.main(image(
label(btex \framebox[2.5cm]{Source} etex, origin);
label(btex \framebox[2.5cm]{Destination} etex, (0, -cm))));
main.dx = main.dy = 12pt;
drawunboxed(main); draw bpath(main) dashed evenly;
label.lrt(btex label etex, main.nw);
endfig;
\end{mplibcode}
\end{document}


The key point is to insert the Source and Destination boxes (I chose to typeset them with a mere \framebox) into a greater box fit with the help of the boxes package of MetaPost.

Once this is done, it is very easy to have access to the upper left corner of this box: it is simply main.nw, where main is the name I have given to it and nw meaning “north-west”.

I have inserted the MetaPost coding into a LuaLaTeX program since it is the most direct way to include MetaPost into a LaTeX document.

For those who don't want to use LuaLaTeX, here is a more general version using the gmp package. (But you have to activate the shell-escape feature of your distribution to typeset it.)

\documentclass[border=2mm]{standalone}
\usepackage[latex, shellescape, everymp={input boxes}]{gmp}
\begin{document}
\begin{mpost*}
boxit.main(image(
label(btex \framebox[2.5cm]{Source} etex, origin);
label(btex \framebox[2.5cm]{Destination} etex, (0, -cm))));
main.dx = main.dy = 12pt;
drawunboxed(main); draw bpath(main) dashed evenly;
label.lrt(btex label etex, main.nw);
\end{mpost*}
\end{document}