(请随意提供更好、更精确的主题标题。)
我有两个chains
垂直不同计数其中的节点。但我想可视化右侧的一些节点属于左侧的一个节点。它们需要出现在同一行/线上。在下面的示例代码中,您可以看到,Y
两个节点应该出现在它的右侧。
这里的问题是我无法处理右链(比如它有 4 个节点)并将它们连接起来。使用\matrix
使其无法使用chain
。
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{matrix,positioning,chains,scopes}
\begin{document}
\begin{tikzpicture}
[
myright/.style={
draw},
myleft/.style={
myright,
on chain,
fill=cyan!30}
]
% LEFT
{[start chain=L going below,
every node/.append style=myleft]
\node {X};
\node {Y};
\node {Z};
}
% RIGHT
{[start chain=R going below]
\node [myright,right=of L-1] {belong to X};
\matrix [right=of L-2]
{
\node [myright] {belong to Y};\\
\node [myright] {also belong to Y};\\
};
\node [myright,right=of L-3] {belong to Z};
}
\end{tikzpicture}
\end{document}
顺便说一句:这个问题与这是关于绘制 PRISMA 流程图的。
答案1
据我理解,您绘制的图正确地放置了节点,但无法像链接节点那样轻松地将它们连接起来,因为右列节点没有链接。此外,也许您希望 Y 的两个节点之间有一些分离,但我不确定。
请注意,做这种事情的最佳方式在很大程度上取决于细节所讨论图表的性质、您对 TikZ 不同方面和不同库的熟悉程度,以及该图表是一次性的还是一系列类似图表中的一个。这里需要在图表编码的效率/优雅性(可能需要付出大量努力才能设置)和设置的简易性(如果有的话)之间取得平衡。
仅给出当前的例子,如果我正确理解了这个问题,我会尝试这样的事情。
创建左侧节点链,包括来自 的分支
X
going right
。将最右边的节点放在 的分支上
X
。将矩阵放置在 的右侧
Y
,与右上方节点对齐。将右下角节点放置在 的右侧
Z
,与右上角节点对齐。创建第二条右侧链,将右侧的节点添加到链中,并在添加时将它们连接起来。
这在命名和方法混合方面有点混乱,但最终会得到两个节点链,可以轻松连接和引用。请注意,一个节点位于多个链或矩阵和链中都没有问题……
如果不想将属于的节点分开Y
,请删除row sep
。如果不想将它们连接起来,请删除相关的[join]
。
\documentclass[tikz,border=10pt]{standalone}
\usetikzlibrary{matrix,positioning,chains,scopes}
\begin{document}
\begin{tikzpicture}
[
myleft/.style={
draw,
fill=cyan!30}
]
% LEFT
{[start chain=L going below,
every on chain/.append style={myleft},
every node/.append style={on chain},
]
\node {X};
{[start branch=X going right,
every on chain/.append style={fill=none}
]
\node {belong to X};
}
\node {Y};
\node {Z};
}
\matrix (m) [row sep=2.5pt, matrix of nodes, every node/.append style={draw}] at (L-2 -| L/X-2)
{
belong to Y\\
also belong to Y\\
};
\node (z2) [draw] at (L-3 -| L/X-2) {belong to Z};
% RIGHT
{[start chain=R going below]
\chainin (L/X-2);
\chainin (m-1-1) [join];
\chainin (m-2-1) [join];
\chainin (z2) [join];
}
\end{tikzpicture}
\end{document}
答案2
现在您的示例就简单多了,就像给定链接上的图片一样。主要区别在于,右分支只有垂直间隔的节点。考虑到这可能是on grid
您要寻找的选项:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc,positioning,chains,scopes}
\begin{document}
\begin{tikzpicture}[
node distance = 10mm and 30mm,
on grid,
start chain = A going below,
start chain = B going below,
myright/.style = {draw, minimum height=4ex, minimum width=33mm,
on chain=A},
myleft/.style = {draw, fill=cyan!30, minimum height=4ex,
on chain=B}
]
% LEFT
\begin{scope}[every node/.style={myleft}]
\node {X}; % name=B-1
\node {Y};
\node {Z};
\end{scope}
% RIGHT
\begin{scope}[every node/.style={myright}]
\node [right=of B-1] {belong to X}; % name=A-1
\node {belong to Y};
\node {also belong to /};
\node {belong to no one};
\end{scope}
\end{tikzpicture}
\end{document}
在上面的 MWE 中,网格的距离由 决定node distance
。节点以网格中心为中心锚定在网格上。这意味着,如果它们的宽度不相同,它们将不会有对齐的左(或右)边框。
选择两条链进行最简单的节点命名(左边是 B-1、B-2、B-3,右边是 A-1、A-2、A-3 和 A-4)。
对于这两个分支,很容易在右侧添加一个分支(如图所示),但如果右侧分支有两个节点,则需要付出更多努力......
附录(1): 部分考虑的问题图片流程图-tikz,上述 MWE 的升级为:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{arrows.meta,chains,positioning,scopes}
\usepackage[active,tightpage]{preview}
\PreviewEnvironment{tikzpicture}
\setlength\PreviewBorder{3mm}
\makeatletter
%---------------------------------------------------------------%
\tikzset{
suspend join/.code={\def\tikz@after@path{}},
node distance = 13mm and 44mm,
on grid = true,
start chain = A going below,
start chain = B going below,
MR/.style = {% My Right
draw, minimum height=4ex, text width=31mm,
inner sep=1mm, align=center, % left?
on chain=A},
ML/.style = {% My Left
draw=cyan!60!black, rounded corners, fill=cyan!30,
minimum width=4ex, inner sep=1mm,
node contents={\rotatebox{90}{#1}},
on chain=B},
arrow/.style = {thick,-{Triangle[]}},
}
%---------------------------------------------------------------%
\makeatother
\begin{document}
%---------------------------------------------------------------%
\begin{tikzpicture}
% LEFT BRANCH
\node [ML=X]; % name=B-1
\node [ML=Y];
\node [ML=Z];
\node [ML=WWW];
\node [ML=QQ];
% RIGHT BRANCH
\begin{scope}[every node/.style={MR,join=by arrow}]
\node [draw=none,
right=of B-1] {}; % name=A-1, auxiliary node which serves
% as placeholder for real left and right node
% (A-L) and (A-R) defined latter in
% the TOP part of this code
\node [suspend join] {belong to Y};
\node {belong to Z};
\node {belong to WWW, however text in this node has three lines};
\node {belong to QQ};
\end{scope}
% TOP ROW LEAVES (horizontally are not on grid)
\begin{scope}[node distance=2mm,
every node/.style={MR}]
\node (A-L) [ left = of A-1.center] {left top leave};
\node (A-R) [right = of A-1.center] {right top leave};
\end{scope}
% RIGHT LEAVES
\node (C-1) [MR, right = of A-3] {upper right leave};
\node (C-2) [MR, right = of A-4] {lower right leave};
% ARROWS NOT DETERMINED BY "JOIN" MACRO
\path[arrow] (A-L) edge (A-2) (A-R) edge (A-2)
(A-3) edge (C-1) (A-4)edge (C-2);
\end{tikzpicture}
%---------------------------------------------------------------%
\end{document}
这使:
包含(我希望如此)足够的注释,因此其结构清晰。我编写代码的主要目标是简洁明了。与第一个 MEW 相比,它具有新颖性暂停加入,从而简化了join
流程图右侧分支中宏的使用。
附录(2): 您的问题就像*可变结构系统,它似乎不能满足菲利波夫的标准(因此不会滑向某个平衡点……)。
假设:
- 右分支中的第二和第三个节点(从上往下)在左分支中有一个共同的蓝色节点
- 右分支中这些节点的高度不固定
- 蓝色节点(在左侧分支中)跨越从上部节点顶部到下部节点底部的距离(在右侧分支中,它属于该分支)
可以通过以下方式实现:
- 测量距离,哪个蓝色节点应该跨越并单独设计这个节点
- 引入假节点来维护网格上的左分支
为此,我添加了两个库:calc
和fit
,定义假节点和真实左节点。代码有足够的注释(我希望如此),很容易理解它在做什么。
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{arrows.meta,calc,chains,fit,positioning,scopes}
\usepackage[active,tightpage]{preview}
\PreviewEnvironment{tikzpicture}
\setlength\PreviewBorder{3mm}
\makeatletter
%---------------------------------------------------------------%
\tikzset{
suspend join/.code={\def\tikz@after@path{}},
node distance = 13mm and 44mm,
on grid = true,
start chain = A going below,
start chain = B going below,
MR/.style = {% My Right node
draw, minimum height=4ex, text width=31mm,
inner sep=1mm, align=center, % left?
on chain=A},
ML/.style = {% My Left node
draw=cyan!60!black, rounded corners, fill=cyan!30,
minimum width=4ex, inner sep=1mm,
node contents={\rotatebox{90}{#1}},
on chain=B},
FL/.style = {%Fake Left node
node contents={\rotatebox{90}{\phantom{X}}},
on chain=B},
RL/.style = {%Fake Left node
draw=cyan!60!black, rounded corners, fill=cyan!30,
minimum width=4ex, inner xsep=0pt,
label=center:\rotatebox{90}{#1},
node contents={}},
arrow/.style = {thick,-{Triangle[]}},
}
%---------------------------------------------------------------%
\makeatother
\begin{document}
%---------------------------------------------------------------%
\begin{tikzpicture}
% LEFT BRANCH
\node [ML=X]; % name=B-1
\node [FL]; % auxiliary node which maintain branch on grid
% real nodes will take a place latter
\node [FL];
\node [ML=WWWW];
\node [ML=QQ];
% RIGHT BRANCH
\begin{scope}[every node/.style={MR,join=by arrow}]
\node [suspend join,
right=of B-1] {belong to X}; % name=A-1,
\node {belong to Y};
\node {also belong to Y};
\node {belong to WWWW, however text in this node has three lines};
\node {belong to QQ};
\end{scope}
% REAL BLUE NODE, instead of FL
\path let \p1 = (B-2 |- A-2.north),
\p2 = (B-2 |- A-3.south),
\n1 = {veclen(\y2-\y1,\x2-\x1)} in
node[RL=Y,
minimum height=\n1,
fit=(B-2) (B-3)];
% RIGHT LEAVES
\node (C-1) [MR, right = of A-3] {upper right leave};
\node (C-2) [MR, right = of A-4] {lower right leave};
% ARROWS NOT DETERMINED BY "JOIN" MACRO
\path[arrow] (A-3) edge (C-1) (A-4)edge (C-2);
\end{tikzpicture}