我想旋转 TikZ 边缘标签文本中的每个字符,同时保持边缘标签的方向不变。
以下代码:
\documentclass{standalone}
\usepackage{tikz}
% TikZ styles
\tikzset{
root/.style={circle,draw=red!70,fill=red!30},
leaf/.style={circle,draw=blue!70,fill=blue!30},
label/.style={sloped,above}
}
\begin{document}
\begin{tikzpicture}
\node [root] {$r$}
child { node [leaf] {$l_1$}
edge from parent
node[label] {\texttt{CBA}}
}
child { node [leaf] {$l_2$}
edge from parent
node[label] {\texttt{ABC}}
};
\end{tikzpicture}
\end{document}
产生这个:
文本根据边缘方向倾斜,这很好。但是,我想要实现的是保持文本基线倾斜,同时单独旋转每个字符。如果需要,我还想调整字符间距。
我想要实现的效果是让每个字符看起来好像根本没有旋转,同时改变整个文本的方向。结果应该是这样的:
有什么方法可以实现吗?我知道我可以沿着边缘的路径放置一些包含单个字母的节点,但我想知道是否有更简单的方法。
理想情况下,我更喜欢拥有某种风格,比如说slopedandrotated
,它可以做到这一点。
答案1
可以稍微改变装饰以使单个字符直立。此解决方案需要使用和text along path
进行一些手动调整才能正确定位,但效果很好。它支持原始装饰的所有选项,如手册中所述。要使用文本格式选项,您必须将它们括在分隔符中,默认为。我添加了一个选项来增加单个字母之间的间距,称为,因为某些字体选项在默认间距下看起来不太好。raise
text align/left indent
text along path
|
kern factor
\documentclass[border=5mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations.text}
% TikZ styles
\tikzset{
root/.style={circle,draw=red!70,fill=red!30},
leaf/.style={circle,draw=blue!70,fill=blue!30},
label/.style={sloped,above}
}
\makeatletter
\tikzset{
/pgf/decoration/kern factor/.code=\pgfmathsetmacro\tikz@textalongpath@kern{0.5*#1},
/pgf/decoration/kern factor=1
}
\pgfdeclaredecoration{text along path not sloped}{initial}{
\state{initial}[width=+0pt, next state=left indent,
persistent precomputation={%
\edef\pgf@lib@dec@text@indent@left{\pgfkeysvalueof{/pgf/decoration/text align/left indent}}%
\edef\pgf@lib@dec@text@indent@right{\pgfkeysvalueof{/pgf/decoration/text align/right indent}}%
\edef\pgf@lib@dec@text@align{\pgfkeysvalueof{/pgf/decoration/text align/align}}%
\pgfdecoratedremainingdistance=\pgfdecoratedpathlength%
\advance\pgfdecoratedremainingdistance by-\pgf@lib@dec@text@indent@right\relax%
\edef\pgfdecoratedpathlength{\the\pgfdecoratedremainingdistance}%
\pgf@lib@dec@text@getwidth%
\pgf@x=\pgf@lib@dec@text@width\relax%
\pgf@y=\pgfdecoratedremainingdistance%
\ifpgf@lib@dec@text@fit%
\advance\pgf@y by-\pgf@lib@dec@text@indent@left\relax%
\advance\pgf@y by-\pgf@x%
\ifpgf@lib@dec@text@stretch@spaces%
\def\pgf@lib@dec@text@character@shift{0pt}%
\divide\pgf@y by\pgf@lib@dec@space@count\relax%
\edef\pgf@lib@dec@text@space@shift{\the\pgf@y}%
\else%
\c@pgf@counta=\pgf@lib@dec@character@count\relax%
\advance\c@pgf@counta by-1\relax%
\divide\pgf@y by\c@pgf@counta\relax%
\edef\pgf@lib@dec@text@character@shift{\the\pgf@y}%
\def\pgf@lib@dec@text@space@shift{0pt}%
\fi%
\ifdim\pgf@y<0pt\relax%
\pgf@lib@dec@text@fitfalse%
\pgf@lib@dec@text@stretch@spacesfalse%
\def\pgf@lib@dec@text@character@shift{0pt}%
\def\pgf@lib@dec@text@space@shift{0pt}%
\fi%
\else%
\def\pgf@lib@dec@text@character@shift{0pt}%
\def\pgf@lib@dec@text@space@shift{0pt}%
\ifx\pgf@lib@dec@text@align\pgf@lib@dec@text@left@text%
\else%
\ifx\pgf@lib@dec@text@align\pgf@lib@dec@text@right@text%
\advance\pgf@y by-\pgf@x%
\edef\pgf@lib@dec@text@indent@left{\the\pgf@y}%
\else%
\advance\pgf@y by-\pgf@x%
\advance\pgf@y by-\pgf@lib@dec@text@indent@left\relax%
\pgf@y=0.5\pgf@y%
\advance\pgf@y by\pgf@lib@dec@text@indent@left\relax%
\edef\pgf@lib@dec@text@indent@left{\the\pgf@y}%
\fi%
\fi%
\fi%
\let\pgfdecorationrestoftext=\pgfdecorationtext%
}]{}
\state{left indent}[width=+\pgf@lib@dec@text@indent@left, next state=scan]{}
%
\state{scan}[width=+0pt, next state=before typeset,
persistent precomputation={
\pgf@lib@dec@text@scanchar%
\ifvoid\pgf@lib@dec@text@box%
\setbox\pgf@lib@dec@text@box\hbox{}%
\wd\pgf@lib@dec@text@box16383pt\relax%
\fi%
}]{}
%
\state{before typeset}[width=+\tikz@textalongpath@kern\wd\pgf@lib@dec@text@box, next state=typeset]{}
%
\state{typeset}[width=+0pt, next state=after typeset]
{%
\pgftransformresetnontranslations
\setbox\pgf@hbox\hbox{\copy\pgf@lib@dec@text@box}%
\pgfqboxsynced\pgf@hbox%
}
\state{after typeset}[width=+.5\wd\pgf@lib@dec@text@box, next state=shift,
persistent precomputation={%
\ifpgf@lib@dec@text@fit%
\ifpgf@lib@dec@text@stretch@spaces%
\ifpgf@lib@dec@text@scan@space%
\let\pgf@lib@dec@text@shift=\pgf@lib@dec@text@space@shift%
\else%
\def\pgf@lib@dec@text@shift{0pt}%
\fi%
\else%
\let\pgf@lib@dec@text@shift=\pgf@lib@dec@text@character@shift%
\fi%
\else%
\def\pgf@lib@dec@text@shift{0pt}%
\fi%
}]{}
\state{shift}[width=+\pgf@lib@dec@text@shift, next state=scan]{}
\state{final}{}
}
\makeatother
\begin{document}
\begin{tikzpicture}
\node [root] {$r$}
child { node [leaf] {$l_1$}
edge from parent[postaction={
decorate,
decoration={
text along path not sloped,
raise=-1.75ex,
text={|\ttfamily|CBA},
text align/left indent=0.5em,
kern factor=2
}
}]
}
child { node [leaf] {$l_2$}
edge from parent [postaction={
decorate,
decoration={
text along path not sloped,
raise=0.4ex,
text={|\ttfamily|ABC},
text align/left indent=0.3em,
kern factor=2
}
}]
};
\end{tikzpicture}
\end{document}