带有 tikz 的 CRISP-DM 图

带有 tikz 的 CRISP-DM 图

我正在尝试制作流行的 CRISP-DM 模型的图表。我的代码如下。

\documentclass[tikz,border=20pt]{standalone}

\usepackage{graphicx}
\usepackage{amsmath}
\usepackage{amsthm}
\usepackage{tikz}
\usetikzlibrary{chains, shapes.multipart}
\usetikzlibrary{shapes, calc, decorations.markings}
\usetikzlibrary{automata, positioning, fit, shapes.geometric}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% https://tex.stackexchange.com/a/442994/233668
\makeatletter
\tikzset{
    database/.style={
        path picture={
            \draw (0, 1.5*\database@segmentheight) circle [x radius=\database@radius,y radius=\database@aspectratio*\database@radius];
            \draw (-\database@radius, 0.5*\database@segmentheight) arc [start angle=180,end angle=360,x radius=\database@radius, y radius=\database@aspectratio*\database@radius];
            \draw (-\database@radius,-0.5*\database@segmentheight) arc [start angle=180,end angle=360,x radius=\database@radius, y radius=\database@aspectratio*\database@radius];
            \draw (-\database@radius,1.5*\database@segmentheight) -- ++(0,-3*\database@segmentheight) arc [start angle=180,end angle=360,x radius=\database@radius, y radius=\database@aspectratio*\database@radius] -- ++(0,3*\database@segmentheight);
        },
        minimum width=2*\database@radius + \pgflinewidth,
        minimum height=3*\database@segmentheight + 2*\database@aspectratio*\database@radius + \pgflinewidth,
    },
    database segment height/.store in=\database@segmentheight,
    database radius/.store in=\database@radius,
    database aspect ratio/.store in=\database@aspectratio,
    database segment height=0.1cm,
    database radius=0.25cm,
    database aspect ratio=0.35,
}
\makeatother
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{document}
\begin{tikzpicture}[start chain=going right,>=latex,node distance=0pt]
    \node[draw, rectangle, align=center, rounded corners=2mm, minimum width=3cm, minimum height=1cm] (v1) {Business \\understanding};
    \node[yshift=0.2cm] at (v1.east) (A1) {};
    \node[yshift=-0.2cm] at (v1.east) (A2) {};
    \node[draw, rectangle, align=center, rounded corners=2mm, minimum width=3cm, minimum height=1cm] (v2) [right=2cm of v1] {Data \\understanding};
    \node[yshift=0.2cm] at (v2.west) (B1){};
    \node[yshift=-0.2cm] at (v2.west) (B2){};
    \node[draw, rectangle, align=center, rounded corners=2mm, minimum width=3cm, minimum height=1cm] (v3) [below right=1.5cm and -0.5cm of v2] {Data \\preparation};
    \node at (v2.south) (B3) {};
    \node at (v3.north) (C1) {};
    \node[draw, rectangle, align=center, rounded corners=2mm, minimum width=3cm, minimum height=1cm] (v4) [below=1.5cm of v3] {Modelling};
    \node[xshift=0.2cm] at (v3.south) (C2) {};
    \node[xshift=0.2cm] at (v4.north) (D1) {};
    \node[xshift=-0.2cm] at (v3.south) (C3) {};
    \node[xshift=-0.2cm] at (v4.north) (D2) {};
    \node[draw, rectangle, align=center, rounded corners=2mm, minimum width=3cm, minimum height=1cm] (v5) [below left=1.5cm and 1.5cm of v4] {Evaluation};
    \node at (v4.south) (D3) {};
    \node at (v5.east) (E1) {};
    \node[draw, rectangle, align=center, rounded corners=2mm, minimum width=3cm, minimum height=1cm] (v6) [above left=2.5cm and 1.5cm of v5] {Evaluation};
    \node at (v5.west) (E2) {};
    \node at (v6.south) (F1) {};
    \node[database,label=below:Data,database radius=1cm,database segment height=0.5cm] (v7) [right=1.25cm of v6] {};

    \draw [-latex] (A1) --+ (B1);
    \draw [-latex] (B2) --+ (A2);
    \draw [-latex] (B3) --+ (C1);
    \draw [-latex] (C2) --+ (D1);
    \draw [-latex] (D2) --+ (C3);
    \draw [-latex] (D3) to [out=-90,in=0] (E1);
    \draw [-latex] (E2) to [out=180,in=-90] (F1);
    
    \node[xshift=1.5cm] at (v1.south) (A3) {};
    \node[xshift=1cm] at (v5.north) (E3) {};
    \draw [-latex] (E3) to [out=75,in=-25] (A3);

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % Sloppy hardcoded block
    \draw [decoration={markings, mark=at position 1 with {\arrow[scale=10,>=stealth]{>}}}, postaction={decorate}] (3.4,3.6) -- (3.5,3.6);
    \draw [decoration={markings, mark=at position 1 with {\arrow[scale=10,>=stealth]{>}}}, postaction={decorate}] (2.6,-11.12) -- (2.5,-11.12);
    \draw [decoration={markings, mark=at position 1 with {\arrow[scale=10,>=stealth]{>}}}, postaction={decorate}] (10.37,-4.1) -- (10.37,-4.2);
    \draw [decoration={markings, mark=at position 1 with {\arrow[scale=10,>=stealth]{>}}}, postaction={decorate}] (-4.37,-3.5) -- (-4.37,-3.4);
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    \node[circle, draw=black, decoration = {
        markings, 
        mark = at position 0.0  with {\arrow{latex}},
        mark = at position 0.25 with {\arrow{latex}}, 
        mark = at position 0.5  with {\arrow{latex}},
        mark = at position 0.75 with {\arrow{latex}},
    }, postaction = decorate, very thick, fit=(v1) (v2) (v3) (v4) (v5) (v6), inner sep=0pt] {};

