TikZ 嵌套相同大小的节点

TikZ 嵌套相同大小的节点

我想在一个 Ti 中发送 2 条短信Z 节点,其中上部文本有绘制边框,而下部文本没有,并且两个文本都应以一定长度换行。此外,上部文本的边框应始终与周围节点一样宽。如果不获取下部文本的宽度并将其设置为上部文本的最小宽度,我无法完成最后一部分。有没有更好的方法来做到这一点?

例子

\documentclass{minimal}

\usepackage{tikz}
\usepackage{varwidth}
\usetikzlibrary{positioning,fit,matrix}
\usepackage{calc}

\begin{document}
\newlength{\somelength}
\settowidth{\somelength}{Technically this works.}

\begin{tikzpicture}[mymatrix/.style = {matrix of nodes, nodes=mynode},
    mynode/.style = {rectangle,draw, rounded corners=1pt,anchor=west},
    title/.style = {draw=none, anchor=west}]
  \matrix[mymatrix] (mx1) {
    Hello there, this is fine. \\
    |[title]| Hello\\
  };

  \node[mynode, fit=(mx1)]{};

  \matrix[mymatrix,,below=of mx1.south west,anchor=north west] (mx2) {
    Hello there. \\
    |[title]| This is not how it is supposed to be.\\
  };

  \node[mynode, fit=(mx2)]{};

  \matrix[mymatrix,below=of mx2.south west,anchor=north west] (mx3) {
    \begin{varwidth}{195pt}
     Hello there. This is a longer text and this is also fine.
    \end{varwidth}\\
    |[title]| \begin{varwidth}{200pt} Hello, this works also exactly how it should work.\end{varwidth}\\
  };

  \node[mynode, fit=(mx3)]{};

  \matrix[mymatrix,below=of mx3.south west,anchor=north west] (mx4) {
    |[mynode,minimum width=\the\somelength]| \begin{varwidth}{195pt}
     Hello there.
     \end{varwidth}\\
    |[title]| \begin{varwidth}{200pt}  Technically this works.
     \end{varwidth}\\
  };

  \node[mynode, fit=(mx4)]{};
\end{tikzpicture}
\end{document}

答案1

像这样吗?

\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{calc,fit,positioning}
\begin{document}
\begin{tikzpicture}
\node (lower) {Some text here};
\path let \p1=(lower.west),\p2=(lower.east) in 
node[draw,minimum width=\x2-\x1,above=1mm of lower] (more) {more text};
\node[fit=(lower) (more),draw]{}; 
\end{tikzpicture}
\end{document}

在此处输入图片描述

当然可以将其设为处理大多数情况的宏(但我承认不是全部)。

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc,fit,positioning}
\newcommand{\DrawNestedNodes}[2]{%
\node[align=left] (lower) {#2};
\path let \p1=($(lower.east)-(lower.west)$) in
\pgfextra{\pgfmathsetmacro{\mywidth}{width("#1")-\x1}} 
\ifdim\mywidth pt<0pt  
node[draw,text width=\x1-8pt,above=1mm of lower.north west,anchor=south
west,align=left] (more) {#1}
\else
node[draw,minimum width=\x1-8pt,above=1mm of lower.north west,anchor=south
west,align=left] (more) {#1}
\fi;
\node[fit=(lower) (more),draw]{}; 
}
\tikzset{every node/.append style={align=left}}
\begin{document}
\section*{Case 1: one--liners}
\subsection*{Case 1a: lower text wider than upper}
\begin{tikzpicture}
\DrawNestedNodes{some text}{more text here}
\end{tikzpicture}
\subsection*{Case 1b: upper text wider than lower}
\begin{tikzpicture}
\DrawNestedNodes{some long text here}{more text}
\end{tikzpicture}
\section*{Case 2: multi--liners}
\subsection*{Case 2a: lower text wider than upper}
\begin{tikzpicture}
\DrawNestedNodes{some text}{more text here running\\ over two lines}
\end{tikzpicture}
\subsection*{Case 2b: upper text wider than lower}
\begin{tikzpicture}
\DrawNestedNodes{some long text}{more text\\ running over\\ three lines}
\end{tikzpicture}
\end{document}

在此处输入图片描述

编辑:添加了屏幕截图。

答案2

另一种基于原始matrix代码的解决方案。外部边界是matrix不使用任何fit节点的边界。节点长度通过操作计算width。为了避免第一行重复写入,矩阵样式使用两个参数(顶部和底部行)定义,这两个参数添加到node contents参数中。使用node contents强制matrix名称必须放在矩阵选项之前。

\documentclass[tikz, border=2mm]{standalone}

\usepackage{tikz}
%\usepackage{varwidth}
\usetikzlibrary{positioning,matrix,calc}
%\usepackage{calc}

\begin{document}

\begin{tikzpicture}[%
    mymatrix/.style 2 args = {%
        matrix of nodes, 
        rounded corners=1pt,
        draw, 
        inner sep=3mm,
        nodes={
            inner sep=.333em,
            align=left,
            text width = {width("#1")},
        },
        row 1/.style={nodes={draw}},
        node contents={#1\\#2\\}
    },
    ]

    \matrix (mx1) [mymatrix={Hello there, this is fine.}{Hello}] ;

    \matrix (mx2) [mymatrix={Hello there}{This is not how it is supposed to be}, below right = 5mm and 0pt of mx1.south west] ;

    \matrix (mx3) [mymatrix={Hello there. This is a longer text and this is also fine.}{Hello, this works also exactly how it should work.}, below right = 5mm and 0pt of mx2.south west] ;

\matrix (mx4) [mymatrix={Hello there.}{Technically this works.}, below right = 5mm and 0pt of mx3.south west] ;
\end{tikzpicture}
\end{document}

在此处输入图片描述

答案3

我理解你的问题不同土拨鼠

在此处输入图片描述

这就是你要找的吗?

\documentclass[tikz,varwidth, margin=3mm]{standalone}
\usetikzlibrary{fit, positioning}

\begin{document}
\begin{tikzpicture}[
node distance = 6mm,
   box/.style = {draw, text width=77mm, align=left},
   tit/.style = {text width=77mm, align=left},
     F/.style = {draw, inner sep= 3mm, node contents={}}
                        ]
\node (n1a) [box]                   {Hello there, this is fine};
\node (n1b) [tit, below=0pt of n1a] {Hello};
\node (n1)  [F, fit=(n1a) (n1b)];
%
\node (n2a) [box, below=of n1]  {Hello there.};
\node (n2b) [tit, below=0pt of n2a]     {This is not how it is supposed to be.};
\node (n2)  [F, fit=(n2a) (n2b)];
%
\node (n3a) [box, below=of n2]  {Hello there. This is a longer text and this is also fine.};
\node (n3b) [tit, below=0pt of n3a]     {Hello, this works also exactly how it should work.};
\node (n3)  [F, fit=(n3a) (n3b)];
%
\node (n4a) [box, below=of n3]  {Hello there.};
\node (n4b) [tit, below=0pt of n4a]     {Technically this works.};
\node (n3)  [F, fit=(n4a) (n4b)];
   \end{tikzpicture}
\end{document}

相关内容