tikz 矢印を x-height 文字に揃える

tikz 矢印を x-height 文字に揃える

矢印TeXは、x 文字の高さで垂直方向に中央揃えされているように見えます。この場合は最後のe:

\documentclass{article}
\begin{document}
Source $\rightarrow$ Target
\end{document}

ここに画像の説明を入力してください

TikZ一方、矢印は、キャップハイト文字(この場合は大文字と)を使用して垂直方向に中央揃えされているように見えSます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} 

ここに画像の説明を入力してください

左側の単語は x ハイト文字で終わり、右側の単語はキャップハイト文字で始まるため、右側の単語が左側の単語よりも高い位置に配置されているという錯覚が生じます (少なくとも私にはそう見えます)。x ハイト文字を使用して矢印をTikZ垂直に中央に配置することで、この問題を回避したいと思います。どうすればよいでしょうか。


編集

実はこれは錯覚ではないことに今気づきました。右側の単語はは、ベースラインの下に表示される文字が含まれているため、より高く配置されますg。この問題を今すぐ回避するには (別の質問にするべきだと思いますが)、次の例を検討してください。矢印は、前の に対して中央に配置されておらずe、間違っているように見えます。

ここに画像の説明を入力してください

答え1

TikZ は hboxes を使用してノードの内容を入力します。テキストの深さが明示的に指定されていない場合、ディセンダーによってノードの高さが変わります。したがって、ディセンダーのあるテキストとディセンダーのないテキストがある場合、その高さは必然的に異なります。それだけです。驚くようなことはなく、変更する必要もほとんどありません。

ディセンダーがない場合、なぜテキストの深さが必要なのかとおっしゃいましたが、これもまた、すべての文字を解析してディセンダーがあるかどうかをチェックすることなく、ディセンダーのあるノードとないノードが適切に揃っているかどうかを確認するためです。

しかし!

ノードの周囲に境界線を描画しない場合は、テキストの深さをリセットしてそのままにしておくことができます。

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

ここに画像の説明を入力してください

あるいは、もう少し手間をかけて接続を描画することに抵抗がない場合は、ノードをベースラインに合わせて配置し、ディセンダーもそれに合わせて配置することができます。ただし、その場合、ノードは水平方向に完全には揃わないため、たとえばオルソ識別子を使用して接続を描画する必要があります。

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

ここに画像の説明を入力してください

leftとの両方を使用する場合は、いくつかの準備が必要であることに注意してくださいmid。私の知る限り、すぐにはサポートされません。

答え2

フォローアップ打楽器答えtext depth = 0を使用すると、ボックスの下部がディセンダーを持つ文字がないかのように描画されることを示すことができます。また、 を使用してtext height = 1ex、ボックスの上部がすべての文字が 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}

ここに画像の説明を入力してください

その結果、矢印は x 高さの文字の中央に垂直に揃えられます。

答え3

TikZ/PGF はどのようにしてノード内にテキストを配置するのでしょうか?

1 つの部分を持つ単純なノード (この例ではシェイプを使用します) の場合、 TikZ はすべてのノードの内容を 1 つの TeX ボックス (通常どおり幅、高さ、深さを持つ) に配置し、その周りにパディングとrectangleを使用してパスを構築します。/pgf/inner xsep/pgf/inner ysep

ノードの中心は TeX ボックスの中心になります。高さと深さが異なるボックスの場合、これはボックス間で同じ垂直高さ (ベースラインを基準として) にはなりません。

TikZ はどのようにノードを配置しますか?

この例では、 と が使用されていますleftが、これらは基本的にそれぞれと とright同じです。これらのアンカーは、アンカーと同じ垂直の高さ (定義により) にあり、ノードのそれぞれの境界上にあります。anchor=eastanchor=westcenter

次の画像 (PGF マニュアルのセクション 66.2「定義済みシェイプ」より) からわかるように、非常に高い線のおかげで、効果がより明確にわかります。
ここに画像の説明を入力してください

すべての図形には、実際のテキストのベースラインに基づいたアンカー(text、、、および、、)も用意されています。これによりbasebase westbase eastmidmid westmid 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} 

(もちろん、境界線が n の場合、異なる垂直の高さの境界線が再び表示されますが、その場合はandおよび/または(に等しいdraw) を使用できます。)text depthtext height\struttext depth=+.3\baselineskip, text height=+.7\baselineskip

ミッドアンカーの馬鹿げた問題

中間アンカーはベースライン(およびそのアンカー)より 0.5ex 上にあります。ただし注意してください。これはフォント サイズに依存する長さの単位ですが、TikZ はこれを少しおかしな方法で実装しています。上記の例の環境[nodes={font=\Huge}]に追加すると何が起こるか観察してください。tikzpicture
ここに画像の説明を入力してください

を使用すると[nodes={/utils/exec=\Huge}](または\Hugeの開始後にを使用するだけtikzpicture)、予想どおりの出力が得られます。

TikZ はノード間のパスをどのように描画しますか?

ミッドアンカーは良い解決策のように思えますね。

ノードのベースライン(または「中線」)が同じ垂直高さに位置するようにノードを配置したとしても、

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

私たちの願いには従わないでしょう。

TikZ に 2 つのノードをシェイプ (つまりcoordinates 以外) で接続するように指示すると、ノードのシェイプの境界上の点が使用されます。line-to ( --) の場合、1 つのノードの中心から別のノードの中心に向かって「発射」されます。この光線がノードの境界に当たる場所に、実際のラインの開始点が設定されます。これは実際には角度アンカーと何ら変わりません。したがって、上記の例では、次のようになる可能性があります。

\draw [thick, ->] (s.359) -- (t.179);

これらすべてに対する解決策は明らかです。

\draw [thick, ->] (s.mid east) -- (t.mid west);

ただし、これにはアンカーを選択的に選択する必要があります (アンカーは 内に隠すことができますto pathが、開始とターゲットだけでなくノード配置のすべての可能な組み合わせをカバーする場合は、すぐに複雑になります)。

では、アンカーを移動してみませんかcenter?

tikz-cdは、通常のアンカーと同様に定義されたアンカー (およびおよび) を提供asymmetrical rectangleする という名前のシェイプを提供します。 固定値の代わりに、キーの値が使用されます。 残念ながら、これには、mid アンカーと同じフォント サイズに関する問題があります。centereastwestmid.5ex/tikz/commutative diagrams/center yshift

ここに画像の説明を入力してください

コード

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

関連情報