같은 줄의 노드를 기반으로 tikz 노드의 너비를 설정하는 방법

같은 줄의 노드를 기반으로 tikz 노드의 너비를 설정하는 방법

다음 tikzpicture를 만들고 싶습니다.

여기에 이미지 설명을 입력하세요

현재 제가 가지고 있는 것은 다음과 같습니다.

\documentclass{article}
\usepackage[showframe]{geometry}
\usepackage{tikz}
\usetikzlibrary{positioning,backgrounds}
\begin{document}
\noindent\begin{tikzpicture}[background rectangle/.style={fill=gray!25}, show background rectangle,every node/.style={inner sep=0pt,outer sep=0pt,draw}]

\begin{scope}[local bounding box=scope1]
\path[use as bounding box] (0,0) rectangle (.5\textwidth,0);
\filldraw (0,0) circle (2pt); 
\node [text width=0.5\textwidth, align=left,anchor=north west](n1) {scope 1, node 1};
\node [below = 0pt of n1.south west,anchor=north west] (n2) {scope 1, node 2};
\node [below left = 0pt and 0pt of n2.north east,anchor=north west,align=left,text width=5.1cm] (n3) {scope 1, node 3 that includes longer text to be broken into lines};
\end{scope}

\begin{scope}[shift={(scope1.north east)},anchor=north west]
\node [text width=0.5\textwidth, align=left](n1) {scope 2, node 1};
\node [below = 0pt of n1.south west,anchor=north west] (n2) {scope 2, node 2};
\node [below left = 0pt and 0pt of n2.north east,anchor=north west,align=left,text width=5.1cm] (n3) {scope 2, node 3 which also includes longer text to be broken into lines};
\end{scope}

\end{tikzpicture}
\end{document}

여기에 이미지 설명을 입력하세요

두 가지 사항에 대한 도움이 필요합니다.

  1. 노드의 너비를 어떻게 정의 n3하여 의 총 너비가 n2( )이 되도록 n3할 수 있습니까 ? 지금은 괜찮아 보이기 때문에 5.1cm로 설정했지만 노드 2의 내용을 변경하면 노드 3의 치수도 변경되어야 합니다. 첫 번째 범위에 대해 생성한 경계 상자를 어떻게 활용할 수 있나요?n1.5\textwidth

  2. 두 범위 사이에 구분 기호를 삽입하려면 어떻게 해야 합니까(예: 첫 번째 그림에서 노란색으로 그려진 것)? 두 범위의 너비가 를 넘어 확장되는 이유는 무엇입니까 textwidth? 왼쪽과 오른쪽에 회색 여백이 있습니다 outer sep=0pt.

답변1

배경 직사각형에는 패딩( 라고 함 )이 있으므로 실제 콘텐츠보다 회색으로 더 많이 표시됩니다. 사용inner frame [xy]septight background이것을 바꾸려면.
또한 선 너비(노드뿐만 아니라 외부 sep에 관계없이 모든 경로)는 그림의 최종 배치를 약간 벗어나는 그림의 최종 경계 상자에 영향을 미치며 과도한 hbox로 이어집니다.
원래 설정에서는 를 사용하여 경계 상자의 수평 측정을 덮어쓸 수 있습니다 trim left=0pt, trim right=\textwidth. 아래 코드에서는 ±.5\textwidth원점을 중심으로 그림을 만들기 때문에 사용하고 있습니다.

다른 노드와 관련된 크기를 가진 노드를 생성하기 위해 fit노드에 실제로 텍스트가 있기를 원하는 경우에는 좋지 않은 텍스트 너비/높이/깊이를 설정하여 작동하는 라이브러리입니다.

ext.positioning-plus라이브러리는 라이브러리를 사용하여 비슷한 작업을 수행 fit하지만 를 사용하여 새 노드의 크기를 제어합니다. 노드에 텍스트를 넣는 데 더 minimum width좋지만 minimum height노드에 맞는 것보다 긴 텍스트에 대해서는 약간의 작업이 필요합니다.

text width between여기서는 다음을 사용하는 매우 기본적인 키를 사용하고 있습니다.calc 라이브러리를 사용하여 두 개의 임의 지점 사이의 거리를 측정하는엑스차원을 사용하여 text width노드의 를 설정합니다. 우리는 빼야 해inner xsep (마지막 노드가 실제로 해당 영역을 포함하도록).~와 함께내부 xsep). 이는 기본적으로고정폭최소 너비 대신. (인수 2는 다른 모양에 따라 다릅니다.)

