加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
pgf-umlcd.sty 9.88 KB
一键复制 编辑 原始数据 按行查看 历史
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Start of pgf-umlcd.sty
%
% Some macros for UML Class Diagrams.
% Home page of project: http://pgf-umlcd.googlecode.com/
% Author: Xu Yuan <xu@informatik.hu-berlin.de>, Humboldt University, Berlin
% Style from: http://www.ibm.com/developerworks/cn/rational/r-uml/
%
\NeedsTeXFormat{LaTeX2e}[1999/12/01]
\ProvidesPackage{pgf-umlcd}[2011/10/01 v0.3dev Some LaTeX macros for
UML Class Diagrams.]
\RequirePackage{tikz}
\usetikzlibrary{arrows,shapes.multipart,backgrounds,fit}
\tikzstyle{help lines}+=[blue!50,very thin,dashed]
\newcommand{\umltextcolor}{black}
\newcommand{\umldrawcolor}{purple}
\newcommand{\umlfillcolor}{yellow!20}
\tikzstyle{umlcolor}=[color=\umldrawcolor,fill=\umlfillcolor,text=\umltextcolor]
\tikzstyle{umlcd style}=[umlcolor, >=angle 90]
\tikzstyle{package}=[matrix, column sep=1mm, row sep=1cm, node distance=2cm]
\tikzstyle{packagename}=[rectangle, minimum height=2em]
\tikzstyle{umlcd style implement line}=[color=\umldrawcolor, open triangle 45-,dashed]
\tikzstyle{objectline}=[color=\umldrawcolor, diamond->]
\tikzstyle{umlcd style inherit line}=[color=\umldrawcolor, open triangle 45-]
\tikzstyle{splitline}=[color=\umldrawcolor, dotted,font=\itshape]
\tikzstyle{umlcd style class}=[rectangle split, rectangle split parts=3,
every text node part/.style={text centered},
draw, minimum height=2em, umlcolor, minimum width=2cm, text width=5cm,
minimum height=1cm, node distance=2cm]
\tikzstyle{umlcd style dashed line}=[color=\umldrawcolor, >=angle 90,dashed]
\tikzstyle{umlcd style school}=[]
\newif\ifschool\schoolfalse
\DeclareOption{school}{\tikzstyle{umlcd style school}=[rounded corners] \schooltrue}
\newif\ifsimplified\simplifiedfalse
\DeclareOption{simplified}{\simplifiedtrue}
\ProcessOptions\relax
% declare layers
\pgfdeclarelayer{background}
\pgfdeclarelayer{connectionlayers}
\pgfsetlayers{background,connectionlayers,main}
\newcounter{umlcdClassAttributesNum}
\newcounter{umlcdClassOperationsNum}
\newcounter{umlcdClassAbstractClassNum}
\newcounter{umlcdClassInterfaceNum}
\newcounter{umlcdClassSplitPartNum}
\def\umlcdPackageFit{}
\newenvironment{class}[3][]%
{
\begin{classAndInterfaceCommon}{#1}{#2}{#3}
}%
{\calcuateNumberOfParts{}
\node[anchor=north, this umlcd style] (\umlcdClassName) at (\umlcdClassPos)
{\textbf{\umlcdClassName}
\insertAttributesAndOperations{}
};
\end{classAndInterfaceCommon}
}
\newenvironment{interface}[3][]%
{
\begin{classAndInterfaceCommon}{#1}{#2}{#3}
}%
{\calcuateNumberOfParts{}
\node[anchor=north,this umlcd style] (\umlcdClassName) at (\umlcdClassPos)
{$<<$interface$>>$ \\ \textbf{\umlcdClassName}
\insertAttributesAndOperations{}
};
\end{classAndInterfaceCommon}
}
\newenvironment{abstractclass}[3][]%
{
\begin{classAndInterfaceCommon}{#1}{#2}{#3}
}%
{\calcuateNumberOfParts{}
\node[anchor=north, this umlcd style] (\umlcdClassName) at (\umlcdClassPos)
{$<<$abstract$>>$ \\ \textbf{\umlcdClassName}
\insertAttributesAndOperations{}
};
\end{classAndInterfaceCommon}
}
\newenvironment{staticclass}[3][]%
{
\begin{classAndInterfaceCommon}{#1}{#2}{#3}
}%
{\calcuateNumberOfParts{}
\node[this umlcd style, anchor=north] (\umlcdClassName) at (\umlcdClassPos)
{$<<$static$>>$ \\ \textbf{\umlcdClassName}
\insertAttributesAndOperations{}
};
\end{classAndInterfaceCommon}
}
% TODO: here the name of \umlcdClassName and \umlObjectName should be
% switched, it is only for reusing \classAndInterfaceCommon at the
% moment.
\newenvironment{object}[3][]%
{
\begin{classAndInterfaceCommon}{#1}{#2}{#3}
\def\@instanceOf{}
\def\@@instanceOf{}
}%
{
% customized
\ifsimplified
\calcuateNumberOfParts{}
\else
\ifnum\c@umlcdClassOperationsNum>0
\setcounter{umlcdClassSplitPartNum}{3}
\protected@xdef\umlcdSplitPart{3}
\else
\setcounter{umlcdClassSplitPartNum}{2}
\protected@xdef\umlcdSplitPart{2}
\fi
\fi
\ifx\@instanceOf\@@instanceOf
\def\umldObjectName{\umlcdClassName}
\else
\def\umldObjectName{\umlcdClassName : \@instanceOf}
\fi
\node[anchor=north, this umlcd style, umlcd style school] (\umlcdClassName) at (\umlcdClassPos)
{ \ifschool
\textbf{\umldObjectName}
\else
\underline{\textbf{\umldObjectName}}
\fi
\insertAttributesAndOperations{}
};
\end{classAndInterfaceCommon}
}
\newcommand*{\insertAttributesAndOperations}
{
\ifnum\c@umlcdClassSplitPartNum>1
\nodepart{second}
\fi
\umlcdClassAttributes
\ifnum\c@umlcdClassSplitPartNum>2
\nodepart{third}
\fi
\umlcdClassOperations
}
\newcommand*{\calcuateNumberOfParts}
{
% calcuate the number of parts
\ifsimplified
\setcounter{umlcdClassSplitPartNum}{1}
\ifnum\c@umlcdClassAttributesNum>0
\stepcounter{umlcdClassSplitPartNum}
\fi
\ifnum\c@umlcdClassOperationsNum>0
\stepcounter{umlcdClassSplitPartNum}
\fi
\else
\setcounter{umlcdClassSplitPartNum}{3}% three parts by default
\fi
\protected@xdef\umlcdSplitPart{3}
\ifnum\c@umlcdClassSplitPartNum=1
\protected@xdef\umlcdSplitPart{1}
\fi
\ifnum\c@umlcdClassSplitPartNum=2
\protected@xdef\umlcdSplitPart{2}
\fi
}
\newenvironment*{classAndInterfaceCommon}[3]
{
\def\umlcdClassName{#2}%
\def\umlcdClassPos{#3}
\def\umlcdClassAttributes{}%
\def\umlcdClassOperations{}%
\def\umlcdClassAbstractClass{}%
\def\umlcdClassInterface{}%
\setcounter{umlcdClassAttributesNum}{0}%
\setcounter{umlcdClassOperationsNum}{0}%
\setcounter{umlcdClassAbstractClassNum}{0}%
\setcounter{umlcdClassInterfaceNum}{0}%
\tikzstyle{this umlcd style}=[umlcd style class, rectangle split
parts=\umlcdSplitPart, #1]
}%
{
%% connections
\begin{pgfonlayer}{connectionlayers}
\ifnum\c@umlcdClassAbstractClassNum>0
\foreach \c in \umlcdClassAbstractClass {
\draw [umlcd style inherit line] (\c) -- (\umlcdClassName);
}
\fi
\ifnum\c@umlcdClassInterfaceNum>0
\foreach \c in \umlcdClassInterface {
\draw [umlcd style implement line] (\c) -- (\umlcdClassName);
}
\fi
\end{pgfonlayer}
%% add to fit
\let\umlcdPackageFitOld\umlcdPackageFit
\protected@xdef\umlcdPackageFit{\umlcdPackageFitOld (\umlcdClassName)}
}
\newcommand{\attribute}[1]{%
\ifnum\c@umlcdClassAttributesNum=0
\protected@xdef\umlcdClassAttributes{#1}
\else
\let\umlcdClassAttributesOld\umlcdClassAttributes
\protected@xdef\umlcdClassAttributes{\umlcdClassAttributesOld \ \newline
#1}
\fi
\stepcounter{umlcdClassAttributesNum}
}
\newcommand{\operation}[2][1]{%
\stepcounter{umlcdClassOperationsNum}
\def\virtualoperation{#2}
\ifnum0=#1
\def\virtualoperation{\textit{#2}}
\fi
\ifnum\c@umlcdClassOperationsNum=1
\protected@xdef\umlcdClassOperations{\virtualoperation}
\else
\let\umlcdClassOperationsOld\umlcdClassOperations
\protected@xdef\umlcdClassOperations{\umlcdClassOperationsOld \ \newline
\virtualoperation}
\fi
}
\newcommand{\inherit}[1]
{
\stepcounter{umlcdClassAbstractClassNum}
\ifnum\c@umlcdClassAbstractClassNum=1
\protected@xdef\umlcdClassAbstractClass{#1}
\else
\let\umlcdClassAbstractClassOld\umlcdClassAbstractClass
\protected@xdef\umlcdClassAbstractClass{\umlcdClassAbstractClassOld,
#1}
\fi
}
\newcommand{\implement}[1]
{
\stepcounter{umlcdClassInterfaceNum}
\ifnum\c@umlcdClassInterfaceNum=1
\protected@xdef\umlcdClassInterface{#1}
\else
\let\umlcdClassInterfaceOld\umlcdClassInterface
\protected@xdef\umlcdClassInterface{\umlcdClassInterfaceOld,
#1}
\fi
}
\newcommand{\instanceOf}[1]{\def\@instanceOf{#1}}
%\newcommand{\association}[7][]{
%\draw [umlcd style,#1] (#2) -- (#5)
% node[near start, auto]{#3}
% node[near start, auto, swap]{#4}
% node[near end, auto]{#6}
% node[near end, auto, swap]{#7};
%}
% 耿楠修改(2020.02.08)
\newcommand{\association}[7][{}]{
\draw [umlcd style] (#2) -- (#5)
node[midway, above]{$\blacktriangleleft$~#1}
node[very near start, above]{#3}%xshift=-0.5cm,
node[very near start, below]{#4}
node[very near end, below]{#6}
node[very near end, above]{#7};
}
\newcommand{\unidirectionalAssociation}[5][]{
\draw [umlcd style, ->, #1] (#2) -- (#5)
node[near end, auto]{#3}
node[near end, auto, swap]{#4};
}
\newcommand{\aggregation}[5][]{
\draw[umlcd style, open diamond->, #1] (#2) -- (#5)
node[near end, auto]{#3}
node[near end, auto, swap]{#4};
}
\newcommand{\composition}[5][]{
\draw[umlcd style, fill=\umldrawcolor, diamond->, #1] (#2) -- (#5)
node[near end, auto]{#3}
node[near end, auto, swap]{#4};
}
\newenvironment{package}[1]{
\def\umlcdPackageFit{}
\def\umlcdPackageName{#1}
}{
\begin{pgfonlayer}{background}
\node[umlcd style, draw, inner sep=0.5cm, fit = \umlcdPackageFit] (\umlcdPackageName) {};
\node[umlcd style, draw, outer ysep=-0.5, anchor=south west] (\umlcdPackageName caption) at
(\umlcdPackageName.north west) {\umlcdPackageName};
\end{pgfonlayer}
}
\newcommand{\switchUmlcdSchool}{
\ifschool
\tikzstyle{umlcd style school}=[]
\schoolfalse
\else
\tikzstyle{umlcd style school}=[rounded corners]
\schooltrue
\fi
}
\pgfdeclareshape{umlcdnote}{
\inheritsavedanchors[from=rectangle] % this is nearly a rectangle
\inheritanchorborder[from=rectangle]
\inheritanchor[from=rectangle]{center}
\inheritanchor[from=rectangle]{north}
\inheritanchor[from=rectangle]{south}
\inheritanchor[from=rectangle]{west}
\inheritanchor[from=rectangle]{east}
% ... and possibly more
\backgroundpath{% this is new
% store lower right in xa/ya and upper right in xb/yb
\southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
\northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y
% compute corner of flipped page
\pgf@xc=\pgf@xb \advance\pgf@xc by-10pt % this should be a parameter
\pgf@yc=\pgf@yb \advance\pgf@yc by-10pt
% construct main path
\pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@ya}}
\pgfpathlineto{\pgfpoint{\pgf@xa}{\pgf@yb}}
\pgfpathlineto{\pgfpoint{\pgf@xc}{\pgf@yb}}
\pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yc}}
\pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@ya}}
\pgfpathclose
% add little corner
\pgfpathmoveto{\pgfpoint{\pgf@xc}{\pgf@yb}}
\pgfpathlineto{\pgfpoint{\pgf@xc}{\pgf@yc}}
\pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yc}}
\pgfpathlineto{\pgfpoint{\pgf@xc}{\pgf@yc}}
}
}
\newcommand{\umlnote}[1][]{
\node[umlcd style, anchor=north, draw,shape=umlcdnote, text width=4cm, #1]
}
%%% End of pgf-umlcd.sty
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化