Ein TeX
scheinbar vertikal zentrierter Pfeil hat die Höhe eines x-Zeichens, in diesem Fall das letzte e
:
\documentclass{article}
\begin{document}
Source $\rightarrow$ Target
\end{document}
Ein TikZ
Pfeil hingegen scheint vertikal zentriert zu sein und ein Zeichen in Großbuchstaben zu haben, in diesem Fall ein Großbuchstabe S
und 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}
Da das linke Wort mit einem Buchstaben in x-Höhe endet und das rechte Wort mit einem Buchstaben in Großbuchstaben beginnt, entsteht (zumindest bei mir) die optische Täuschung, dass das rechte Wort höher steht als das linke. Dies möchte ich vermeiden, indem ich den TikZ
Pfeil vertikal mit einem Buchstaben in x-Höhe zentriere. Wie kann ich das erreichen?
BEARBEITEN
Eigentlich ist mir gerade aufgefallen, dass es sich hier nicht um eine optische Täuschung handelt. Das Wort rechtsIsthöher platziert, weil es den Buchstaben enthält g
, der unter die Grundlinie geht. Um dieses Problem sofort zu vermeiden (ich denke, es sollte eine separate Frage sein), betrachten Sie das folgende Beispiel. Der Pfeil ist in Bezug auf das vorhergehende nicht zentriert e
, und das sieht für mich falsch aus:
Antwort1
TikZ verwendet Hboxen, um den Knoteninhalt einzugeben. Wenn keine explizite Texttiefe angegeben ist, bewirken die Unterlängen eine Änderung der Knotenhöhe. Wenn Sie also einen Text mit und ohne Unterlängen haben, ist deren Höhe zwangsläufig unterschiedlich. Das ist alles. Es gibt keine Überraschungen und auch nicht viel zu ändern.
Sie haben erwähnt, warum Sie eine Texttiefe benötigen, wenn Sie keine Unterlänge haben. Dabei geht es wiederum darum, sicherzustellen, dass alle Knoten mit/ohne Unterlängen richtig ausgerichtet sind, ohne wirklich jeden Buchstaben zu analysieren und zu prüfen, ob einer vorhanden ist.
Aber!
Wenn Sie keine Rahmen um die Knoten zeichnen, können Sie die Texttiefe zurücksetzen und damit leben.
\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}
Oder alternativ, wenn es Ihnen nichts ausmacht, die Verbindung mit etwas mehr Aufwand zu zeichnen, können Sie die Knoten in Bezug auf ihre Grundlinie ausrichten, wobei die Unterlängen diese berücksichtigen. Allerdings sind die Knoten dann nicht horizontal perfekt ausgerichtet und Sie müssen die Verbindungen beispielsweise mit Ortho-Bezeichnern zeichnen.
\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}
Beachten Sie, dass Sie einige Vorbereitungen treffen müssen, wenn Sie sowohl left
als auch verwenden möchten mid
. Soweit ich weiß, wird es nicht sofort unterstützt.
Antwort2
Folgend aufSchlagzeug'SAntwortkönnen wir verwenden, text depth = 0
um anzugeben, dass die Unterseite der Box so gezeichnet wird, als gäbe es keine Zeichen mit Unterlängen, und verwenden, text height = 1ex
um die Oberseite der Box so zu zeichnen, als hätten alle Zeichen die Höhe 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}
Das Ergebnis ist, dass der Pfeil vertikal auf die Mitte der Zeichen mit der x-Höhe ausgerichtet ist.
Antwort3
Wie platziert TikZ/PGF Text in einem Knoten?
Für einfache Knoten (und ich werde rectangle
für dieses Beispiel die Form verwenden) mit einem Teil fügt TikZ den gesamten Knoteninhalt in eine TeX-Box ein (mit einer Breite, einer Höhe und einer Tiefe wie üblich) und konstruiert mit der Polsterung /pgf/inner xsep
und einen Pfad darum herum /pgf/inner ysep
.
Der Mittelpunkt des Knotens ist der Mittelpunkt der TeX-Box. Bei Boxen mit unterschiedlichen Höhen und Tiefen liegt dieser nicht bei allen Boxen auf derselben vertikalen Höhe (relativ zur Grundlinie).
Wie platziert TikZ Knoten?
In Ihrem Beispiel verwenden Sie left
und, right
was im Grunde dasselbe ist wie anchor=east
bzw. anchor=west
Diese Anker liegen auf der gleichen vertikalen Höhe wie der center
Anker (per Definition) und am jeweiligen Rand des Knotens.
Wie Sie dem folgenden Bild (aus dem PGF-Handbuch, Abschnitt 66.2 Vordefinierte Formen) entnehmen können, sind die Effekte dank einer absurd hohen Linie viel deutlicher zu erkennen:
Alle Formen bieten außerdem Anker, die auf der Grundlinie des eigentlichen Textes basieren: text
, base
, base west
und base east
sowie mid
, mid west
und mid east
. Damit ist es bereits möglich,
\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
(Wenn der Rand n ist, erhalten Sie natürlich wieder Ränder auf unterschiedlichen vertikalen Höhen, aber dann können Sie text depth
und text height
und/oder verwenden \strut
(was gleich ist text depth=+.3\baselineskip, text height=+.7\baselineskip
).)
Ein dummes Problem mit mittleren Ankern
Die mittleren Anker liegen 0,5ex über der Grundlinie (und ihren Ankern). Aber Vorsicht! Obwohl dies eine von der Schriftgröße abhängige Längeneinheit ist, implementiert TikZ sie etwas albern. Beobachten Sie, was passiert, wenn Sie [nodes={font=\Huge}]
die tikzpicture
Umgebung des obigen Beispiels erweitern:
Mit [nodes={/utils/exec=\Huge}]
(oder einfach durch Verwendung \Huge
nach dem Beginn von tikzpicture
) erhalten Sie die Ausgabe, die Sie möglicherweise erwartet haben.
Wie zeichnet TikZ einen Pfad zwischen Knoten?
Die Mittelanker scheinen eine gute Lösung zu sein, oder?
Auch wenn Sie die Knoten so positionieren, dass ihre Basislinien (oder ihre "Mittellinien") auf der gleichen vertikalen Höhe liegen, bleibt die Verbindung wie in
\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}
wird nicht unseren Wünschen folgen.
Wenn Sie TikZ bitten, zwei Knoten mit einer Form zu verbinden (also alle außer coordinate
s), verwendet es Punkte an den Rändern der Knotenformen. Bei einer Linie zu ( --
) „schießt“ es vom Mittelpunkt eines Knotens zum Mittelpunkt des anderen Knotens. Wo dieser Strahl den Rand des Knotens trifft, wird der eigentliche Start der Linie festgelegt. Dies ist in der Tat nichts anderes als die Winkelanker, daher könnte das obige Beispiel genau dasselbe ergeben wie
\draw [thick, ->] (s.359) -- (t.179);
Die Lösung für all dies liegt auf der Hand:
\draw [thick, ->] (s.mid east) -- (t.mid west);
Dazu müssen Sie jedoch die Anker selektiv auswählen (die in einem versteckt werden können, to path
aber auch das wird schnell komplex, wenn Sie alle möglichen Kombinationen von Knotenplatzierungen sowie Starts und Zielen abdecken möchten).
Warum verschieben wir center
dann nicht einfach den Anker?
Dertikz-cd
bietet eine Form namens , die uns einen Anker (und und ) asymmetrical rectangle
liefert , der ähnlich definiert ist wie die üblichen Anker. Anstelle eines festen Werts wird der Wert des Schlüssels verwendet. Leider hat dies dasselbe Problem bezüglich der Schriftgrößen wie die mittleren Anker.center
east
west
mid
.5ex
/tikz/commutative diagrams/center yshift
Code
\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}