tikz 画像のスタッキング/グループ化コマンド定義

tikz 画像のスタッキング/グループ化コマンド定義

私は、tikz 画像を作成するために使用するコマンドを多用するパッケージに取り組んでいますpgfkeys。以下は簡単な例です。

\documentclass[tikz,border=5pt]{standalone}
\makeatletter
\usetikzlibrary{shapes.geometric, calc}
\newcommand{\example}[2][]{
\tikzset{
 /Example/.cd,
 caption/.store in=\Example@caption,
 caption=X,
 #1,
}
\draw [local bounding box=M] rectangle (1,1);
\node at (0.5,0.5) {\Example@caption};
}
\makeatother
\begin{document}
\begin{tikzpicture}
\example[caption=A];
\end{tikzpicture}
\end{document}

予想どおり、次の出力が得られます。

マクロ出力

(これは簡略化のために作成された例であり、実際のコマンドの複雑さを反映していないことに注意してください。実際のコマンドには、より複雑なことを実行するキーが多数含まれています)。

私が作成したいのは、異なるキー値を使用してコマンドの 1 つを複数回追加できる 2 つの新しいリスト環境です。結果の画像は、tikz で描画された中括弧で「グループ化」されるか、コマンド内で定義されたローカル境界ボックスの南西隅から一定の長さまで伸びた線で「積み重ね」られ、次の画像がある場合はそれと接続されます (すべて等間隔になり、各画像の全体的なサイズは同じになります)。

スタックとグループ

私が理想的に探しているのは、次のようなリスト環境構造です。

\begin{examplestack}
    \item \example[caption=A] 
    \item \example[caption=B] 
    \item \example[caption=C] 
\end{examplestack}

\begin{examplegroup}
    \item \example[caption=A] 
    \item \example[caption=B] 
    \item \example[caption=C] 
\end{examplegroup}

スタックとグループは両方ともtikzpictureキャンバス内で原点オフセットを持つ必要があります。グループは中括弧の先端、スタックは最後の行の下部 (「旗竿」の下部) になります。これにより、別のレイヤー (マップなど) に重ねる場合に正しく配置できます。

答え1

概念実証。少なくともこの単純なケースでは機能するようです。長さはあちこちで調整する必要があります。たとえば、各アイテムの垂直方向のシフトは、単純に 1.2cm にハードコードされています。一般的に、これはあまり柔軟なアプローチではありません。もっと良い方法がある人がいると思います。

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

\documentclass[tikz,border=5pt]{standalone}
\makeatletter
\usetikzlibrary{shapes.geometric, calc}
\newcommand{\example}[2][]{
\tikzset{
 /Example/.cd,
 caption/.store in=\Example@caption,
 caption=X,
 #1,
}
\draw [local bounding box=M] rectangle (1,1);
\node at (0.5,0.5) {\Example@caption};
}
\makeatother

\newcounter{exitem}

\newenvironment{examplestack}{
\setcounter{exitem}{0}
\renewcommand\item{
% if you only want to draw a line between items
%\ifnum \value{exitem}>0
%  \draw ([xshift=0.5\pgflinewidth]current bounding box.south west) -- ++(0,-0.2cm);
%\fi
%
% if you also want the line below the last item -- not very elegant
\draw (0,{-(1.2cm+\theexitem*1.2cm)}) -- ++(0,-2mm);
%
\stepcounter{exitem}\scoped[yshift=-\theexitem*1.2cm]}
\tikzpicture
}{
%\draw (current bounding box.north west) -- ([yshift=-3pt]current bounding box.south west);
\node [above right] at (current bounding box.north west) {``Stack''};
\endtikzpicture
}

\newenvironment{examplegroup}{
\setcounter{exitem}{0}
\renewcommand\item{\stepcounter{exitem}\scoped[yshift=-\theexitem*1.2cm]}
\tikzpicture
}{
\draw ([shift={(5pt,3pt)}]current bounding box.north west) -| ([shift={(-3pt,-3pt)}]current bounding box.south west) -- ++(8pt,0)
 (current bounding box.west) -- ++(-5pt,0);

\node [above right] at (current bounding box.north west) {``Group''};
\endtikzpicture
}


\begin{document}
\begin{examplegroup}
\item\example[caption=A];
\item\example[caption=B];
\item\example[caption=C];
\end{examplegroup}

\begin{examplestack}
\item\example[caption=A];
\item\example[caption=B];
\item\example[caption=C];
\end{examplestack}
\end{document}

答え2

私は、この問題に対する Torbjørn T の回答よりも優れた、より柔軟な解決策を思いついたので、これに回答を追加すべきだと感じています。彼らの解決策では、高さの異なる写真の間隔を同じにすることはできませんでした。長さマクロを使用することで、前の画像の長さを保存し、それを使用して次の画像をオフセットすることができ、座標セットを使用してそれらを「スタック」に結合することができました。

重要な注意点: は\item1 つの引数を取るように再定義されたため、環境内では\item{<picture>}の代わりにを使用する必要があります\item <picture>

このソリューションは、xparseよりクリーンなコマンドと環境構文を使用しますが、単純な LaTeX ソリューションも同様に簡単に使用できます。

前文(および MWE からの残りの部分):

\newcounter{exitem}
\newlength{\itemlength}

「スタック」構文:

\NewDocumentEnvironment{examplestack}{}{
\setlength{\itemlength}{0}
\begin{scope}
\setcounter{exitem}{0}
\RenewDocumentCommand\item{m}{
\scoped[yshift=-\itemlength, local bounding box=T]
##1;
\ifnum \value{exitem}>0
\pgfmathtruncatemacro\result{\value{exitem}-1}
\draw ($(M.south west) + (0, -0.25)$) -- (F\result);
\fi
\coordinate (F\arabic{exitem}) at (M.north west);
\pgfpointdiff{\pgfpointanchor{T}{north west}}{\pgfpointanchor{T}{south west}}
\addtolength{\itemlength}{\pgf@y-5pt} % 5pt is the spacing between pictures.
\stepcounter{exitem}}
}{\end{scope}}

「グループ」構文:

\NewDocumentEnvironment{examplegroup}{}{
\setlength{\itemlength}{0}
\begin{scope}[local bounding box=G]
\RenewDocumentCommand\item{m}{
\scoped[yshift=-\itemlength, local bounding box=T]
##1;
\pgfpointdiff{\pgfpointanchor{T}{north west}}{\pgfpointanchor{T}{south west}}
\addtolength{\itemlength}{\pgf@y-5pt}} % 5pt is the spacing between pictures.
}{
\draw ([shift={(5pt,3pt)}]G.north west) -| ([shift={(-3pt,-3pt)}]G.south west) -- ++(8pt,0)
 (G.west) -- ++(-5pt,0);
\end{scope}}

例:

\begin{examplegroup}
\item{\example[caption=A]}
\item{\example[caption=B]}
\item{\example[caption=C]}
\end{examplegroup}

\begin{examplestack}
\item{\example[caption=A]}
\item{\example[caption=B]}
\item{\example[caption=C]}
\end{examplestack}

関連情報