2

I am trying to make the diagram of the popular CRISP-DM model. My code is below.

\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}

The code successfuly produces a nice version of the CRISP-DM model, see here for reference. I attach the result in the image below. However, despite the success, I am not satisfied with my code. Especially, the sloppy hardcoded block where I manually add the four arrows on the circular frame. I ended up doing that because I was not able to modify the scale of the decoration marking using a simple \arrow{scale=5, latex} or similar.

Can anyone propose a solution to replace the sloppy hardcoded block or some other optimization?

Output of the code

gva
  • 23

1 Answers1

3

With defining style for nodes in circle, and redefining node distance and \decoration your ME can become much shorter and clear:

\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}

enter image description here

Size of arrows on circle you can change by setting scale in decoration style:

\arrow{Stealth[scale=4]}

to desired size, for example \arrow{Stealth[scale=3]} or \arrow{Stealth[width=7mm, length=6mm, bend]} (which require to load TikZ library bending).

Zarko
  • 296,517