
다음 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}
두 가지 사항에 대한 도움이 필요합니다.
노드의 너비를 어떻게 정의
n3
하여 의 총 너비가n2
( )이 되도록n3
할 수 있습니까 ? 지금은 괜찮아 보이기 때문에 5.1cm로 설정했지만 노드 2의 내용을 변경하면 노드 3의 치수도 변경되어야 합니다. 첫 번째 범위에 대해 생성한 경계 상자를 어떻게 활용할 수 있나요?n1
.5\textwidth
두 범위 사이에 구분 기호를 삽입하려면 어떻게 해야 합니까(예: 첫 번째 그림에서 노란색으로 그려진 것)? 두 범위의 너비가 를 넘어 확장되는 이유는 무엇입니까
textwidth
? 왼쪽과 오른쪽에 회색 여백이 있습니다outer sep=0pt
.
답변1
배경 직사각형에는 패딩( 라고 함 )이 있으므로 실제 콘텐츠보다 회색으로 더 많이 표시됩니다. 사용inner frame [xy]sep
tight 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) from
tcolorbox , 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의 너비 비율( percentAmount
0에서 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}