Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I am trying to insert some vertical space inside a node (So it will be filled later).

\node [draw,rounded corners,minimum height=5cm] (node1) {\underline{Case 1}};

This is giving this:

enter image description here

However, I want Case 1 to be at the top of the node.

Can any one help please. Thanks in advance.

share|improve this question
    
Is this answer helpful: How to make a tikz node, top-aligned with the rest of the text? –  Kevin C Oct 20 '13 at 15:12
add comment

3 Answers

up vote 8 down vote accepted

You can achieve the effect you want by using an anchor and a second node:

\documentclass{article}
\usepackage{tikz}
%%\usetikzlibrary{calc}%% not necessary, but potentially useful
\pagestyle{empty}
\begin{document}

\begin{tikzpicture}
  \node [draw,rounded corners,minimum height=5cm,minimum width=2cm] (node1) {};
  \node [anchor=north west] at (node1.north west) {\underline{Case 1}};
\end{tikzpicture}

\end{document}

enter image description here

What's happening here is that node1.north west tells \node where you want the content to be placed. The anchor=north west tell the \node to use the upper left hand corner of the text as the anchor position to be placed.

It's a bit easier to see what's happening if we do something completely different from what you actually want (but perhaps this will make clear what the two north west directives are about):

\documentclass{article}
\usepackage{tikz}
\begin{document}

\begin{tikzpicture}
  \node [draw,rounded corners,minimum height=5cm,minimum width=4cm] (node1) {};
  \node [anchor=north west] at (node1.north west) {\fbox{Case: anchor is NW}};
  \node [anchor=south west] at (node1.north west) {\fbox{Case: anchor is SW}};
  \node [anchor=south east] at (node1.north west) {\fbox{Case: anchor is SE}};
  \node [anchor=north east] at (node1.north west) {\fbox{Case: anchor is NE}};
  \foreach \myanchor in {north west,south west,north east,south east}
    { 
      \node[fill,circle,inner sep=1pt,outer sep=1ex,anchor=\myanchor] at (node1.north west){};
    }
\end{tikzpicture}

\end{document}

enter image description here

Notice that the anchoring is about the corners to the text being place with respect to the node being used (which in this case is node1.north west.

Additionally using the TikZ library calc you can exert more control over the positioning:

  \node [anchor=north west] at ($(node1.north west)+(1ex,-2ex)$) {\underline{Case 1}};

The positioning here is a bit more extreme to help illustrate what's happening.

UPDATE

If you'll be doing this a lot, then (following @Qrrbrbirlbel 's suggestion), you can define a style and do everything within one node:

\documentclass{article}
\usepackage{tikz}
\begin{document}

