tikz マトリックスでのノード エッジの描画を制御する

tikz マトリックスでのノード エッジの描画を制御する

特定のサイズのノードのグリッドを描画しようとしています。さらに、セル、特にセルの内側の境界線を白くすることで、このグリッドに穴を開けようとしています。これを具体的にするには、次の点を考慮してください。

\documentclass[tikz]{standalone}
\usetikzlibrary{fit, matrix}

\begin{document}

\begin{tikzpicture}
\matrix [
    matrix of nodes,
    inner sep=0pt,                % no padding around the cells
    row sep=-\pgflinewidth,
    column sep=-\pgflinewidth,
    nodes={
        rectangle, draw=black, minimum height=11mm, minimum width=11mm,
        anchor=center, inner sep=0pt, outer sep=0pt
    },
    nodes in empty cells,
    name=table
] {
& & & & \\
& & |[white]| & & \\
& |[white]| & |[white]| & & \\
& & |[white]| & |[white]| & \\
& & & & \\
};

\end{tikzpicture}
\end{document}

一般的に、マトリックス内に任意の白いセルの「島」があるとします。この場合、島は 1 つ (サイズ 5) だけであり、白いセルはホスト グリッドの接続されたサブグラフにまたがりますが、このような島が複数存在する場合もあります。

内側の境界線は描画しないようにしたいのですが、外側の境界線はそのままにしておきたいのです。現状では、外側の境界線は端だけが描画され、灰色っぽく見えてしまいます。望ましくない出力については以下を参照してください。

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

ノードとそのエッジの描画をより適切に制御するにはどうすればよいでしょうか?この質問これは、これらをもっときれいに描画するのに役立つかもしれません。私はこれをプログラムで実行しているので、島の座標をリストのような方法で指定できると便利そうです。

答え1

白い境界線を描く代わりに、境界線を描かないでください。そうすれば、灰色の線 (実際には黒の上に白の線) は表示されなくなります。

以下のコードでは、matrix of grid nodes = <rows> x <columns>各セルに含まれる行数と列数を指定して TikZ マトリックスを設定します\node{};。デフォルトでは、これらの各ノードは になりますgrid node

キーを使用することで、 を代わりに使用するisland(s)セルを指定できます。 は単純に(つまり) ですが、任意の値、たとえば座標だけ (ただし、そのためには または をで実行する必要があります。そうしないと、行または列全体に島が含まれている場合に、サイズがゼロの行または列が生成されます) になります。grid island nodegrid island nodepath onlydraw = none, fill = node, …row sepcolumn sepbetween origins

代わりに、通常は各セルに\node{};配置することができますが、島の場合はセルに何も配置しないこともできます (座標さえも配置できません)。\tikzgridnode\node[grid node]{};

コード

