Tikz 标签根据字母大小移动

Tikz 标签根据字母大小移动

内在行为的一般描述

tikz 图片中的标签被移动(例如,通过上方)到标签中字母的极端,即它采用下降符(参见维基百科中有关 descender 的条目) 的字母,例如字母“g”(或 Sphinx 的“p”)。

在此处输入图片描述

不同方面(为什么问这个问题)

但以下例子看起来不再对称了。

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

为了锚定到上升或下降,您可以使用例如anchor=north。这会将节点锚定在节点上边缘的中间。但是,节点内部有一些不可见的填充(尝试添加例如fill=blue以查看填充)。要删除填充,请使用inner sep=0pt。锚点位置的其他选择包括north east、、等north westsouth 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}

在我的例子中,我将节点(实际上是节点标签)系统地放置在另一个宏中,因此使用宏重置所有节点的框并不困难。如果您手动设置许多节点,那么将它们每个都包装在宏中可能会很困难。

相关内容