\documentclass{article} \usepackage{tikz-opm} \usepackage{a4wide} \usepackage{etoolbox} \usepackage[T1]{fontenc} \usepackage{dejavu} \usepackage{showexpl} \lstset{basicstyle=\ttfamily\small, explpreset={rframe={}}} \usetikzlibrary{fit} \title{\texttt{tikz-opm}: creating Object Process Methodology diagrams with Tikz\\ Version 0.1.1} \author{Torben Hoffmann \\ e-mail: \texttt{torben.lehoff@gmail.com}} \begin{document} \maketitle \tikzset{every node/.style={font={\usefont{T1}{DejaVuSerifCondensed-TLF}{m}{n}}}} \label{sec:tikz-opm:-creating} The \texttt{tikz-opm} package allows you to create nice OPM diagrams using a number of relatively simple commands. The package does not attempt to do any clever things - I am not clever enough to encode smart placement of things like the aggregation symbol below the object it applies to. Sorry. But it does allow you to most of the important things from OPM displayed in your diagram, so that is pretty good. First we start out with the picture from the front of the OPM book: \begin{LTXexample}[caption=OPM book front page,pos=t, varwidth=false] \begin{tikzpicture} \node [opmobject] (object) {Object}; \node [opmaggregation, below=of object] (object-aggr) {}; \path (object) edge (object-aggr); \node [opmobject, below=of object-aggr] (system) {System}; \path (object-aggr) edge (system); \node [opmprocess, below left=of system] (commercializing) {Commercializing}; \path (system) edge [opmagent] (commercializing); \node [opmaggregation, below=of system] (system-aggr) {}; \node [opmobject, below=of system-aggr] (product) {Product}; \path (system) edge (system-aggr) edge (product); \path (commercializing) edge[opmoutput] (product.north west); \node [opmgeneralization, below right=25pt of system, xshift=10pt] (system-gen) {}; \node [opmobject, below=15pt of system-gen] (function) {Function}; \draw [thick] (system.east) -| (system-gen.north); \path (system-gen.south) edge (function); \node [opmprocess, below=of function, yshift=-20pt] (benefitting) {Benefitting}; \path (function) edge[opmagent] (benefitting); \node [opmobject, right=of function] (beneficiary) {Beneficiary}; \path (benefitting) edge[opmeffect] (beneficiary); \end{tikzpicture} \end{LTXexample} \section{Catalog of OPM symbols} \label{sec:catalog-opm-symbols} \lstset{ explpreset={rframe={},width=0.3\linewidth}} \begin{LTXexample}[rangeprefix=\%, rangesuffix=, includerangemarker=false, linerange=start-stop] \begin{tikzpicture} %start \node [opmobject] (object) {Object}; %stop \end{tikzpicture} \end{LTXexample} \begin{LTXexample}[rangeprefix=\%, rangesuffix=, includerangemarker=false, linerange=start-stop] \begin{tikzpicture} %start \node [opmprocess] (processing) {Process(ing)}; %stop \end{tikzpicture} \end{LTXexample} \begin{LTXexample}[rangeprefix=\%, rangesuffix=, includerangemarker=false, linerange=start-stop, caption=Aggregation for object, pos=t] \begin{tikzpicture} %start \node [opmobject] (root) {Root}; \node [opmaggregation, below=of root] (root-aggr) {}; \path (root) edge (root-aggr); \node [opmobject, below left=of root-aggr] (part-a) {Part A}; \node [opmobject, below right=of root-aggr] (part-b) {Part B}; \path (root-aggr) edge (part-a); \draw [thick] (root-aggr.east) -| (part-b.north); %stop \end{tikzpicture} \end{LTXexample} Note that in order to get the more traditional vertial/horizontal lines with right angles one has to use \verb|draw| and the \verb,-|, operator. \begin{LTXexample}[rangeprefix=\%, rangesuffix=, includerangemarker=false, linerange=start-stop, pos=t, caption=Aggregation for process] \begin{tikzpicture} %start \node [opmprocess] (root) {Rooting}; \node [opmaggregation, below=of root] (root-aggr) {}; \path (root) edge (root-aggr); \node [opmprocess, below left=of root-aggr] (part-a) {Part Aing}; \node [opmprocess, below right=of root-aggr] (part-b) {Part Bing}; \path (root-aggr) edge (part-a); \draw [thick] (root-aggr.east) -| (part-b.north); %stop \end{tikzpicture} \end{LTXexample} \begin{LTXexample}[rangeprefix=\%, rangesuffix=, includerangemarker=false, linerange=start-stop, pos=t, caption=Exhibition] \begin{tikzpicture} %start \node [opmobject] (root) {Root}; \node [opmexhibition, below=of root] (root-aggr) {}; \path (root) edge (root-aggr.north); \node [opmobject, below left=of root-aggr] (part-a) {Attr A}; \node [opmprocess, below right=of root-aggr] (part-b) {Operating}; \path (root-aggr) edge (part-a); \draw [thick] (root-aggr.east) -| (part-b.north); %stop \end{tikzpicture} \end{LTXexample} Note that one could equally well have a Rooting process instead of Root in exhibition. %%% GENERALIZATION \begin{LTXexample}[rangeprefix=\%, rangesuffix=, includerangemarker=false, linerange=start-stop, pos=t, caption=Generalization for object] \begin{tikzpicture} %start \node [opmobject] (root) {Root}; \node [opmgeneralization, below=of root] (root-aggr) {}; \path (root) edge (root-aggr.north); \node [opmobject, below left=of root-aggr] (part-a) {Spec A}; \node [opmobject, below right=of root-aggr] (part-b) {Spec B}; \path (root-aggr) edge (part-a); \draw [thick] (root-aggr.east) -| (part-b.north); %stop \end{tikzpicture} \end{LTXexample} \begin{LTXexample}[rangeprefix=\%, rangesuffix=, includerangemarker=false, linerange=start-stop, pos=t, caption=Generalization for process] \begin{tikzpicture} %start \node [opmprocess] (root) {Rooting}; \node [opmgeneralization, below=of root] (root-aggr) {}; \path (root) edge (root-aggr.north); \node [opmprocess, below left=of root-aggr] (part-a) {Spec Aing}; \node [opmprocess, below right=of root-aggr] (part-b) {Spec Bing}; \path (root-aggr) edge (part-a); \draw [thick] (root-aggr.east) -| (part-b.north); %stop \end{tikzpicture} \end{LTXexample} %% INSTANTIATION \begin{LTXexample}[rangeprefix=\%, rangesuffix=, includerangemarker=false, linerange=start-stop, pos=t, caption=Instantiation for object] \begin{tikzpicture} %start \node [opmobject] (root) {Root}; \node [opminstantiation, below=of root] (root-aggr) {}; \path (root) edge (root-aggr.north); \node [opmobject, below left=of root-aggr] (part-a) {Instance A}; \node [opmobject, below right=of root-aggr] (part-b) {Instance B}; \path (root-aggr) edge (part-a); \draw [thick] (root-aggr.east) -| (part-b.north); %stop \end{tikzpicture} \end{LTXexample} \begin{LTXexample}[rangeprefix=\%, rangesuffix=, includerangemarker=false, linerange=start-stop, pos=t, caption=Instantiation for process] \begin{tikzpicture} %start \node [opmprocess] (root) {Rooting}; \node [opminstantiation, below=of root] (root-aggr) {}; \path (root) edge (root-aggr.north); \node [opmprocess, below left=of root-aggr] (part-a) {Instance Aing}; \node [opmprocess, below right=of root-aggr] (part-b) {Instance Bing}; \path (root-aggr) edge (part-a); \draw [thick] (root-aggr.east) -| (part-b.north); %stop \end{tikzpicture} \end{LTXexample} \begin{LTXexample}[rangeprefix=\%, rangesuffix=, includerangemarker=false, linerange=start-stop, pos=t, caption=Consumption] \begin{tikzpicture} %start \node [opmprocess] (processing) {Processing}; \node [opmobject, right=of processing] (object) {Object}; \path (processing) edge[opmconsumes] (object); %stop \end{tikzpicture} \end{LTXexample} \begin{LTXexample}[rangeprefix=\%, rangesuffix=, includerangemarker=false, linerange=start-stop, pos=t, caption=Result] \begin{tikzpicture} %start \node [opmprocess] (processing) {Processing}; \node [opmobject, right=of processing] (object) {Object}; \path (processing) edge[opmyields] (object); %stop \end{tikzpicture} \end{LTXexample} \begin{LTXexample}[rangeprefix=\%, rangesuffix=, includerangemarker=false, linerange=start-stop, pos=t, caption=Effect] \begin{tikzpicture} %start \node [opmprocess] (processing) {Processing}; \node [opmobject, right=of processing] (object) {Object}; \path (processing) edge[opmaffects] (object); %stop \end{tikzpicture} \end{LTXexample} \begin{LTXexample}[rangeprefix=\%, rangesuffix=, includerangemarker=false, linerange=start-stop, pos=t, caption=Agent] \begin{tikzpicture} %start \node [opmprocess] (processing) {Processing}; \node [opmobject, left=of processing] (object) {Object}; \path (object) edge[opmhandles] (processing); %stop \end{tikzpicture} \end{LTXexample} \begin{LTXexample}[rangeprefix=\%, rangesuffix=, includerangemarker=false, linerange=start-stop, pos=t, caption=Instrument] \begin{tikzpicture} %start \node [opmprocess] (processing) {Processing}; \node [opmobject, left=of processing] (object) {Object}; \path (processing) edge[opmrequires] (object); %stop \end{tikzpicture} \end{LTXexample} \begin{LTXexample}[rangeprefix=\%, rangesuffix=, includerangemarker=false, linerange=start-stop, pos=t, caption=Invocation] \begin{tikzpicture} %start \node [opmprocess] (x-processing) {X Processing}; \node [opmprocess, right=of x-processing] (y-processing) {Y Processing}; \path (x-processing) edge[opminvokes] (y-processing); %stop \end{tikzpicture} \end{LTXexample} Note that the version with two arrow heads have been chosen since it is easier to work with than with the lightning zig-zag line that OPM uses in the book. \begin{LTXexample}[rangeprefix=\%, rangesuffix=, includerangemarker=false, linerange=start-stop, pos=t, caption=State] \begin{tikzpicture} %start \node [opmstate] (nonexistent) {nonexistent}; \node [opmstate, right=of nonexistent] (existent) {existent}; \node [opmobject, fit=(nonexistent) (existent), text depth=5ex] (object) {Object}; \node [opmprocess, below=of object] (constructing) {Constructing}; \path (constructing) edge[opmconsumes] (nonexistent); \path (constructing) edge[opmyields] (existent); %stop \end{tikzpicture} \end{LTXexample} This is not optimal, so I could do with some help on making this drawing nicer. Using \verb|text depth=5ex| is a very crude way of scaling the object box. Putting the \verb|text depth| inside a Tikz style does not help \emph{unless} one ensures that it is called after the \verb|fit| key. \end{document} %%% Local Variables: %%% mode: latex %%% TeX-master: t %%% End: