# Text alignment using fix anchor positions in TikZ

I created some biological drawings using Dia and exported them as TikZ TeX code.

I want to define some commands that insert these drawings and add some text to them. As there is a lot of text and not much space I want the text to be aligned left, right or centered according to a certain anchor point.

Just consider this example. The arrows should point to the anchor points.

The first text, "right", has a fixed anchor point on its right. If the text grows the text should move further to the left. The text "left" has an anchor on its left edge. It grows to the right. The "center" text is centered according to an anchor on its center position.

The resulting TeX Code is posted below. I am sorry for all of the boilerplate parts!

To clarify what I really want to achieve:

I create a picture in Dia that contains some (placeholder) text. I now want a corresponding LaTeX command that inserts this picture and a new text for each text originally placed in the graphic. As the space is limited the text sometimes need to be aligned in a different way.

Consider this example picture

For the creation of the command I can easily replace the text in the generated Tex by something like

\node[anchor=west] at (8.650000\du,7.400000\du){#1};


which only replaces the original text by a corresponding argument, but as it can be already seen in the second example picture there is not enough space to left-align every string. So what I need is a command like

\drawText{(8.650000\du,7.400000\du)}{#1}{l}


which enables me to specify the alignment just as shown in the first example.

Do you have any idea how this (the text output in the three mentioned ways) could be achieved by only knowing the anchor point?

Here is some sample code which was generated by the first example Dia project

\documentclass{article}
\usepackage{tikz}
\begin{document}
\ifx\du\undefined
\newlength{\du}
\fi
\setlength{\du}{15\unitlength}
\newcommand{\testpic}[3]{
\begin{tikzpicture}
\pgftransformxscale{1.000000}
\pgftransformyscale{-1.000000}
\definecolor{dialinecolor}{rgb}{0.000000, 0.000000, 0.000000}
\pgfsetstrokecolor{dialinecolor}
\definecolor{dialinecolor}{rgb}{1.000000, 1.000000, 1.000000}
\pgfsetfillcolor{dialinecolor}
\pgfsetlinewidth{0.100000\du}
\pgfsetdash{}{0pt}
\pgfsetdash{}{0pt}
\pgfsetbuttcap
{
\definecolor{dialinecolor}{rgb}{0.000000, 0.000000, 0.000000}
\pgfsetfillcolor{dialinecolor}
% was here!!!
\pgfsetarrowsend{stealth}
\definecolor{dialinecolor}{rgb}{0.000000, 0.000000, 0.000000}
\pgfsetstrokecolor{dialinecolor}
\draw (9.950000\du,10.050000\du)--(9.950000\du,7.700000\du);
}
\pgfsetlinewidth{0.100000\du}
\pgfsetdash{}{0pt}
\pgfsetdash{}{0pt}
\pgfsetbuttcap
{
\definecolor{dialinecolor}{rgb}{0.000000, 0.000000, 0.000000}
\pgfsetfillcolor{dialinecolor}
% was here!!!
\pgfsetarrowsend{stealth}
\definecolor{dialinecolor}{rgb}{0.000000, 0.000000, 0.000000}
\pgfsetstrokecolor{dialinecolor}
\draw (14.831803\du,10.050000\du)--(14.831803\du,7.700000\du);
}
\pgfsetlinewidth{0.100000\du}
\pgfsetdash{}{0pt}
\pgfsetdash{}{0pt}
\pgfsetbuttcap
{
\definecolor{dialinecolor}{rgb}{0.000000, 0.000000, 0.000000}
\pgfsetfillcolor{dialinecolor}
% was here!!!
\pgfsetarrowsend{stealth}
\definecolor{dialinecolor}{rgb}{0.000000, 0.000000, 0.000000}
\pgfsetstrokecolor{dialinecolor}
\draw (19.951803\du,10.050000\du)--(19.951803\du,7.700000\du);
}
% setfont left to latex
\definecolor{dialinecolor}{rgb}{0.000000, 0.000000, 0.000000}
\pgfsetstrokecolor{dialinecolor}
\node[anchor=west] at (8.650000\du,7.400000\du){#1};
% setfont left to latex
\definecolor{dialinecolor}{rgb}{0.000000, 0.000000, 0.000000}
\pgfsetstrokecolor{dialinecolor}
\node[anchor=west] at (6.250000\du,7.800000\du){};
% setfont left to latex
\definecolor{dialinecolor}{rgb}{0.000000, 0.000000, 0.000000}
\pgfsetstrokecolor{dialinecolor}
\node[anchor=west] at (14.050000\du,7.418625\du){#2};
% setfont left to latex
\definecolor{dialinecolor}{rgb}{0.000000, 0.000000, 0.000000}
\pgfsetstrokecolor{dialinecolor}
\node[anchor=west] at (20.000000\du,7.400000\du){#3};
\end{tikzpicture}
}
\testpic{right}{center}{left}
\end{document}

-
What do you mean with “anchor point” and “fixed anchor point”? What do you want to achieve how? (I don’t understand the question.) –  Qrrbrbirlbel Sep 26 '13 at 18:17
You can define styles like l, c and r that are set to anchor=east, anchor=center and anchor=west respectively. (Or south east, south and south west.) Then you can use that argument in the optional argument of the node. –  Qrrbrbirlbel Sep 26 '13 at 20:38
I'm very foggy on what it is you want. Are you saying that dia (whatever that might be) is generating the TikZ code? Then are you importing this code into you LaTeX document and wishing to make some changes (such as what text is placed in the nodes)? –  A.Ellett Sep 26 '13 at 20:48
If I understand what you want to do, and if this is code generated by some third party program, then I think this is going to be very difficult to do. In particular, the arrows are drawn very rigidly and without reference to the nodes that they correspond to. The nodes are also drawn very rigidly with no connection to their corresponding arrows. So, to get the text to behave different with this boilerplate code, it seems to me you'll have to do some major editing. –  A.Ellett Sep 26 '13 at 20:53

There's a lot going on in your code with a lot of duplication and redefining going on. But, it seems (if you want to use TikZ for this), that something like the following should do just fine:

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

\begin{document}

\begin{tikzpicture}[my node/.style={anchor=base,inner sep=0pt},
my arrows/.style={arrows=stealth-,line width=2pt}
]
\pgftransformxscale{3}
\node[my node] (right)  at (0,0) {right};
\node[my node] (center) at (1,0) {center};
\node[my node] (left)   at (2,0) {left};

\draw[my arrows] ($(left.base west)+(0,-1ex)$)  -- ($(left.base west)+(0,-2cm)$);
\draw[my arrows] ($(center.base)+(0,-1ex)$)     -- ($(center.base)+(0,-2cm)$);
\draw[my arrows] ($(right.base east)+(0,-1ex)$) -- ($(right.base east)+(0,-2cm)$);
\end{tikzpicture}

\end{document}


Or at @Qrrbrbirlbel has very nicely suggested, you can accomplish this without having to use the calc library as follows

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

\begin{document}

\begin{tikzpicture}[my node/.style={anchor=base,inner sep=0pt},
my arrows/.style={arrows=stealth-,line width=2pt}
]
\pgftransformxscale{3}
\node[my node] (right)  at (0,0) {right};
\node[my node] (center) at (1,0) {center};
\node[my node] (left)   at (2,0) {left};

\draw[my arrows] (left.base west)  ++ (down:1ex) -- ++ (down:2cm);
\draw[my arrows] (center.base)     ++ (down:1ex) -- ++ (down:2cm);
\draw[my arrows] (right.base east) ++ (down:1ex) -- ++ (down:2cm);

\end{tikzpicture}

\end{document}

-
Or (*) ++ (down:1ex) -- ++ (down:2cm) without calc where the first moveto can also be replaced with ([yshift=-1ex] *). You can also use the south anchors with text depth=1ex. –  Qrrbrbirlbel Sep 26 '13 at 20:04
@Qrrbrbirlbel I'm not familiar with the * notation. Nor am I familiar with (down:<dim>). Do you know what section of the manual these are documented in? –  A.Ellett Sep 26 '13 at 20:06
@Qrrbrbirlbel A search on (*) in the manual doesn't reveal anything. –  A.Ellett Sep 26 '13 at 20:07
Sorry for the confusion. * was just my placeholder for the node names/node anchors you’ve used. The (down:<dim>) is just a specific polar coordinate (i.e. (270:<dim>)). The manual describes them on page 125. –  Qrrbrbirlbel Sep 26 '13 at 20:14

While you exported to tikz, it wasn't clear that you wanted a solution in the tikz context. So I interpreted in a fashion absent from tikz.

First, I had to import more stealth like arrows to the math font. WHile they are not the exact same as yours, I grabbed the single character from the mathabx package, without loading the whole package.

Then, to achieve the text, I used the \toplap macro found in \stackengine package, which takes l, c, and r as arguments along with the text to lap.

My left and right are opposite from yours, but I thought it easier to retrain my brain, rather than write the few lines of code to interchange their meaning.

I should point out that, because the command is a lapping macro, the size of the text block is not "seen" by LaTeX, and so, depending on how you place stuff adjacent to it, you may have to account for additional spacing. On the other hand, this may be exactly what you want, since the text will not affect the anchor location, which will always be the arrow.

\documentclass{article}
\usepackage{graphicx}
\usepackage{stackengine}
% Setup the matha font (from mathabx.sty)
\DeclareFontFamily{U}{matha}{\hyphenchar\font45}
\DeclareFontShape{U}{matha}{m}{n}{
<5> <6> <7> <8> <9> <10> gen * matha
<10.95> matha10 <12> <14.4> <17.28> <20.74> <24.88> matha12
}{}
\DeclareSymbolFont{matha}{U}{matha}{m}{n}
% Define a subset character from that font (from mathabx.dcl)
% to completely replace the \subset character, you can replace
% \varsubset with \subset
\DeclareMathSymbol{\varleftarrow}{3}{matha}{"D0}
%\DeclareMathSymbol{\varrightarrow}{3}{matha}{"D1}
\def\uparrow{\scalebox{2}{\rotatebox{-90}{\hspace{-1.3ex}$\varleftarrow$}}}
\newcommand\textarrow[2]{\hsmash{\uparrow}\toplap{#1}{\sffamily#2}}
\parindent 0in\parskip 1em
\begin{document}
\textarrow{l}{left text}\par
\textarrow{c}{center text}\par
\textarrow{r}{right text}
\end{document}


Importing a single math character was learned from Alan Munn at

Importing a Single Symbol From a Different Font

-