\documentclass[tikz]{standalone}
\makeatletter
\newcommand*\utilrepeat[2]{%
  \ifnum#1=1 \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
    {#2}{#2\expandafter\utilrepeat\expandafter{\the\numexpr#1-1\relax}{#2}}}
\makeatother
\tikzset{
  grid node/.style={
    shape=rectangle, draw=black, fill=lightgray, anchor=center,
    minimum size=+11mm, inner sep=+0pt, outer sep=+0pt},
%  grid island node/.style={shape=coordinate}, % no node, just a coordinate
  grid island node/.style=path only,         % node but no output
  tight matrices/.style={every outer matrix/.append style={inner sep=+0pt}},
  matrix of grid nodes/.style args={#1x#2}{
    matrix, tight matrices, nodes=grid node,
    row sep=+-\pgflinewidth, column sep=+-\pgflinewidth,
    execute at empty cell=\node{};,
    node contents=%
      \utilrepeat{#1}{%
        \utilrepeat{\pgfinteval{#2-1}}{\pgfmatrixnextcell}\pgfmatrixendrow}},
  island/.style args={#1-#2}{
    row #1 column #2/.append style={nodes=grid island node}},
  islands/.style={island/.list={#1}}}
\begin{document}
\tikz\node[matrix of grid nodes = 5 x 5, islands = {2-3, 3-2, 3-3, 4-3, 4-4}];
\end{document}

出力

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

答え2

境界線のないセル スタイルを定義するという、シンプルですが少し失礼な解決策があります。

\documentclass[border=6pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{matrix}

\begin{document}
    \begin{tikzpicture}
\newcommand\nx{|[draw=none]|}
\matrix (m) [matrix of nodes,
             row sep=-\pgflinewidth,
             column sep=-\pgflinewidth,
             nodes = {draw,
                      minimum size=11mm, anchor=center,
                      inner sep=0pt, outer sep=0pt}
             ] 
{
a & b & c & d & e\\
f & g & \nx
        h & i & j\\
k & \nx l 
      & \nx m
          & n & o\\
p & q & \nx r 
          &  \nx s 
              & t\\
u & v & w & x & y\\
};
    \end{tikzpicture}
\end{document}

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

答え3

以下のコマンド\islandsは 3 つの引数を取ります。最初の引数は行数、2 番目の引数は列数、3 番目の引数はフォーム内のセルのリストです(<row>,<column>)

このコマンドは、水平線と垂直線を描画します。3 番目の引数のリストに上下のセルが含まれている場合、水平線は描画されません。垂直線についても同様です。

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

\documentclass[border=6pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{matrix}
\ExplSyntaxOn
\cs_generate_variant:Nn \str_if_in:nnT { neT }
\bool_new:N \l__islands_bool
\NewDocumentCommand { \islands } { mmm }
% #1 number of rows
% #2 number of columns
% #3 list of cells in the form (<row>,<column>)
  {
    \begin { scope }
      [
        shift = { ( mymatrix-1-1.north~west ) } ,
        x = 11 mm ,
        y = -11 mm
      ]
      \int_step_inline:nnn { 0 } {#1}
        {
          \int_step_inline:nn {#2}
            {
              \bool_set_true:N \l__islands_bool
              \str_if_in:neT {#3} { ( ##1 , ####1 ) }
                {
                  \str_if_in:neT {#3} { ( \int_eval:n { ##1 + 1 } , ####1 ) }
                    {
                      \bool_set_false:N \l__islands_bool
                    }
                }
              \bool_if:NT \l__islands_bool
                { \draw ( { ####1 - 1 } , ##1 ) --++ ( 1 , 0 ) ; }
            }
        }
      \int_step_inline:nnn { 0 } {#2}
        {
          \int_step_inline:nn {#1}
            {
              \bool_set_true:N \l__islands_bool
              \str_if_in:neT {#3} { ( ####1 , ##1 ) }
                {
                  \str_if_in:neT {#3} { ( ####1 , \int_eval:n { ##1 + 1 } ) }
                    {
                      \bool_set_false:N \l__islands_bool
                    }
                }
              \bool_if:NT \l__islands_bool
                { \draw ( ##1 , { ####1 - 1 } ) --++ ( 0 , 1 ) ; }
            }
        }
    \end { scope }
  }
\ExplSyntaxOff
\begin{document}
\begin{tikzpicture}
\matrix (mymatrix) [
  matrix of nodes,
  inner sep=0pt,
  row sep=-\pgflinewidth,
  column sep=-\pgflinewidth,
  nodes={
    rectangle,
    minimum height=11mm,
    minimum width=11mm,
    anchor=center,
    inner sep=0pt,
    outer sep=0pt
  }
]
  {
    a & b & c & d & e\\
    f & g & h & i & j\\
    k & l & m & n & o\\
    p & q & r & s & t\\
    u & v & w & x & y\\
  };
\islands{5}{5}{(2,3),(3,2),(3,3),(4,3),(4,4)}
\end{tikzpicture}
\end{document}

関連情報