如何使用 TikZ 创建一个节点,该节点具有为其他目的保留的部分,并且文本围绕它流动?
我认为我已经找到了一个答案,但是它不能让我满意。
在下面的 MWE 中,
- 第一个“测试标题”显示了我的起点:一个包含标题的节点和一个级别标记(即,您可以达到标题所标识的事物的级别)。这占用了比我喜欢的更多的空间,所以我寻找了另一种方法。
- 第二个“另一个标题”显示最近的发展,翻转标题框内的级别标记。看起来好多了,但是……
- 第三个“另一个标题...”显示了当文本足够长而无法容纳在级别标记的左侧时发生的情况。
- 第四个“另一个带有...的标题”显示如果我创建一个比名义上包含它的标题节点更高的标记节点会发生什么。
我希望 TikZ 节点内的文本尊重级别标记节点并环绕它。在这种情况下,它看起来会像这样
|Another Header With Lots [ 4 ]|
|of Text |
到目前为止,我能够通过设置标题节点的属性(根据需要创建标记节点)来完成这一切。标记和标题文本几乎总是兼容的,我可以解决其余的问题。
我认为我需要做的是创建一个类似于迷你页面或其他框的东西,其中wrapfig
包含一个或类似的标记,然后将其放在标题节点内。也就是说,构建我想要的完整图片,然后将其与包含节点对齐。
我说得对吗?或者有更简单的方法吗?
如果我是正确的,我该怎么做呢?我怀疑会是这样的:
- 创建与节点宽度相同的小页面,并带有边距/填充;
- 用来
wrapfig
为标记腾出空间; - 创建足够高和足够宽的节点以精确适合小页面,包括标记框。
我希望我不需要这样做,我可以接受两个答案,因为我实际上有两个用例。第一个是正文中的对象标题(textwidth
可以包含更大标记的框),第二个是显示项目如何连接的图表,并且在一个角落只有一个标记。
\documentclass{article}
\usepackage{lipsum}
\usepackage[most]{tcolorbox}
\usepackage{tikz}
\usetikzlibrary{intersections,positioning,shapes.misc}
\tikzstyle{test} = [rectangle,draw,thick,fill=brown!30,text width=50mm,inner sep=1mm,font=\sffamily]
\tikzstyle{level} = [test,thin,fill=white,text width=8mm,inner sep=1mm,anchor=south east,font=\footnotesize\sffamily,align=center,yshift=-1\pgflinewidth,]
\tikzstyle{newlevel} = [level,anchor=north east,xshift=-1\pgflinewidth,]
\tikzstyle{gear} = [newlevel,text width=]
\title{TikZ MWE}
\author{Keith Davies}
\begin{document}
\maketitle
\noindent\lipsum[1]
\noindent\begin{tikzpicture}[-,node distance=30mm,auto]
\node[test] (header) {Test Header};
\node[level] at (header.north east) {4};
\end{tikzpicture}
\bigskip
\noindent\begin{tikzpicture}[-,node distance=30mm,thick]
\node[test] (short) {Another Header};
\node[newlevel] at (short.north east) {4};
\end{tikzpicture}
\bigskip
\noindent\begin{tikzpicture}[-,node distance=30mm,thick]
\node[test] (wide) {Another Header With Lots of Text};
\node[newlevel] at (wide.north east) {4};
\end{tikzpicture}
\bigskip
\noindent\begin{tikzpicture}[-,node distance=30mm,thick]
\node[test] (double) {Another Header With two rows in inset};
\node[gear] at (double.north east) {
\begin{tabular}{@{}lr@{}}
\bfseries{Cost} & 5 gp \\
\bfseries{Market} & 15 gp \\
\bfseries{Weight} & 4 lbs \\
\end{tabular}};
\end{tikzpicture}
\noindent\lipsum[2-3]
\end{document}
通常只需要一个换行符,我并不需要裹标记。解决方案TikZ:如何在一侧(例如在矩形的右侧)定义具有自定义内部分离的节点?实际上可能非常接近我需要的。如果可以的话,我想看看是否可以将其放入单个对象(或者更确切地说,对象加标记)。
答案1
使用 的部分解决方案wrapfig
。添加wrapfig
包,更改节点的定义gear
,并使用带有空的 minipage wrapfigure
:
\documentclass{article}
\usepackage{lipsum}
\usepackage[most]{tcolorbox}
\usepackage{tikz}
\usepackage{printlen}
\usetikzlibrary{intersections,positioning,shapes.misc}
\usepackage{wrapfig}
\tikzstyle{header} = [rectangle,draw,text width=40mm,inner sep=1mm,font=\sffamily,anchor=north west]
\tikzstyle{test} = [rectangle,draw,thick,fill=brown!30,text width=50mm,inner sep=1mm,font=\sffamily]
\tikzstyle{level} = [test,thin,fill=white,text width=8mm,inner sep=1mm,anchor=south east,font=\footnotesize\sffamily,align=center,yshift=-1\pgflinewidth,]
\tikzstyle{newlevel} = [level,anchor=north east,xshift=-1\pgflinewidth,]
\tikzstyle{gear} = [newlevel,text width=,minimum height=3\baselineskip]
\title{TikZ MWE}
\author{Keith Davies}
\setlength{\columnsep}{1mm}
\begin{document}
\maketitle
\noindent\lipsum[1]
\noindent
\begin{tikzpicture}[-,node distance=30mm,thick]
\node[test] (wide) {
\begin{minipage}{\textwidth}
\begin{wrapfigure}[1]{r}{0.9cm} \end{wrapfigure}
Another Header With Lots of Text... and even more than that to force multiple line wraps.
\end{minipage}
};
\node[newlevel] at (wide.north east) {4};
\end{tikzpicture}
\bigskip
\noindent
\begin{tikzpicture}[-,node distance=30mm,thick]
\node[test,minimum height=3\baselineskip] (double) {
\begin{minipage}{\textwidth}
\begin{wrapfigure}[3]{r}{2cm} \end{wrapfigure}
Another Header
\end{minipage}
};
\node[gear] at (double.north east) {
\begin{tabular}{@{}lr@{}}
\bfseries{Cost} & 5 gp \\
\bfseries{Market} & 15 gp \\
\bfseries{Weight} & 4 lbs \\
\end{tabular}};
\end{tikzpicture}
\noindent\lipsum[2-3]
\end{document}
也就是说,每个标题节点包含一个小页面,小页面有一个空图形,为标记留出空间。这似乎满足了我大部分的需求。我还没有找到一种令人满意的方法让第二张图片中的文本与节点顶部垂直对齐。设置使minimum height
小页面居中,设置text depth
要求我知道我还需要多少行。\vfill\mbox{}
,无论是否在小页面内,都会让我多一行。我可以将小页面高度设置为2.5\baselineskip
(这对我而言实际上可能是安全的,我并不指望这里有三行文本)但我更喜欢一个通用的解决方案......最终我会遇到需要两行以上的情况,这会让我发疯因为我不记得这样做过。