Una TeX
flecha aparentemente está centrada verticalmente con la altura de un carácter x, en este caso el final e
:
\documentclass{article}
\begin{document}
Source $\rightarrow$ Target
\end{document}
Una TikZ
flecha, por otro lado, parece estar centrada verticalmente con un carácter de altura de mayúscula, en este caso la mayúscula S
y T
:
\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\draw [thick, ->] (0,0) -- (1,0);
\node[left] at (0,0) {Source};
\node[right] at (1,0) {Target};
\end{tikzpicture}
\end{document}
Dado que la palabra de la izquierda termina en un carácter de altura x y la palabra de la derecha comienza con un carácter de altura mayúscula, esto crea la ilusión óptica (al menos para mí) de que la palabra de la derecha está colocada más arriba que la palabra de la izquierda. Me gustaría evitar esto centrando la TikZ
flecha verticalmente con un carácter de altura x. ¿Cómo puedo hacer esto?
EDITAR
En realidad acabo de darme cuenta de que esto no es una ilusión óptica. La palabra de la derechaescolocado más alto porque contiene la letra g
que va por debajo de la línea de base. Para evitar este problema ahora (supongo que debería ser una pregunta aparte), considere el siguiente ejemplo. La flecha no está centrada respecto a la anterior e
, y eso me parece mal:
Respuesta1
TikZ usa hboxes para escribir el contenido del nodo. Si no se especifica una profundidad de texto explícita, los descendientes harán que la altura del nodo cambie. Entonces, cuando tienes un texto con descendentes y sin descendentes, su altura será necesariamente diferente. Eso es todo. No hay ninguna sorpresa y tampoco hay mucho que cambiar.
Usted ha mencionado que ¿por qué necesitaría una profundidad de texto si no tiene un descendente y eso es nuevamente para asegurarse de que cualquier nodo con o sin descendentes se alinee correctamente sin analizar realmente cada letra y verificar si hay alguna?
¡Pero!
Si no va a dibujar ningún borde alrededor de los nodos, puede restablecer la profundidad del texto y vivir con él.
\documentclass[tikz,border=5mm]{standalone}
\begin{document}
\begin{tikzpicture}[every node/.style={inner sep=0,text depth=0,draw}]
\node[anchor=east] (s) at (0,0) {Source};
\node[anchor=west] (t) at (1,0) {Target};
\draw[->] (s) -- (t);
\end{tikzpicture}
\end{document}
O, alternativamente, si no le importa trazar la conexión con un poco más de trabajo, puede alinear los nodos con respecto a su línea base con los descendentes respetándola. Sin embargo, entonces los nodos no estarán perfectamente alineados horizontalmente y será necesario dibujar las conexiones con, por ejemplo, identificadores orto.
\documentclass[tikz,border=5mm]{standalone}
\begin{document}
\begin{tikzpicture}[every node/.style={draw,inner sep=0}]
\node[anchor=mid] (s) at (0,0) {Source};
\node[anchor=mid] (t) at (1.5,0) {Target};
\draw[->,ultra thick] (s) -- (t);
\draw[-latex,red] (s) -- (t.west|-s);
\end{tikzpicture}
\end{document}
Tenga en cuenta que necesita hacer algo de preparación si desea utilizar ambos left
y mid
. Hasta donde yo sé, no es compatible de inmediato.
Respuesta2
Seguimiento depercutir'srespuesta, podemos usar text depth = 0
para indicar que la parte inferior del cuadro se dibuje como si no hubiera caracteres con descendentes, y usar text height = 1ex
para dibujar la parte superior del cuadro como si todos los caracteres tuvieran altura x:
\documentclass[tikz, border = 1mm]{standalone}
\begin{document}
\begin{tikzpicture}[every node/.style = {inner sep = 0, text height = 1ex, text depth = 0, draw}]
\node[anchor = east] (s) at (0,0) {Sphinx};
\node[anchor = west] (t) at (1,0) {Sphinx};
\draw[->] (s) -- (t);
\end{tikzpicture}
\end{document}
El resultado es que la flecha está alineada verticalmente con el centro de los caracteres de altura x.
Respuesta3
¿Cómo coloca TikZ/PGF el texto dentro de un nodo?
Para nodos simples (y usaré la rectangle
forma para este ejemplo) con una parte, TikZ coloca todo el contenido del nodo en un cuadro TeX (con un ancho, alto y profundidad como de costumbre) y construye un camino alrededor de él con el relleno /pgf/inner xsep
y /pgf/inner ysep
.
El centro del nodo será el centro del cuadro TeX. Con cajas con diferentes alturas y profundidades, esto no estará en la misma altura vertical (en relación con la línea de base) en todas las cajas.
¿Cómo coloca TikZ los nodos?
En tu ejemplo, usas left
y right
que es básicamente lo mismo que anchor=east
y anchor=west
respectivamente. Estos anclajes se encuentran a la misma altura vertical que el center
anclaje (por definición) y en el borde respectivo del nodo.
Como puedes ver en la siguiente imagen (tomada del manual de PGF, apartado 66.2 Formas Predefinidas) puedes ver los efectos mucho más claros gracias a una ridícula línea alta:
Todas las formas también proporcionan anclajes que se basan en la línea base del texto real: text
, base
y además de , y . Esto hace que ya sea posible utilizarbase west
base east
mid
mid west
mid east
\documentclass[tikz]{standalone}
\begin{document}
\begin{tikzpicture}
\draw [thick, ->] (0,0) -- node[at start, anchor=mid east] {Source}
node[at end, anchor=mid west] {Target} (1,0);
\end{tikzpicture}
\end{document}
(Por supuesto, si el borde es draw
n, obtendrás un borde en diferentes alturas verticales nuevamente, pero luego puedes usar text depth
y text height
y/o \strut
(que es igual a text depth=+.3\baselineskip, text height=+.7\baselineskip
).
Un problema tonto con los anclajes medios.
Los anclajes medios se encuentran 0,5 ex por encima de la línea de base (y sus anclajes). ¡Pero cuidado! Aunque se trata de una unidad de longitud que depende del tamaño de fuente, TikZ la implementa de forma un poco tonta. Observe lo que sucede cuando agrega [nodes={font=\Huge}]
al tikzpicture
entorno del ejemplo anterior:
Con [nodes={/utils/exec=\Huge}]
(o simplemente usando \Huge
después del inicio de tikzpicture
) obtienes el resultado que esperabas.
¿Cómo dibuja TikZ un camino entre nodos?
Los anclajes medios parecen una buena solución, ¿verdad?
Incluso si coloca los nodos de manera que sus líneas de base (o sus "líneas medias") estén ubicadas en la misma altura vertical, la conexión como en
\documentclass[tikz]{standalone}
\usetikzlibrary{positioning}
\begin{document}
\begin{tikzpicture}
\node (s) {Source}; \node (t) [mid right=of s] {Target};
\draw [thick, ->] (s) -- (t);
\end{tikzpicture}
\end{document}
no se dejará arrastrar por nuestros deseos.
Cuando le pides a TikZ que conecte dos nodos con una forma (es decir, todos menos coordinate
s), utiliza puntos en el borde de las formas de los nodos. Para una línea hacia ( --
), "dispara" desde el centro de un nodo al centro del otro nodo. Donde este rayo llega al borde del nodo se establece el inicio real de la línea. De hecho, esto no es nada diferente a los anclajes angulares, por lo que el ejemplo anterior podría resultar igual que
\draw [thick, ->] (s.359) -- (t.179);
La solución a todo esto es obvia:
\draw [thick, ->] (s.mid east) -- (t.mid west);
Pero esto requiere que usted elija selectivamente los anclajes (que pueden estar ocultos en un to path
pero que también se volverán complejos rápidamente si desea cubrir todas las combinaciones posibles de ubicación de nodos, así como inicios y objetivos).
¿Por qué no movemos el center
ancla entonces?
Eltikz-cd
proporciona una forma nombrada asymmetrical rectangle
que nos da un center
ancla (y east
y west
) que se define de manera similar a las mid
anclas habituales. En lugar de un valor fijo, se utiliza .5ex
la clave. /tikz/commutative diagrams/center yshift
Desafortunadamente, esto sufre el mismo problema con respecto al tamaño de fuente que los anclajes medios.
Código
\documentclass[tikz]{standalone}
\usepackage{tikz-cd}\tikzset{nodes={shape=asymmetrical rectangle}}
\usetikzlibrary{positioning}
\begin{document}
\begin{tikzpicture}
\draw [thick, ->] (0,0) -- node[at start, left] {Source}
node[at end, right] {Target} (1,0);
\end{tikzpicture}
\begin{tikzpicture}
\node (s) {Source}; \node (t) [right=of s] {Target};
\draw [thick, ->] (s) -- (t);
\end{tikzpicture}
\end{document}