Метки Tikz смещаются в зависимости от размера букв

Метки Tikz смещаются в зависимости от размера букв

Общее описание внутреннего поведения

Метки на рисунке tikz смещены (например, на ) точно к краю букв в метках, т.е. она занимает нижний выносной элемент (см.Статья Википедии о спусковом механизме) букв во внимание, как у буквы «г» (или «п» в слове «Сфинкс»).

введите описание изображения здесь

Другой аспект (почему этот вопрос)

Но тогда следующие примеры уже не выглядят симметричными.

\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}

введите описание изображения здесь

Проблема, требующая решения

Какой самый простой способ обойти эту (в некоторых случаях желаемую) особенность? Я не хочу анализировать каждый символ во всех метках узлов, которые я печатаю.

решение1

TikZ уже понимает эту проблему и предлагает text depthдлину. Вы можете либо обнулить ее, либо добавить фиксированную глубину ко всем узлам. Пример (мне почему-то нравится тесный дизайн)

\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}

введите описание изображения здесь

решение2

Вот общее решение с двумя вариантами: \strutили \vphantom. Это решение можно использовать с многострочными узлами или разными размерами шрифта.

введите описание изображения здесь

\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}

решение3

Что вам нужно сделать, так это добавить anchor=baseк опциям двух узлов. Это выровняет две метки по их базовым линиям. Вероятно, вы хотели написать:

\node[above of=leadl, anchor=base] {left circle};

Чтобы прикрепиться к подъему или спуску, используйте eg anchor=north. Это прикрепит узел к середине верхнего края узла. Однако внутри узла есть некоторая невидимая отбивка (попробуйте добавить eg , fill=blueчтобы увидеть отбивку). Чтобы удалить отбивку, используйте inner sep=0pt. Другие варианты для позиции привязки включают north east, north west, south eastи т. д.

решение4

Я написал что-то вроде этого для похожей цели. Возможно, это немного громоздко для того, что оно делает, но, возможно, вы найдете это полезным.

\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

Это работает так: вы оборачиваете текст узла, \standardiseboxи он набирается так, как будто имеет высоту и глубину цифры 0 вместо его истинной высоты и глубины. Вы можете изменить символ, используемый для определения высоты и глубины, с помощью макроса \setboxdeterminingsymbolи сбросить его до обычного с помощью \resetboxdeterminingsymbol. Используйте звездчатые формы для глобальных изменений.

\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}

В моем случае я размещал узлы (фактически метки узлов) систематически внутри другого макроса, поэтому использование макроса для сброса всех их полей не было сложной работой. Если вы устанавливаете много узлов вручную, то обертывание каждого из них в макрос может оказаться трудным.

Связанный контент