
TL;DR 要約:
リーフノードの幅を測定し、この測定値をツリーに戻して設定に使用する方法はありますかsibling distance
? ( についても同様のことを実行したい場合がありますlevel distance
。)
例:
それぞれのリーフノードに同じ画像が含まれる単純なツリーがあるとします。
\documentclass{standalone}
\usepackage{tikz}
\pgfdeclareimage{image}{fptp-ballot}
\begin{document}
\begin{tikzpicture}
\node {root} [level/.append style={level distance=4cm}]
child foreach \c in {1,2} {
node [fill=red!10] {\pgfuseimage{image}}};
\end{tikzpicture}
\end{document}
のデフォルト設定ではsibling distance
、葉は重なり合います。
葉の幅を測定する 1 つの方法は、目に見えない一時的な葉 を作成しtmp
、let
パスの演算を使用してその幅を計算することです。
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}
\pgfdeclareimage{image}{fptp-ballot}
\begin{document}
\begin{tikzpicture}
\node (tmp) [fill=red!10, transparent, overlay] {\pgfuseimage{image}};
\path let \p{leafwidth} = ($(tmp.east)-(tmp.west)$) in
node {root} [level/.append style={level distance=4cm, sibling distance=\x{leafwidth}}]
child foreach \c in {1,2} {
node [fill=red!10] {\pgfuseimage{image}}};
\end{tikzpicture}
\end{document}
このアプローチの問題点は、tmp
実際に測定したいリーフがコードの後半にすでに存在しているのに、一時的なリーフ を作成する必要があるのは不格好に思えることです。これにより、モジュール性が低下します。リーフを変更する場合は、それtmp
に応じてノードを変更する必要があります (または、マクロとスタイルを使用してリーフ コードを除外する必要があります)。
言い換えれば、私は機能する解決策を望んでいます地元で葉の中に何を入れるか(単一の画像、任意のセルの内容を含むマトリックスなど)に関係なく、
質問:
幅を直接測定する方法はありますか?実際のリーフノードでこの測定値をツリーに戻して設定に使用しますかsibling distance
?
次のようなことを書きたいと思います。
\begin{tikzpicture}
\node {root} [level/.append style={level distance=4cm, sibling distance=\x{leaf1width}}]
child foreach \c in {1,2} {
node (leaf\c)
[fill=red!10] {\pgfuseimage{image}}
let \p{leaf\c width} = ($(leaf\c.east)-(leaf\c.west)$) in};
\end{tikzpicture}
ここでは、実際のsibling distance
葉があり、これを使用してルート ノードに 設定しようとしています。残念ながら、これは「未定義の制御シーケンス<argument> \x{leaf1width}
」というエラーになります。おそらく、\p{leaf\c width}
葉に到達するまで定義されないためです。このコードを修正する方法はありますか?
鍵を使うことも考えたlate options
が、TikZ マニュアルと述べています
すでに存在するノードが決定され、オプションはローカルスコープで実行されます。これらのオプションのほとんどは、ノードの外観を変更できませんつまり、late オプションを使用して赤いノードを緑のノードに変更することはできません。
実際、次のコードはエラーなしでコンパイルされますが、 はsibling distance
影響を受けません。
\begin{tikzpicture}
\node (root) {root} [level/.append style={level distance=4cm}]
child foreach \c in {1,2} {
node (leaf\c)
[fill=red!10] {\pgfuseimage{image}}
let \p{leaf\c width} = ($(leaf\c.east)-(leaf\c.west)$) in
(root) [late options={level/.append style={sibling distance=\x{leaf1width}}}]};
\end{tikzpicture}
答え1
コメントにリンクされているように、最初に画像をボックスに配置すると、画像のサイズを測定するのが非常に簡単になります。複雑さを理解しているかどうかはわかりませんが、ツリーに入る画像が少数の場合は、max(x,y)
数学ライブラリからそれらの測定値の最大値を取得できます。ここでは、マクロを削除し、自動化なしで Yiannis のソリューションを使用しました。
\documentclass{standalone}
\usepackage{tikz}
\newsavebox{\Image}
\savebox{\Image}{\includegraphics[scale=0.05]{DSOTM}}
\newlength{\imageh}
\newlength{\imagew}
\settoheight{\imageh}{\usebox{\Image}}
\settowidth{\imagew}{\usebox{\Image}}
\begin{document}
\begin{tikzpicture}
\node {root} [level/.append style={
level distance=1.5\imageh, sibling distance=1.1\imagew
}
]
child foreach \c in {1,2} {
node [fill=red!10,inner sep=1pt] {\includegraphics[scale=0.05]{DSOTM}}};
\end{tikzpicture}
\end{document}