Descrição geral do comportamento intrínseco
Os rótulos em uma imagem tikz são deslocados (por exemplo, acima) exatamente para o extremo das letras nos rótulos, ou seja, leva o descendente (vejaEntrada da Wikipedia para descendente) das letras em conta como na letra "g" (ou no "p" da Esfinge).
Aspecto diferente (por que essa pergunta)
Mas então os exemplos a seguir não parecem mais simétricos.
\documentclass{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\coordinate (leadl) at (1,0);
\coordinate (leadr) at (2,0);
\fill (leadl) circle[radius=2pt];
\fill (leadr) circle[radius=2pt];
\node[above] at (leadl) {left};
\node[above] at (leadr) {right};
\end{tikzpicture}
\end{document}
\documentclass[tikz]{standalone}
\begin{document}
\begin{tikzpicture}
\coordinate (leadl) at (1,0);
\coordinate (leadr) at (2,0);
\fill (leadl) circle[radius=2pt];
\fill (leadr) circle[radius=2pt];
\node[below] at (leadl) {lelele};
\node[below] at (leadr) {rerere};
\end{tikzpicture}
\end{document}
Questão a ser resolvida
Qual é a maneira mais fácil de contornar esse recurso (em alguns casos desejado)? Não quero analisar todos os caracteres nos rótulos de todos os nós que estou digitando.
Responder1
TikZ já entende esse problema e oferece text depth
extensão. Você pode zerar ou adicionar uma quantidade fixa de profundidade a todos os nós. Exemplo (de alguma forma gosto de design restrito)
\documentclass[tikz]{standalone}
\begin{document}
\begin{tikzpicture}[scale=1.5]
\coordinate (leadl) at (3,0);
\coordinate (leadr) at (5,0);
\fill (leadr) circle[radius=2pt];
\fill (leadl) circle[radius=2pt];
\node[above] at (leadl) {left circle};
\node[above,text depth=0pt] at (leadr) {right circle};
\end{tikzpicture}
\end{document}
Responder2
Aqui está uma solução geral com duas variantes: \strut
ou \vphantom
. Esta solução pode ser usada com nós multilinhas ou tamanhos de fonte diferentes.
\documentclass{standalone}
\usepackage{tikz}
\tikzset{
fix node via strut/.style={
execute at begin node={\strut},
execute at end node={\strut},
},
fix node via vphantom/.style={
execute at begin node={\vphantom{Ag}},
execute at end node={\vphantom{Ag}},
},
}
\begin{document}
\begin{tikzpicture}
\coordinate (leadl) at (1,0);
\coordinate (leadr) at (2,0);
\fill (leadl) circle[radius=2pt];
\fill (leadr) circle[radius=2pt];
\node[fix node via strut,above,align=center] at (leadl) {left\\left};
\node[fix node via strut,above,align=center] at (leadr) {right\\right};
\node[fix node via strut,below,font=\large] at (leadl) {lelele};
\node[fix node via strut,below,font=\large] at (leadr) {rerere};
\node[blue,above] at (current bounding box.north){via strut};
\end{tikzpicture}
\begin{tikzpicture}
\coordinate (leadl) at (1,0);
\coordinate (leadr) at (2,0);
\fill (leadl) circle[radius=2pt];
\fill (leadr) circle[radius=2pt];
\node[fix node via vphantom,above,align=center] at (leadl) {left\\left};
\node[fix node via vphantom,above,align=center] at (leadr) {right\\right};
\node[fix node via vphantom,below,font=\large] at (leadl) {lelele};
\node[fix node via vphantom,below,font=\large] at (leadr) {rerere};
\node[red,above] at (current bounding box.north){via vphantom};
\end{tikzpicture}
\end{document}
Responder3
O que você precisa fazer é adicionar anchor=base
as opções dos dois nós. Isso alinhará os dois rótulos pelas linhas de base. Provavelmente você pretendia escrever:
\node[above of=leadl, anchor=base] {left circle};
Para ancorar na subida ou descida, você usaria, por exemplo anchor=north
, . Isto irá ancorar o nó no meio da borda superior do nó. No entanto, há algum preenchimento invisível dentro do nó (tente adicionar, por exemplo, fill=blue
para ver o preenchimento). Para remover o preenchimento, use inner sep=0pt
. Outras opções para a posição da âncora incluem north east
, north west
, south east
, etc.
Responder4
Escrevi algo assim com um propósito semelhante. Provavelmente é um pouco volumoso para o que realiza, mas talvez você o ache útil.
\usepackage{xparse}
\makeatletter
\newcommand{\standardisebox}[1]{%
\smash{#1}\vphantom{\strpeters@box@determining@symbol}%
}
\let\standardizebox\standardisebox
\NewDocumentCommand{\setboxdeterminingsymbol}{sm}{%
\IfBooleanTF {#1}%
{\gdef\strpeters@box@determining@symbol{#2}}%
{\def\strpeters@box@determining@symbol{#2}}%
}
\NewDocumentCommand{\resetboxdeterminingsymbol}{s}{%
\IfBooleanTF {#1}%
{\setboxdeterminingsymbol*{0}}%
{\setboxdeterminingsymbol{0}}%
}
\resetboxdeterminingsymbol
\makeatother
A maneira como isso funciona é envolver o texto do nó \standardisebox
e ele é composto como se tivesse a altura e a profundidade de um dígito 0 em vez de sua altura e profundidade verdadeiras. Você pode alterar o caractere usado para determinar a altura e a profundidade usando a macro \setboxdeterminingsymbol
e redefini-lo para o normal usando \resetboxdeterminingsymbol
. Use os formulários marcados com estrela para mudanças globais.
\documentclass{standalone}
\usepackage{tikz}
\usepackage{xparse}
\makeatletter
\newcommand{\standardisebox}[1]{%
\smash{#1}\vphantom{\strpeters@box@determining@symbol}%
}
\let\standardizebox\standardisebox
\NewDocumentCommand{\setboxdeterminingsymbol}{sm}{%
\IfBooleanTF {#1}%
{\gdef\strpeters@box@determining@symbol{#2}}%
{\def\strpeters@box@determining@symbol{#2}}%
}
\NewDocumentCommand{\resetboxdeterminingsymbol}{s}{%
\IfBooleanTF {#1}%
{\setboxdeterminingsymbol*{0}}%
{\setboxdeterminingsymbol{0}}%
}
\resetboxdeterminingsymbol
\makeatother
\begin{document}
\begin{tikzpicture}
\coordinate (leadl) at (1,0);
\coordinate (leadr) at (2,0);
\fill (leadr) circle[radius=2pt];
\fill (leadl) circle[radius=2pt];
\node[above] at (leadl) {\standardisebox{left}};
\node[above] at (leadr) {\standardisebox{right}};
\end{tikzpicture}
\end{document}
No meu caso, eu estava colocando nós (na verdade, rótulos de nós) sistematicamente dentro de outra macro, portanto, usar a macro para redefinir todas as suas caixas não foi um trabalho árduo. Se você estiver configurando muitos nós manualmente, agrupar cada um deles na macro pode ser árduo.