UML混乱图

UML混乱图

我有 7 个类,想用 Latex 制作这些类的 UML 图。我确实设法编写了代码,但请看一下结果(我甚至尝试过重新缩放和重新排列): 在此处输入图片描述 您甚至无法识别显示关系的所有线条。如您所见,UML 非常混乱,所以我想知道是否可以在 Latex 中制作此 UML,使其看起来更清晰?代码:

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{fullpage}
\usepackage[schoo,simplified]{pgf-umlcd}
\date{January 2019}

\begin{document}



\maketitle

\section{UML-diagram (se næste side)}
\newpage
\begin{tikzpicture}
\begin{package}{Chess}
\begin{class}[text width = 5cm]{chessPiece}{0,0}
    \attribute{\textit{nameOfType : string}}
    \attribute{color : Color}
    \attribute{position : Position option with get/set = None}
    \attribute{\textit{candidateRelativeMoves : Position list list}}
    \attribute{}
    \operation{}
    \operation{ToString : unit $\rightarrow$ string}
    \operation{availableMoves : Board $\rightarrow$ Position list}
    \operation{isThreatened : Board : chessPiece : Position $\rightarrow$ bool}
    \operation{}
\end{class}
\begin{class}[text width = 5cm]{Board}{-5.5,0}
    \attribute{Item : : chessPiece option with set}
    \operation{static validPositionWrap : Position $\rightarrow$ Position option}
    \operation{ToString : unit $\rightarrow$ string}
    \operation{move : Position : Position $\rightarrow$ unit}
    \operation{getVacantNOccupied : chessPiece : Position list $\rightarrow$ unit}
    \operation{getVacantNNeighbours : chessPiece : Position list $\rightarrow$ unit}
\end{class}
\end{package}
\begin{package}{Pieces}
\begin{class}[text width = 3cm]{king}{-11,-1}
\inherit{chessPiece}
\attribute{nameOfType : string= "king"}
\attribute{candidateRelativeMoves = [[(-1,0)];[(-1,1)];[(0,1)];[(1,1)];
      [(1,0)];[(1,-1)];[(0,-1)];[(-1,-1)]]}
\end{class}
\begin{class}[text width = 3cm]{rook}{-11,-5}
    \inherit{chessPiece}
    \attribute{nameOfType : string= "rook"}
    \attribute{candidateRelativeMoves = List.map (swap List.map [1..7]) indToRel}
\end{class}
\end{package}
\begin{package}{Interactives}
\begin{class}[text width = 5cm]{Player}{0,-8}
    \attribute{pieceToMove : chessPiece option = None}
    \operation{nextMove : Board $\rightarrow$ string}
\end{class}
\begin{class}[text width = 5 cm]{Human}{0, -11}
    \inherit{Player}
\end{class}
\end{package}
\begin{class}[text width = 5cm]{Game}{-8,-10}
    \attribute{player1 : Human}
    \attribute{player2 : Human}
    \attribute{\_board : Board}
    \operation{setup : unit}
    \operation{run : unit}
    \operation{valid : string [] $\rightarrow$ Human $\rightarrow$ bool}
\end{class}
\unidirectionalAssociation {chessPiece}{}{}{Board}
\unidirectionalAssociation{Game}{}{}{chessPiece}
\unidirectionalAssociation{Game}{}{}{Player}
\composition{Game}{}{}{king}
\composition{Game}{}{}{rook}
\composition{Game}{}{}{Human}
\composition{Game}{}{}{Board}
\composition{Player}{}{}{chessPiece}
\end{tikzpicture}
\end{document}

更好版本的示例,其中包含修改后的箭头的示例: 在此处输入图片描述

答案1

这个看起来怎么样?主要是我只是重新定位了一些东西,改变了一些text widths 和字体大小。请注意,我将一些类相对于其他类进行了定位(请参阅有没有什么方法可以使用 LaTeX 创建 UML 而无需提供 (x,y) 坐标?了解更多信息),这使得对齐事物变得更容易。

如果您有修改建议,请随时在评论中添加。例如,当然可以以不同的方式绘制各种箭头,它们不必是直线,但可能需要更多的手动工作,而不是pgf-umlcd宏(\composition等等)。

下面的代码展示了在包之间创建继承箭头的几种方法kingchessPieceChess是使用标准 TikZ\draw宏“手动”完成的。

它们主要利用在路径的角点定义命名坐标,并使用-|/|-路径规范(参见TikZ:箭头的 |- 符号到底起什么作用?) 来绘制线条。为了获得正确的外观,我添加了umlcd style inherit line样式。有些方法需要特定的 TikZ 库,在评论中提到。