노드 크기를 동기화하기 위해 다음을 제공할 수 있습니다.ext.node-families도서관나의tikz-ext패키지.

설정된 모든 노드 node family={height=row1}는 동일한 minimum height. 그러면 각 노드의 텍스트가 수직 중앙에 정렬됩니다.

파란색 노드와 노란색 구분선(노드이기도 함)은 모두 동일한 수직 공간에 걸쳐 있습니다.

코드(노드 제품군)

\documentclass{article}
\usepackage[showframe]{geometry}
\usepackage{tikz, amsmath}
\makeatletter % https://tex.stackexchange.com/a/656319/16595
\tikzset{parse let/.code={\def\tikz@cc@stop@let in{}\tikz@let@command et #1in}}
\makeatother
\usetikzlibrary{calc, positioning, backgrounds, ext.node-families}
\tikzset{
  text width between/.style args={#1 and #2}{
    parse let={\p@=($(#2)-(#1)$)},
    text width/.expanded={abs(\x@)-2*(\noexpand\pgfkeysvalueof{/pgf/inner xsep}}}}
\begin{document}
\noindent
\begin{tikzpicture}[
  background rectangle/.style={fill=gray!25},
  show background rectangle, tight background,
  trim left=-.5\textwidth, trim right=.5\textwidth,
  every node/.style={outer sep=+0pt},
  Yellow/.style={fill=yellow, node family={height=row1}},
  Blue/.style  ={fill=blue,   node family={height=row1}, text=white},
  Red/.style   ={fill=red,   align=center},
  Green/.style ={fill=green, align=center},
  node distance=+0pt
]
\node[Yellow] (sep) {};
\node[Blue, left=of sep,  text width between={-.5\textwidth,0 and sep.west}]
  (Blue-left) {scope 1, node 1 $\displaystyle e^x = \cfrac{1}{1 - \cfrac{x}{1 + x -
                               \cfrac{\frac{1}{2}x}{1 + \frac{1}{2}x - \ddots}}}$};
\node[Blue, right=of sep, text width between={ .5\textwidth,0 and sep.east}]
  (Blue-right) {scope 1, node 1};

\node[Red, below right=of Blue-left.south  west] (Red-left)  {scope 1,\\ node 2};
\node[Red, below right=of Blue-right.south west] (Red-right) {scope 1,\\ node 2};

\node[Green, below left=of Blue-left.south east,
     text width between=Red-left.east and Blue-left.east]
  (Red-left) {scope 1, node 3 that includes longer text to be broken into lines};

\node[Green, below left=of Blue-right.south east,
     text width between=Red-right.east and Blue-right.east]
  (Red-left) {scope 2, node 3 which also includes longer text to be broken into lines
    \dots\ and here's an extra linre};
\end{tikzpicture}
\end{document}

코드(노드 제품군 제외)

\documentclass{article}
\usepackage[showframe]{geometry}
\usepackage{tikz, amsmath}
\makeatletter % https://tex.stackexchange.com/a/656319/16595
\tikzset{parse let/.code={\def\tikz@cc@stop@let in{}\tikz@let@command et #1in}}
\makeatother
\usetikzlibrary{calc, positioning, backgrounds}
\tikzset{
  text width between/.style args={#1 and #2}{
    parse let={\p@=($(#2)-(#1)$)},
    text width/.expanded={abs(\x@)-2*(\noexpand\pgfkeysvalueof{/pgf/inner xsep}}},
  minimum height of three nodes/.style n args={3}{
    parse let={\p1=($(#1.north)-(#1.south)$),
               \p2=($(#2.north)-(#2.south)$),
               \p3=($(#3.north)-(#3.south)$),
               \n@={max(\y1,\y2,\y3)}},
    minimum height/.expanded={\n@}}}
\DeclareDocumentCommand{\tikzthreenodessameheight}{O{} m O{} m O{} m}{
  \node[#1,alias=@1,overlay,path only,outer ysep=+0pt]{\phantom{#2}};
  \node[#3,alias=@2,overlay,path only,outer ysep=+0pt]{\phantom{#4}};
  \node[#5,alias=@3,overlay,path only,outer ysep=+0pt]{\phantom{#6}};
  \node[#1,minimum height of three nodes={@1}{@2}{@3}] {#2};
  \node[#3,minimum height of three nodes={@1}{@2}{@3}] {#4};
  \node[#5,minimum height of three nodes={@1}{@2}{@3}] {#6};}
\begin{document}
\noindent
\begin{tikzpicture}[
  background rectangle/.style={fill=gray!25},
  show background rectangle, tight background,
  trim left=-.5\textwidth, trim right=.5\textwidth,
  every node/.style={outer sep=+0pt},
  Yellow/.style={fill=yellow},
  Blue/.style  ={fill=blue,   text=white},
  Red/.style   ={fill=red,   align=center},
  Green/.style ={fill=green, align=center},
  node distance=+0pt
]
\tikzthreenodessameheight
  [Yellow, name=sep]{}
  [Blue, left=of sep, name=Blue-left,
   text width between={-.5\textwidth,0 and sep.west}]
  {scope 1, node 1 $\displaystyle e^x = \cfrac{1}{1 - \cfrac{x}{1 + x -
                          \cfrac{\frac{1}{2}x}{1 + \frac{1}{2}x - \ddots}}}$}
  [Blue, right=of sep, text width between={ .5\textwidth,0 and sep.east}, name=Blue-right]
  {scope 1, node 1};

\node[Red, below right=of Blue-left.south  west] (Red-left)  {scope 1,\\ node 2};
\node[Red, below right=of Blue-right.south west] (Red-right) {scope 1,\\ node 2};

\node[Green, below left=of Blue-left.south east,
     text width between=Red-left.east and Blue-left.east]
  (Red-left) {scope 1, node 3 that includes longer text to be broken into lines};

\node[Green, below left=of Blue-right.south east,
     text width between=Red-right.east and Blue-right.east]
  (Red-left) {scope 2, node 3 which also includes longer text to be broken into lines
    \dots\ and here's an extra linre};
\end{tikzpicture}
\end{document}

산출

여기에 이미지 설명을 입력하세요

답변2

tcbraster(또는 기본적으로 tcbitemize) fromtcolorbox , we can leave the package to do all the work for us. The래스터 \texwidth`를 사용하면 use모든 래스터 열의 너비가 동일하지만 수동으로 조정할 수도 있습니다.

\documentclass{article}
\usepackage[showframe]{geometry}
\usepackage[most]{tcolorbox}

\begin{document}

\begin{tcbitemize}[raster every box/.style={sharp corners,  
    fontupper=\sffamily, colupper=white, boxrule=0pt, halign=center},
    raster left skip=0pt, raster right skip=0pt, 
    raster before skip=0pt, raster row skip=0pt, 
    raster after skip=0pt, raster valign=top]
    \tcbitem[colback=blue!90!black] scope 1, node 1
    \tcbitem[colback=blue!90!black] scope 2, node 1
    \tcbitem[blankest, raster column skip=0pt]
        \begin{tcbitemize}[raster force size=false]
            \tcbitem[colback=red!90!black, width=.4\linewidth] scope 1, node 2
            \tcbitem[colback=green!90!black, width=.6\linewidth] scope 1, node 3 that includes longer text to be broken into lines
        \end{tcbitemize}
    \tcbitem[blankest, raster column skip=0pt]
        \begin{tcbitemize}[raster force size=false]
            \tcbitem[colback=red!90!black, width=.4\linewidth] scope 2, node 2
            \tcbitem[colback=green!90!black, width=.6\linewidth] scope 2, node 3 which also includes longer text to be broken into lines
        \end{tcbitemize}
\end{tcbitemize}
\end{document}

여기에 이미지 설명을 입력하세요

답변3

여기에 이미지 설명을 입력하세요

나는 귀하의 초기 코드에 가깝게 유지하려고 노력했습니다. 하지만 고려되지 않은 한 가지 문제가 있습니다. 오른쪽 상단 노드의 높이가 왼쪽 상단 노드의 높이보다 크면 어떻게 될까요? 해결 방법은 구성을 반대로 하고 오른쪽 상단 노드를 참조로 삼는 것입니다.

코드

\documentclass{article}
\usepackage[showframe]{geometry}
\usepackage{lipsum}
\usepackage{tikz}
\usetikzlibrary{calc, positioning}

\begin{document}

\lipsum[1]
\bigskip

\tikzset{%
  T/.style={blue!50!black, fill=blue!50!black, text=white,
    minimum width=0.48\textwidth, text width=0.48\textwidth-1ex
  },
  BW/.style={green!50!black, fill=green!70!black, text=black,
    minimum width=0.17\textwidth, text width=0.17\textwidth-1ex
  },
  BE/.style={red!75!black, fill=red!95!black, text=black,
    minimum width=0.30\textwidth, text width=0.30\textwidth-1ex,
  }
}
\noindent\begin{tikzpicture}[%
  every node/.style={draw, inner sep=1ex, outer sep=0pt, align=center,
  minimum height=7ex}
  ]
  \node[T, anchor=north west] at (0, 0)
  (nTW) {\bfseries \lipsum[2]};
  \node[BW, below=0pt of nTW.south west, anchor=north west]
  (n2) {scope 1, node 2};
  \node[BE, below left=0pt and 0pt of n2.north east, anchor=north west]
  (n3) {scope 1, node 3 that includes longer text to be broken into lines};

  \path ($(nTW.south) -(nTW.north)$);
  \pgfgetlastxy{\newW}{\newH}

  \node[T, right=.02\textwidth of nTW.north east,
  anchor=north west, minimum height={-\newH}]
  (nTE) {\bfseries scope 2, node 1};
  \node[BW, below=0pt of nTE.south west, anchor=north west]
  (n2E) {scope 2, node 2};
  \node[BE, below left=0pt and 0pt of n2E.north east, anchor=north west]
  (n3E) {scope 2, node 3 that includes longer text to be broken
    into lines; can be longer than the West corresponding node};

  \fill[yellow!90!red] (nTW.north east) rectangle (nTE.south west);
\end{tikzpicture}
\end{document}

답변4

대체 제안. 내 코드는 덜 기술적입니다(하지만 덜 우아하기도 할까요?).

노란색 구분 기호의 너비( \yellowGap내 코드)와 노드 1의 너비 비율( percentAmount0에서 100 사이의 정수)을 조정할 수 있지만, 매우 피하기 위해 0이나 100에 너무 가까운 값을 선택하지 않는 것이 좋습니다. 좁은 열), 노드 2의 너비를 얻습니다.

마지막으로 노드의 내부 격막 길이를 조정할 수 있습니다 \innerXSep.

\documentclass[a4paper,10pt]{article}
\usepackage[showframe]{geometry}
\usepackage[x11names]{xcolor}
\usepackage{tikz}
\usetikzlibrary{calc}
\usepackage{calc}

\newlength{\yellowGap}
\setlength{\yellowGap}{3mm}
\newcounter{percentAmount}
\setcounter{percentAmount}{40}% =40% of the width of the first node. Value needs to be integer
\newlength{\innerXSep}
\setlength{\innerXSep}{.3333em}% default value

\newlength{\mainNodeWidth}
\setlength{\mainNodeWidth}{(\textwidth-\yellowGap)/2}
\newlength{\secondNodeWidth}
\setlength{\secondNodeWidth}{\mainNodeWidth*\value{percentAmount}/100}
\newlength{\thirdNodeWidth}
\setlength{\thirdNodeWidth}{\mainNodeWidth-\secondNodeWidth}

\begin{document}

\noindent\begin{tikzpicture}[outer sep=0pt,inner xsep=\innerXSep,text=white]
    \node[text width=\mainNodeWidth-2\innerXSep,fill=DodgerBlue3,align=center]  (mainLeft) {Scope 1, Node 1};
    \node[text width=\secondNodeWidth-2\innerXSep,fill=Firebrick2,align=center,anchor=north west] (secondLeft) at (mainLeft.south west) {Scope 1,\\Node 2};
    \node[text width=\thirdNodeWidth-2\innerXSep,fill=Green3,align=center,anchor=north west] (thirdLeft) at (secondLeft.north east) {Scope 1, Node 3\\ that includes longer text to be broken into lines};
    \fill[DarkGoldenrod1] (mainLeft.north east) rectangle ($(mainLeft.south east)+(\yellowGap,0)$);
    \node[text width=\mainNodeWidth-2\innerXSep,fill=DodgerBlue3,align=center,anchor=north west]    (mainRight) at ($(mainLeft.north east)+(\yellowGap,0)$) {Scope 2, Node 1};
    \node[text width=\secondNodeWidth-2\innerXSep,fill=Firebrick2,align=center,anchor=north west] (secondRight) at (mainRight.south west) {Scope 2,\\Node 2};
    \node[text width=\thirdNodeWidth-2\innerXSep,fill=Green3,align=center,anchor=north west] at (secondRight.north east) {Scope 2, Node 3\\ which also includes longer text to be broken into lines};
\end{tikzpicture}
\end{document}

여기에 이미지 설명을 입력하세요

관련 정보