我正在尝试制作流行的 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
)。