在此处输入图片描述

\documentclass{article}
\usepackage[school,simplified]{pgf-umlcd}
\usetikzlibrary{calc}
\usetikzlibrary{positioning}
\usepackage{fullpage}

\begin{document}   
\begin{tikzpicture}[font=\footnotesize] % reduce fontsize
\begin{package}{Chess}
\begin{class}[text width = 3.3cm]{chessPiece}{0,0}
    \attribute{\textit{nameOfType : string}}
    \attribute{color : Color}
    \attribute{position : Position option with get/set = None}
    \attribute{\textit{candidateRelativeMoves : Position list list}}
    \attribute{}
    \operation{}
    \operation{ToString : unit $\rightarrow$ string}
    \operation{availableMoves : Board $\rightarrow$ Position list}
    \operation{isThreatened : Board : chessPiece : Position $\rightarrow$ bool}
    \operation{}
\end{class}
\begin{class}[text width = 3cm, xshift=-3cm]{Board}{chessPiece.north west}
    \attribute{Item : : chessPiece option with set}
    \operation{static validPositionWrap : Position $\rightarrow$ Position option}
    \operation{ToString : unit $\rightarrow$ string}
    \operation{move : Position : Position $\rightarrow$ unit}
    \operation{getVacantNOccupied : chessPiece : Position list $\rightarrow$ unit}
    \operation{getVacantNNeighbours : chessPiece : Position list $\rightarrow$ unit}
\end{class}
\end{package}
\begin{package}{Pieces}
\begin{class}[text width = 3.3cm, xshift=-4cm]{king}{Board.north west}
%\inherit{chessPiece}
\attribute{nameOfType : string= "king"}
\attribute{candidateRelativeMoves = [[(-1,0)];[(-1,1)];[(0,1)];[(1,1)];
      [(1,0)];[(1,-1)];[(0,-1)];[(-1,-1)]]}
\end{class}
\begin{class}[text width = 3.3cm, yshift=-5mm]{rook}{king.south}
    \inherit{chessPiece}
    \attribute{nameOfType : string= "rook"}
    \attribute{candidateRelativeMoves = List.map (swap List.map [1..7]) indToRel}
\end{class}
\end{package}
\begin{package}{Interactives}
\begin{class}[text width = 3.3cm, yshift=-2cm]{Player}{chessPiece.south}
    \attribute{pieceToMove : chessPiece option = None}
    \operation{nextMove : Board $\rightarrow$ string}
\end{class}
\begin{class}[text width = 3.3cm, yshift=-1cm]{Human}{Player.south}
    \inherit{Player}
\end{class}
\end{package}
\begin{class}[text width = 4cm, xshift=-4cm]{Game}{Player.north west}
    \attribute{player1 : Human}
    \attribute{player2 : Human}
    \attribute{\_board : Board}
    \operation{setup : unit}
    \operation{run : unit}
    \operation{valid : string [] $\rightarrow$ Human $\rightarrow$ bool}
\end{class}
\unidirectionalAssociation {chessPiece}{}{}{Board}
\unidirectionalAssociation{Game}{}{}{chessPiece}
\unidirectionalAssociation{Game}{}{}{Player}
\composition{Game}{}{}{king}
\composition{Game}{}{}{rook}
\composition{Game}{}{}{Human}
\composition{Game}{}{}{Board}
\composition{Player}{}{}{chessPiece}

%% method 1
%\path (king.east) ++(1cm,0) coordinate (m1)
%      (chessPiece.north) ++(0,1.2cm) coordinate(m2);
%\draw [umlcd style inherit line] (chessPiece.north) -- (m2) -| (m1) -- (king.east);

%% method 2 -- requires \usetikzlibrary{calc}
%\draw [umlcd style inherit line]
%     let
%         \p1=(king.east),\p2=(Board.west)
%     in
%     (chessPiece.north) -- ++(0,1.2cm) -| ($(\x1,\y1)!0.5!(\x2,\y1)$) -- (king.east);

%% method 3 -- requires \usetikzlibrary{calc}
%\draw [umlcd style inherit line] (chessPiece.north) -- ++(0,1.2cm) -| ($(king.east)+(1.2cm,0)$) -- (king.east);

%% method 4 -- requires \usetikzlibrary{positioning}
%\coordinate [above left=of Chess] (m3);
%\draw [umlcd style inherit line] (chessPiece) |- (m3) |- (king);

%% method 5
\coordinate (m4) at ([shift={(-4mm,7mm)}]Chess.north west);
\draw [umlcd style inherit line] (chessPiece) |- (m4) |- (king);
\end{tikzpicture}
\end{document}

相关内容