\end{tikzpicture}
\end{document}

该代码成功生成了 CRISP-DM 模型的一个良好版本,请参阅这里以供参考。我将结果附在下面的图片中。然而,尽管成功了,但我对我的代码并不满意。尤其是我手动在圆形框架上添加四个箭头的草率的硬编码块。我最终这样做是因为我无法使用简单\arrow{scale=5, latex}或类似的方法修改装饰标记的比例。

有人能提出解决方案来替代草率的硬编码块或进行其他优化吗?

代码输出

答案1

通过定义圆圈中的节点样式并重新定义,node distance\decoration的 ME 可以变得更短更清晰:

\documentclass[tikz,border=20pt]{standalone}

\usepackage{graphicx}
\usepackage{amsmath}
\usepackage{amsthm}
\usepackage{tikz}
\usetikzlibrary{arrows.meta, % <---
                automata,
                calc, chains, 
                decorations.markings,
                fit,
                positioning, 
                shapes.geometric, shapes.multipart}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% https://tex.stackexchange.com/a/442994/233668
\makeatletter
\tikzset{
    database/.style={
        path picture={
            \draw (0, 1.5*\database@segmentheight) circle [x radius=\database@radius,y radius=\database@aspectratio*\database@radius];
            \draw (-\database@radius, 0.5*\database@segmentheight) arc [start angle=180,end angle=360,x radius=\database@radius, y radius=\database@aspectratio*\database@radius];
            \draw (-\database@radius,-0.5*\database@segmentheight) arc [start angle=180,end angle=360,x radius=\database@radius, y radius=\database@aspectratio*\database@radius];
            \draw (-\database@radius,1.5*\database@segmentheight) -- ++(0,-3*\database@segmentheight) arc [start angle=180,end angle=360,x radius=\database@radius, y radius=\database@aspectratio*\database@radius] -- ++(0,3*\database@segmentheight);
        },
        minimum width=2*\database@radius + \pgflinewidth,
        minimum height=3*\database@segmentheight + 2*\database@aspectratio*\database@radius + \pgflinewidth,
    },
    database segment height/.store in=\database@segmentheight,
    database radius/.store in=\database@radius,
    database aspect ratio/.store in=\database@aspectratio,
    database segment height=0.1cm,
    database radius=0.25cm,
    database aspect ratio=0.35,
}
\makeatother
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{document}
    \begin{tikzpicture}[
node distance = 12mm and 21mm,
every edge/.style = {draw,semithick, -{Stealth[scale=1.2]}},
       box/.style = {draw, rounded corners=2mm, 
                     minimum width=3cm, minimum height=1cm,
                     align=center},
decoration = {markings, 
              mark = between positions 0 and 1 step 0.25  with {\arrowreversed{Stealth[scale=4]}} % <---
              }, 
                    ]
% nodes
\node (v1) [box]                {Business \\understanding};
    \coordinate[above=2mm of v1.east] (A1);
    \coordinate[below=2mm of v1.east] (A2);
\node (v2) [box, right=of v1]   {Data \\understanding};
    \coordinate[above=2mm of v2.west] (B1);
    \coordinate[below=2mm of v2.west] (B2);
\node (v3) [box, below right=of v2.south west]  {Data \\preparation};
    \coordinate[left =2mm of v3.south] (C1);
    \coordinate[right=2mm of v3.south] (C2);
\node (v4) [box, below=of v3] {Modelling};
    \coordinate[left =2mm of v4.north] (D1);
    \coordinate[right=2mm of v4.north] (D2);
\node (v5) [box, below  left=of v4.south]    {Evaluation};
\node (v6) [box, above left=of v5 |- v4] {Evaluation};
\node (v7) [database,
            database radius=1cm,
            database segment height=0.5cm,
            label=below:Data] [above=of v5] {};
%
    \path   (A1) edge (B1) 
            (B2) edge (A2)
            (v2) edge (v3)  %(B3) edge (C1)
            (C1) edge (D1)
            (D2) edge (C2)
            (v4) edge [out=-90,in=0  ] (v5)
            (v5) edge [out=180,in=-90] (v6)
            (v5) edge [out=45, in=-5, looseness=1.3] (v1);
    \node[circle, draw, postaction = {decorate}, 
    very thick, fit=(v1) (v4)] {};
\end{tikzpicture}
\end{document}

在此处输入图片描述

您可以通过设置装饰样式中的比例来更改圆圈上箭头的大小:

\arrow{Stealth[scale=4]}

到所需大小,例如\arrow{Stealth[scale=3]}\arrow{Stealth[width=7mm, length=6mm, bend]}(需要加载 TikZ 库bending)。

相关内容