包裹 tikz 链,多线框图

包裹 tikz 链,多线框图

我正在尝试自动生成多线框图。到目前为止,在帮助下 (旧帖),我能够使用 TikZ 链生成单个框图序列。它非常适合短流程,但是,我想将其扩展为更长的块序列并使其多行。我解决这个问题的想法是生成一些固定长度(例如 5 个块)的水平链,并具有垂直偏移,然后通过链连接选项连接它们。理想情况下,我还会尝试翻转链的方向,使其像锯齿形(或割草机图案)一样。我试图将我的链分成几行,但在尝试创建用于迭代行的列表时遇到了困难。简而言之,我想问是否有一些选项,或者在 TikZ 中实现框图“换行”的最佳方法是什么。

\documentclass[10pt]{report}

\usepackage{blindtext}
\usepackage[a4paper, margin={1in}]{geometry}

\usepackage{tikz}
\usetikzlibrary{chains, arrows.meta, quotes}

\tikzset{block/.style={draw, minimum width=2cm, minimum height=1cm}}

\ExplSyntaxOn
\newcommand\createlist[1]{
  \int_step_function:nnN{0}{\int_eval:#1 - 1}{\int_eval:n}
}
\ExplSyntaxOff

\newcommand{\process}[1]{
    \newcounter{row_count}
    \foreach \blockstr/\outputstr/\descriptionstr [count=\n] in {#1}{
        \addtocounter{row_count}{1}
    }
    
    % five blocks per page should be ok
    % \{\pgfmathparse{int(ceil(\value{len} / 5))}\pgfmathresult}
    \def\nrows{{\pgfmathparse{int(ceil(\value{row_count} / 5))}\pgfmathresult}} 
    
    % \nrows
    % \def\mylist{{{0,...,\nrows}}}
    % \mylist
    % \def\mylist{\createlist{\nrows}}
    
    % \foreach \row [count=\i] in {0,...,\nrows}
    %     {
    %        \row
    %        }
        
    \begin{tikzpicture}
        \begin{scope}[start chain=diagram_chain going right, node distance=1mm and 1cm, 
                      every join/.style={thick, -Stealth}]
            \foreach \blockstr/\outputstr/\descriptionstr [count=\j] in {#1}{
                \node[on chain=diagram_chain, block, join=by "\outputstr"]{\blockstr};
            }
        \end{scope}
    \end{tikzpicture}
    
    \begin{description}
    \foreach \blockstr/\outputstr/\descriptionstr [count=\k] in {#1}{
        \item [\blockstr] output: \outputstr \ \descriptionstr
    }
    
    \end{description}
}   

\begin{document}

\process{
    n0/$s(0)$/Long description of what n0 does,
    n1/$s(1)$/Long description of what n1 does,
    n2/$s(2)$/Long description of what n2 does,
    n3/$s(3)$/Long description of what n4 does,
    n4/$s(4)$/Long description of what n5 does,
    n5/$s(5)$/Long description of what n6 does,
    n6/$s(6)$/Long description of what n7 does
}



\end{document}

迄今为止的结果: 在此处输入图片描述

目标结构: 在此处输入图片描述

答案1

看起来似乎只能容纳四列,但这在很大程度上取决于特殊连接上的边缘标签。

所有智能的事情都发生在循环evaluate的一部分中\foreach

关键在于我们可以分别为链上的每个节点设置链的方向:因此,对于 n1、n2、n3,我们希望它是going right,对于 n4,我们需要going below,然后 n5、n6 和 n7 是 ,going left并且再次n8going below。 用设置的方向start chain无关紧要(也可以为空)。

join边标签将通过库中的密钥放置chains,但我们会将其延迟到下一次迭代,因为您指定了“输出”标签(即到下一个节点的边),尽管join描述了到上一个节点的边。因此,remember使用密钥。

根据 的值process columns,我们称之为n,并且每个节点我们确定

  • \Direction下一个节点的:

    • 以下如果 mod(n)为零(即第 0 个,n第 2nth,…链上节点),
    • 如果 mod( 则为正确,2n)小于n(即 2+1,2+2,…,2+ 2+ (n−1) 链上的第节点)
    • 否则就离开。
  • 我们是否需要\SpecialJoin(以及什么样的)以及

  • 这样\AutoDirection,沿边缘的标签始终位于顶部或外侧。


我们可以让 TikZ 或 TeX 测量事物并调整列数,至少对于下一次编译运行来说,但我相信这是一个好的开始。

代码

\documentclass[10pt]{report}
\usepackage{blindtext}
\usepackage[a4paper, margin={1in}]{geometry}
\usepackage{tikz}
\usetikzlibrary{arrows.meta, chains, ext.paths.ortho}
\tikzset{
  every process diagram/.style={
    start chain=processes going right,
    every on chain/.append style={process node},
    every join/.append style={-Stealth, thick},
    node distance=3mm and 1cm,
    left join/.style ={to path={r-rl(\tikztotarget)\tikztonodes}},
    right join/.style={to path={r-lr(\tikztotarget)\tikztonodes}},
  },
  process node/.style={draw, minimum width=2cm, minimum height=1cm},
  process columns/.initial=4}
\newcommand*\process[2][]{%
  \begin{center}
  \begin{tikzpicture}[every process diagram]
  \foreach[
    count=\i from 0,
    remember=\Output as \PrevOutput,
    evaluate={
      \NotVerticalLR=mod(\i,   \pgfkeysvalueof{/tikz/process columns} );
      \NotVerticalL =mod(\i,2*(\pgfkeysvalueof{/tikz/process columns}));
      \Direction=ifthenelse(\NotVerticalLR, ifthenelse(\NotVerticalL<
          \pgfkeysvalueof{/tikz/process columns}, "right", "left"), "below");
      \SpecialJoin=ifthenelse(not(\NotVerticalLR),
        ifthenelse(\NotVerticalL, "left join", "right join"), "");
      \AutoDirection=ifthenelse(\NotVerticalL>
        \pgfkeysvalueof{/tikz/process columns}||\NotVerticalL==0,"right","left");
      }] \Text/\Output/\throwaway in {#2}
    \node[on chain=going \Direction,
          join=by {\SpecialJoin, auto=\AutoDirection, edge label=\PrevOutput}]{\Text};
  \end{tikzpicture}
  \end{center}
  \begin{description}
  \foreach\Text/\Output/\Item in{#2}{\item[\Text] output: \Output\par\Item}
  \end{description}}
\begin{document}
\blindtext
\process{
    n0/$s(0)$/Long description of what n0 does,
    n1/$s(1)$/Long description of what n1 does,
    n2/$s(2)$/Long description of what n2 does,
    n3/$s(3)$/Long description of what n3 does,
    n4/$s(4)$/Long description of what n4 does,
    n5/$s(5)$/Long description of what n5 does,
    n6/$s(6)$/Long description of what n6 does,
    n7/$s(7)$/Long description of what n7 does,
    n8/$s(8)$/Long description of what n8 does,
    n9/$s(9)$/Long description of what n9 does,
    n10/$s(10)$/Long description of what n10 does,
    n11/$s(11)$/Long description of what n11 does,
    n12/$s(12)$/Long description of what n12 does
}
\blindtext
\end{document}

输出

在此处输入图片描述

相关内容