Graphics, Figures & Tablestikzpicture position label vertically

Information and discussion about graphics, figures & tables in LaTeX documents.
Post Reply
User avatar
jess-elzbth
Posts: 7
Joined: Thu Sep 01, 2016 8:12 pm

tikzpicture position label vertically

Post by jess-elzbth »

Preamble:
I am trying to create a vertical timeline. After looking around I decided using tikz to draw a line and use the nodes and their labels was my best option. Now I'm thinking \tabular would be better... either way, I'd like to know the answer to the following problem. I am a beginner to LaTeX, so I would appreciate a lot of definitions in replies. :D

After looking in the documentation I have found that the text for labels is stored in an hbox. I did not find any commands relating to the height, depth or width of an hbox, but I would assume they are the same for all boxes. I also learned the definitions of baseline (e.g. "p" the baseline is under the circle part), height (would be from top of "p" to baseline), and depth (would be from baseline to bottom of "p"). Width is self-explanatory. Is this correct?

My problem:
My problem is that the labels line-up vertically at their baseline (I think) with their respective node. My labels will be more than one line of text and I want the label to line up at the top, e.g.
ex1.png
ex1.png (8.72 KiB) Viewed 23767 times

Code: Select all

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning}

\begin{document}
	
	\begin{tikzpicture}
	\draw [cyan] (0,0) --(0,10);
	\draw [fill, cyan] (0,9.75) circle [radius=0.075]{};
		\node [left] (1) at (-0.25,9.75){Left side 1 };
		\node [right, align=left, text width=3cm, yshift=-6ex] (1t) at (0.25,9.75) {Sample text header goes here. The text on this side will be multiple lines long};
	
	\end{tikzpicture}
\end{document}
While using \yshift is indeed what I want to do, I don't want to play a guessing game for each hbox (and to be honest, I just hate the way that code looks). Instead, I would like to yshift the hbox negatively by it's height. I thought I found a solution to this problem in another forum post, here:

Code: Select all

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning}


\begin{document}
	\begin{tikzpicture}[baseline={([yshift={-\ht\strutbox}]current bounding box.north)},outer sep=0pt,inner sep=0pt];
	\draw [cyan] (0,0) --(0,10);
	\draw [fill, cyan] (0,9.75) circle [radius=0.075]{};
		\node [left] (1) at (-0.25,9.75){Left side 1 };
		\node [right, align=left, text width=3cm] (1t) at (0.25,9.75) {\strut Sample text header goes here. The text on this side will be multiple lines long};
	\end{tikzpicture}
\end{document}
Which renders:
ex2.png
ex2.png (9.08 KiB) Viewed 23767 times
However my compiler doesn't seem to recognize \strutbox as a command; as you can see the hbox is lined up at, what I assume is, it's baseline. And after searching for days I have no idea what current bounding box actually is. In the second example I am not thrown any errors, however \ht\strutbox is hightlighted orange. I am using TeXstudio in Windows.

After learning that the text is stored in an hbox, I changed the above code to reflect that, e.g. yshift={-\ht\hbox}, but to no avail. Here though, I am actually thrown an error: "Missing number, treated as zero." on the \end{tikzpicture} line.

In short: Can I have \tikzpicture determine the height of each hbox and define a dynamic yshift based on this result?

I feel like variables need to be defined... but I'm sure there is a simpler way. Like I said, I'm a beginner! ;)
Last edited by jess-elzbth on Sat Sep 03, 2016 8:54 pm, edited 2 times in total.

Recommended reading 2024:

LaTeXguide.org • LaTeX-Cookbook.net • TikZ.org
TikZ book
User avatar
Stefan Kottwitz
Site Admin
Posts: 10316
Joined: Mon Mar 10, 2008 9:44 pm

Re: tikzpicture yshift label by height

Post by Stefan Kottwitz »

Welcome to the forum!

That's pretty good for a beginner! I cannot test the code right now, and it's after midnight here, so I will take a close look tomorrow. I'm a TikZ user too.

Stefan
LaTeX.org admin
User avatar
jess-elzbth
Posts: 7
Joined: Thu Sep 01, 2016 8:12 pm

Re: tikzpicture yshift label by height

Post by jess-elzbth »

Thank you Stefan. I look forward to your reply!
Somewhere in my mind are good java programming skills; I just haven't used them for a while. The logic of coding is therefore not foreign to me :) And the code you see above wasn't written in 5 minutes ;)
User avatar
Stefan Kottwitz
Site Admin
Posts: 10316
Joined: Mon Mar 10, 2008 9:44 pm

tikzpicture position label vertically

Post by Stefan Kottwitz »

You could use an anchor for positioning.

However, as you mentioned tabular, I think that's a good idea, because you would like to position at the base line of the first line of a tabular cell content, that's what tabular does well. It's also easy to fill in.

Here is an example with tabularx. I used TikZ to draw a line via an overlay over the table.

Code: Select all

\documentclass{article}
\usepackage{tikz}
\newcommand*{\point}{\textcolor{blue}{$\bullet$}}
\newcommand{\pos}[1]{\tikz[overlay,remember picture,
                           baseline=(#1.base)] \node (#1) {\point};}
\usepackage{array}
\usepackage{tabularx}
\usepackage{microtype}
\begin{document}
\centering
\begin{tabularx}{0.6\textwidth}{rcX}
  Left side 1     & \pos{top}    & Sample text header goes here.
                                   The text on this side will be
                                   multiple lines long. \\
  Now left side 2 & \point       & More sample text goes here.
                                   Again, it is multiple lines long. \\
  Last left side  & \pos{bottom} & More sample text.
\end{tabularx}
\tikz[overlay,remember picture] {
  \draw[thick,blue,draw] (top.north) -- (bottom.south);
}
\end{document}
table.png
table.png (22.94 KiB) Viewed 23733 times
Stefan
LaTeX.org admin
rais
Posts: 419
Joined: Sun Nov 16, 2014 8:51 pm

tikzpicture position label vertically

Post by rais »

Stefan_K wrote:You could use an anchor for positioning.
though I like your idea with {tabularx} better, I followed up on this anyway.
Using the positioning library, it wasn't too complicated, after all:

Code: Select all

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning}

\begin{document}

\begin{tikzpicture}[node distance=5mm]
  \draw [cyan] (0,0) --(0,10);
  \draw [fill, cyan] (0,9.75) circle [radius=0.075] node (1c) {}
    node [black, left=2.5mm] (1) {Left side 1};
  \node [base right=of 1, text width=3cm] (1t) {Sample text header goes here. The text on this side will be multiple lines long};
  \draw[very thin, red, ->] (1c.center) -- (1.east) node [midway, above] {\tiny left};
  \draw[very thin, red, ->] (1.base east) -- (1t.base west) node [midway, below] {\tiny base right};
\end{tikzpicture}
\end{document}
"node (1c) {}" and everything rendered red is just for illustrating the placing of the nodes:
base-right-align.png
base-right-align.png (27.7 KiB) Viewed 23722 times
KR
Rainer
User avatar
jess-elzbth
Posts: 7
Joined: Thu Sep 01, 2016 8:12 pm

Re: tikzpicture yshift label by height

Post by jess-elzbth »

Thank you Stefan for showing me \tabularx and an alternative solution. Using variables at this point is too much for me ;) I need to get a better grip on the syntax before I dive into that.

That's great Rainer! Something simple and to the point. Thanks for coming back to the anchor idea. Works perfectly for me.
Post Reply