箭頭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 高度字元結尾,而右側的單字以大寫高度字元開頭,因此這會產生視覺錯覺(至少對我而言),即右側的單字位置高於右側的單字。我想透過將TikZ
箭頭與 x 高度字元垂直居中來避免這種情況。我怎樣才能做到這一點?
編輯
事實上我只是注意到這不是視錯覺。右邊這個詞是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 如何將文字放置在節點內?
對於簡單的節點(我將在本例中使用形狀rectangle
),TikZ 將所有節點內容放入 TeX 框中(與往常一樣具有寬度、高度和深度),並使用 padding/pgf/inner xsep
和建立圍繞它的路徑/pgf/inner ysep
。
節點的中心將是 TeX 框的中心。對於具有不同高度和深度的盒子,盒子之間的垂直高度(相對於基線)不會相同。
TikZ 如何放置節點?
在您的範例中,您使用的left
和分別與和right
基本相同。這些錨點與錨點位於相同的垂直高度(根據定義),並且位於節點的相應邊界上。anchor=east
anchor=west
center
如下圖所示(取自 PGF 手冊第 66.2 節預定義形狀),由於一條荒謬的高線,您可以更清晰地看到效果:
所有形狀還提供基於實際文字基線的錨點:text
、base
、base 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}
(當然,如果邊框為draw
n,您將再次獲得不同垂直高度的邊框,但您可以使用text depth
和text height
和/或\strut
(等於text 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 用形狀(即 s 之外的所有節點)連接兩個節點時,coordinate
它會使用節點形狀邊界上的點。對於 line-to ( --
),它從一個節點的中心「射」到另一個節點的中心。當這條射線撞擊節點的邊界時,線的實際起點被設定。事實上,這與角度錨點沒有什麼不同,因此上面的範例可能會導致與
\draw [thick, ->] (s.359) -- (t.179);
所有這一切的解決方案是顯而易見的:
\draw [thick, ->] (s.mid east) -- (t.mid west);
但這需要您有選擇地選擇錨點(可以隱藏在 a 中,to path
但如果您想覆蓋節點放置以及開始和目標的所有可能組合,這也會很快變得複雜)。
那我們為什麼不直接移動center
錨點呢?
這tikz-cd
提供了一個名為的形狀asymmetrical rectangle
,它為我們提供了一個center
錨點(和east
)west
,其定義與通常的mid
錨點類似。使用鍵.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}