\begin{tikzpicture}[my case/.style={draw,
                                    rounded corners,
                                    minimum height=5cm,
                                    minimum width=4cm,
                                    append after command={node[anchor=north west]
                                                          at  (\tikzlastnode.north west)
                                                          {#1}}}]
  \node [my case={\textbf{Case A:}}] (node1) {};
\end{tikzpicture}

\end{document}

And yes, you can define a command for this:

\documentclass{article}
\usepackage{tikz}
\def\mycasenode(#1)#2;{\node[my case={#2}] (#1) {};}
\begin{document}

\begin{tikzpicture}[my case/.style={draw,
                                    rounded corners,
                                    minimum height=5cm,
                                    minimum width=4cm,
                                    append after command={node[anchor=north west]
                                                          at  (\tikzlastnode.north west)
                                                          {#1}}}]
  %\node [my case={\textbf{Case A:}}] (node1) {};
  \mycasenode (node1) {\textbf{Case A:}};
\end{tikzpicture}

\end{document}

Notice how I created a definition to mimic TikZ command and node styles.

share|improve this answer
    
thanks for your answer. It works perfectly. Is it possible to create a new command using your suggestion ? (Because I will be doing it alot) –  user2536125 Oct 20 '13 at 17:01
    
You can do it in one node (interface-wise) if you use append after command={node [below right] at (\tikzlastnode.north west) {Case}}. This makes it easy to do it within a style at a node (and not as a path option). Or even a label with my solution from How can I set the TikZ label anchor explicitly? –  Qrrbrbirlbel Oct 20 '13 at 17:28
    
@Qrrbrbirlbel Thank you for the suggestion. –  A.Ellett Oct 20 '13 at 17:49
add comment

I usually have another node dedicated for displaying only. I find it much easier.

\node [draw,rounded corners,minimum height=5cm] (node1) {};
\node [below=0cm of node1.north]{\underline{Case 1}};
share|improve this answer
add comment

When TikZ collects the text for a node it puts it directly in a box (an \hbox), this box is (except for the options text width, text height and text depth) exactly the size of its content.

This box and its measurements is then used to calculate the shape around it (in our case the rectangle). This box is always placed in one specific position of the shape (most times, this is the center). We cannot change this position without re-writing the shapes.

In this answer, a different approach is taken. After the node content has been collected and the box is created the box is re-set.

The value of the valign height key is used to put the node in a larger (higher) box. The vertical alignment can be changed with the valign key which accepts the following values:

  • top,
  • center (default) and
  • bottom.

I am no boxing expert, so there may be better way to re-use the \pgfnodeparttextbox and pack it in a new box.

It should be noted, that this works best with rectangular shapes because the extended vertical height of the box will change the calculation of the shape dimension.
There may be another approach to this problem which includes changing the height and the depths of the \pgfnodeparttextbox directly (i.e. subtracting a length from the height that is added to the depth pushes the content of the box to the top but doesn’t change the size of the box itself). This would possibly result in the text protruding the shape.
This topic is along the lines of a related question about raising the node content about a certain value (I’m referring mostly to the images in the answers).

I assume that this is only really practicable for rectangular shapes anyway.

Code

\documentclass[tikz]{standalone}
\usepackage{etoolbox}
\makeatletter
\def\tikz@valign{c}
\tikzset{
  enforce alignment/.code={% even without text width
    \csname if#1\endcsname
      \def\tikz@text@width
        {\pgfkeysvalueof{/pgf/minimum width}-2*(\pgfkeysvalueof{/pgf/inner xsep})}%
    \else
      \let\tikz@text@width\pgfutil@empty
    \fi},
  enforce alignment/.default=true,
  valign/.is choice,
  valign/top/.code=\def\tikz@valign{t},
  valign/center/.code=\def\tikz@valign{c},
  valign/bottom/.code=\def\tikz@valign{b},
  valign height/.initial=%
    \pgfkeysvalueof{/pgf/minimum height}-2*(\pgfkeysvalueof{/pgf/inner ysep})}
\patchcmd\tikz@fig@continue{\tikz@node@transformations}{%
  \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/tikz/valign height}}%
  \pgf@y\ht\pgfnodeparttextbox
  \advance\pgf@y\dp\pgfnodeparttextbox
  \ifdim\pgf@y<\pgf@x
  \if\tikz@valign b%
    \advance\pgf@x-\dp\pgfnodeparttextbox
    \setbox\pgfnodeparttextbox\vbox to \pgf@x{\vfill\hbox{\unhbox\pgfnodeparttextbox}}%
  \else\if\tikz@valign t%
    \setbox\pgfnodeparttextbox\vbox to \pgf@x{\hbox{\unhbox\pgfnodeparttextbox}\vfill}%
  \fi\fi\fi
  %
  \tikz@node@transformations}{}{}
\makeatother
\tikzset{nodes={draw,rounded corners},minimum height=1.5cm,minimum width=2cm}
\begin{document}
\begin{tikzpicture}
  \node [text=red,  valign=top]    {Case t};
  \node                            {Case c};
  \node [text=blue, valign=bottom] {Case b};
\end{tikzpicture}
\begin{tikzpicture}[enforce alignment]
  \node [text=red,  valign=top,    align=left ]  {Case t};
  \node [                         align=center]  {Case c};% or "enforce alignment=false"
  \node [text=blue, valign=bottom, align=right]  {Case b};
\end{tikzpicture}
\begin{tikzpicture}[enforce alignment, align=center, minimum height=3cm]
  \node [text=red,  valign=top]                 {Case t Case t Case t Case t};
  \node                            at (right:2) {Case c Case c Case c Case c};
  \node [text=blue, valign=bottom] at (right:4) {Case b Case b Case b Case b};
\end{tikzpicture}
\end{document}

Output

enter image description hereenter image description here

enter image description here

share|improve this answer
    
It should also be noted that for non-empty text widths a version of the minipage environment is used for typesetting (and for LaTeX the actual minipage environment is used), so there might be a third approach on doing this. –  Qrrbrbirlbel Oct 23 '13 at 0:56
    
Have you considered to make a CTAN package with your great answers? or propose them to be incorporated to TikZ? –  Ignasi Oct 25 '13 at 7:53
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.