4

This question is a follow up to How to draw inside a TikZ node, using node style?

I am trying to get the AND and XOR gateway from BPMN as seen here http://www.omg.org/bpmn/Samples/Elements/Gateways.GIF

As a starting point I found this style file https://github.com/sbadia/gdeploy/blob/master/francegrilles/tikz-bpmn.sty but to get the plus and x in the gateway I have to set them as text. That does not look nice at all... How would I draw a thick 'plus' for the AND gateway and add the same share rotated by 45° for the XOR? With 'thick' I mean that it is significantly thicker than the border of the shape. Also note that neither the plus nor the x actually reach the border of the surrounding shape.

Reference showing BPMN Gateways

DodoFXP
  • 457
  • I removed the thanks and sign off. Neither are necessary; the sign off because your user name and badge are already displayed, and thanks is expressed as upvoting answers that help you. You should place the diagrams you linked to, or equivalents, into the question directly since we can't rely on external resources to remain intact in the future and it's bothersome to have to follow links to interpret a question. – qubyte Feb 24 '12 at 17:27
  • Please note that the graphics show BPMN 1.x, not BPMN 2.0: http://www.bpmb.de/images/BPMN2_0_Poster_EN.pdf – koppor Oct 05 '13 at 00:53

2 Answers2

10

I created three new shapes based on diamond. If you need to scale these shapes and if you need to scale the circle, the cross, the + etc..., it would be interesting to choice another way to draw inside the diamond. Only the EB is well defined, for all other you need to draw a path and to fill it. But it's a lot of work.

Picture

BPMN

Code

\documentclass[11pt]{scrartcl}
\usepackage{tikz} 
\usetikzlibrary{shapes}
\makeatletter

\pgfdeclareshape{CD}
{
  \inheritsavedanchors[from=diamond] % this is nearly a rectangle
  \inheritanchorborder[from=diamond]
  \inheritanchor[from=diamond]{center}
  \inheritanchor[from=diamond]{north}
  \inheritanchor[from=diamond]{south}
  \inheritanchor[from=diamond]{west}
  \inheritanchor[from=diamond]{east}
  \inheritanchor[from=diamond]{north east}
  \inheritanchor[from=diamond]{south east}
  \inheritanchor[from=diamond]{north west}
  \inheritanchor[from=diamond]{south west}                    

  \backgroundpath{
    \pgf@process{\outernortheast}%
    \pgf@xc=\pgf@x%
    \pgf@yc=\pgf@y%
    \pgfmathsetlength{\pgf@xa}{\pgfkeysvalueof{/pgf/outer xsep}}%
    \pgfmathsetlength{\pgf@ya}{\pgfkeysvalueof{/pgf/outer ysep}}%
    \advance\pgf@xc by-1.414213\pgf@xa%
    \advance\pgf@yc by-1.414213\pgf@ya%
    \pgfpathmoveto{\pgfqpoint{\pgf@xc}{0pt}}%
    \pgfpathlineto{\pgfqpoint{0pt}{\pgf@yc}}%
    \pgfpathlineto{\pgfqpoint{-\pgf@xc}{0pt}}%
    \pgfpathlineto{\pgfqpoint{0pt}{-\pgf@yc}}%
    \pgfpathclose\pgfusepath{stroke} 
    % add 
    \advance\pgf@xc by -.5\pgf@xc% 
    \advance\pgf@yc by -.5\pgf@yc%
    \pgfsetlinewidth{2pt}
    \pgfpathmoveto{\pgfqpoint{\pgf@xc}{0pt}}%
    \pgfpathlineto{\pgfqpoint{-\pgf@xc}{0pt}}%
    \pgfpathmoveto{\pgfqpoint{0pt}{\pgf@yc}}%
    \pgfpathlineto{\pgfqpoint{0pt}{-\pgf@yc}}%
    \pgfpathmoveto{\pgfqpoint{0.707\pgf@xc}{0.707\pgf@yc}}%
     \pgfpathlineto{\pgfqpoint{-0.707\pgf@xc}{-0.707\pgf@yc}}%
     \pgfpathmoveto{\pgfqpoint{-0.707\pgf@xc}{0.707\pgf@yc}}%
     \pgfpathlineto{\pgfqpoint{0.707\pgf@xc}{-0.707\pgf@yc}}%  
      }
}

\pgfdeclareshape{PF}
{
  \inheritsavedanchors[from=diamond] % this is nearly a rectangle
  \inheritanchorborder[from=diamond]
  \inheritanchor[from=diamond]{center}
  \inheritanchor[from=diamond]{north}
  \inheritanchor[from=diamond]{south}
  \inheritanchor[from=diamond]{west}
  \inheritanchor[from=diamond]{east}
  \inheritanchor[from=diamond]{north east}
  \inheritanchor[from=diamond]{south east}
  \inheritanchor[from=diamond]{north west}
  \inheritanchor[from=diamond]{south west}                    

  \backgroundpath{
    \pgf@process{\outernortheast}%
    \pgf@xc=\pgf@x%
    \pgf@yc=\pgf@y%
    \pgfmathsetlength{\pgf@xa}{\pgfkeysvalueof{/pgf/outer xsep}}%
    \pgfmathsetlength{\pgf@ya}{\pgfkeysvalueof{/pgf/outer ysep}}%
    \advance\pgf@xc by-1.414213\pgf@xa%
    \advance\pgf@yc by-1.414213\pgf@ya%
    \pgfpathmoveto{\pgfqpoint{\pgf@xc}{0pt}}%
    \pgfpathlineto{\pgfqpoint{0pt}{\pgf@yc}}%
    \pgfpathlineto{\pgfqpoint{-\pgf@xc}{0pt}}%
    \pgfpathlineto{\pgfqpoint{0pt}{-\pgf@yc}}%
    \pgfpathclose\pgfusepath{stroke} 
    % add 
    \advance\pgf@xc by -.5\pgf@xc% 
    \advance\pgf@yc by -.5\pgf@yc%
    \pgfsetlinewidth{2pt}
    \pgfpathmoveto{\pgfqpoint{\pgf@xc}{0pt}}%
    \pgfpathlineto{\pgfqpoint{-\pgf@xc}{0pt}}%
    \pgfpathmoveto{\pgfqpoint{0pt}{\pgf@yc}}%
    \pgfpathlineto{\pgfqpoint{0pt}{-\pgf@yc}}% 
      }
}

\pgfdeclareshape{ID}
{
  \inheritsavedanchors[from=diamond] % this is nearly a rectangle
  \inheritanchorborder[from=diamond]
  \inheritanchor[from=diamond]{center}
  \inheritanchor[from=diamond]{north}
  \inheritanchor[from=diamond]{south}
  \inheritanchor[from=diamond]{west}
  \inheritanchor[from=diamond]{east}
  \inheritanchor[from=diamond]{north east}
  \inheritanchor[from=diamond]{south east}
  \inheritanchor[from=diamond]{north west}
  \inheritanchor[from=diamond]{south west}                    

  \backgroundpath{
    \pgf@process{\outernortheast}%
    \pgf@xc=\pgf@x%
    \pgf@yc=\pgf@y%
    \pgfmathsetlength{\pgf@xa}{\pgfkeysvalueof{/pgf/outer xsep}}%
    \pgfmathsetlength{\pgf@ya}{\pgfkeysvalueof{/pgf/outer ysep}}%
    \advance\pgf@xc by-1.414213\pgf@xa%
    \advance\pgf@yc by-1.414213\pgf@ya%
    \pgfpathmoveto{\pgfqpoint{\pgf@xc}{0pt}}%
    \pgfpathlineto{\pgfqpoint{0pt}{\pgf@yc}}%
    \pgfpathlineto{\pgfqpoint{-\pgf@xc}{0pt}}%
    \pgfpathlineto{\pgfqpoint{0pt}{-\pgf@yc}}%
    \pgfpathclose\pgfusepath{stroke}
    % add 
    \pgfsetlinewidth{2pt}
    \pgfutil@tempdima=\pgf@xc%
    \pgfutil@tempdima=0.5\pgfutil@tempdima%
    \pgfpathcircle{\pgfpointorigin}{\pgfutil@tempdima}
      }
} 

\pgfdeclareshape{EB}
{
  \inheritsavedanchors[from=diamond] % this is nearly a rectangle
  \inheritanchorborder[from=diamond]
  \inheritanchor[from=diamond]{center}
  \inheritanchor[from=diamond]{north}
  \inheritanchor[from=diamond]{south}
  \inheritanchor[from=diamond]{west}
  \inheritanchor[from=diamond]{east}
  \inheritanchor[from=diamond]{north east}
  \inheritanchor[from=diamond]{south east}
  \inheritanchor[from=diamond]{north west}
  \inheritanchor[from=diamond]{south west}                    

  \backgroundpath{
    \pgf@process{\outernortheast}%
    \pgf@xc=\pgf@x%
    \pgf@yc=\pgf@y%
    \pgfmathsetlength{\pgf@xa}{\pgfkeysvalueof{/pgf/outer xsep}}%
    \pgfmathsetlength{\pgf@ya}{\pgfkeysvalueof{/pgf/outer ysep}}%
    \advance\pgf@xc by-1.414213\pgf@xa%
    \advance\pgf@yc by-1.414213\pgf@ya%
    \pgfpathmoveto{\pgfqpoint{\pgf@xc}{0pt}}%
    \pgfpathlineto{\pgfqpoint{0pt}{\pgf@yc}}%
    \pgfpathlineto{\pgfqpoint{-\pgf@xc}{0pt}}%
    \pgfpathlineto{\pgfqpoint{0pt}{-\pgf@yc}}%
    \pgfpathclose\pgfusepath{stroke}
    % add 
    \pgfutil@tempdima=\pgf@xc%
    \pgfutil@tempdima=0.6\pgfutil@tempdima%
    \pgfpathcircle{\pgfpointorigin}{\pgfutil@tempdima} 
        \pgfutil@tempdima=0.8\pgfutil@tempdima%
    \pgfpathcircle{\pgfpointorigin}{\pgfutil@tempdima}
     \pgfusepath{stroke} 
    %add 
        \pgfpathmoveto{\pgfqpoint{0pt}{\pgfutil@tempdima}}%
        \pgfpathlineto{\pgfqpoint{0.25\pgfutil@tempdima}{0.433\pgfutil@tempdima}}% 
        \pgfpathlineto{\pgfqpoint{0.866\pgfutil@tempdima}{0.5\pgfutil@tempdima}}%
        \pgfpathlineto{\pgfqpoint{0.5\pgfutil@tempdima}{0pt}}%
        \pgfpathlineto{\pgfqpoint{0.866\pgfutil@tempdima}{-0.5\pgfutil@tempdima}}%   
        \pgfpathlineto{\pgfqpoint{0.25\pgfutil@tempdima}{-0.433\pgfutil@tempdima}}% 
        \pgfpathlineto{\pgfqpoint{0pt}{-\pgfutil@tempdima}}% 
        \pgfpathlineto{\pgfqpoint{-0.25\pgfutil@tempdima}{-0.433\pgfutil@tempdima}}%    
        \pgfpathlineto{\pgfqpoint{-0.866\pgfutil@tempdima}{-0.5\pgfutil@tempdima}}%
        \pgfpathlineto{\pgfqpoint{-0.5\pgfutil@tempdima}{0pt}}%    
        \pgfpathlineto{\pgfqpoint{-0.866\pgfutil@tempdima}{0.5\pgfutil@tempdima}}% 
        \pgfpathlineto{\pgfqpoint{-0.25\pgfutil@tempdima}{0.433\pgfutil@tempdima}}%
        \pgfpathclose 
        \pgfusepath{fill}
       }
}  

\pgfdeclareshape{XOR}
{
  \inheritsavedanchors[from=diamond] % this is nearly a rectangle
  \inheritanchorborder[from=diamond]
  \inheritanchor[from=diamond]{center}
  \inheritanchor[from=diamond]{north}
  \inheritanchor[from=diamond]{south}
  \inheritanchor[from=diamond]{west}
  \inheritanchor[from=diamond]{east}
  \inheritanchor[from=diamond]{north east}
  \inheritanchor[from=diamond]{south east}
  \inheritanchor[from=diamond]{north west}
  \inheritanchor[from=diamond]{south west}                    

  \backgroundpath{
    \pgf@process{\outernortheast}%
    \pgf@xc=\pgf@x%
    \pgf@yc=\pgf@y%
    \pgfmathsetlength{\pgf@xa}{\pgfkeysvalueof{/pgf/outer xsep}}%
    \pgfmathsetlength{\pgf@ya}{\pgfkeysvalueof{/pgf/outer ysep}}%
    \advance\pgf@xc by-1.414213\pgf@xa%
    \advance\pgf@yc by-1.414213\pgf@ya%
    \pgfpathmoveto{\pgfqpoint{\pgf@xc}{0pt}}%
    \pgfpathlineto{\pgfqpoint{0pt}{\pgf@yc}}%
    \pgfpathlineto{\pgfqpoint{-\pgf@xc}{0pt}}%
    \pgfpathlineto{\pgfqpoint{0pt}{-\pgf@yc}}%
    \pgfpathclose\pgfusepath{stroke}
    %add 
    \advance\pgf@xc by -.5\pgf@xc% 
    \pgfsetlinewidth{2pt}
    \pgfpathmoveto{\pgfqpoint{ 0.6\pgf@xc}{0.8484\pgf@xc}}%
    \pgfpathlineto{\pgfqpoint{-0.6\pgf@xc}{-0.8484\pgf@xc}}%
    \pgfpathmoveto{\pgfqpoint{-0.6\pgf@xc}{0.8484\pgf@xc}}%
    \pgfpathlineto{\pgfqpoint{ 0.6\pgf@xc}{-0.8484\pgf@xc}}%  
    }
} 
\begin{document}

\begin{tikzpicture}
  \node[draw,shape=CD,minimum size=1cm] (x) {};
  \node[draw,shape=PF,minimum size=1cm] at ([shift=(0:5cm)]x) (y) {};
  \node[draw,shape=ID,minimum size=1cm] at ([shift=(90:5cm)]x) (z) {};
  \node[draw,shape=EB,minimum size=1cm] at ([shift=(0:5cm)]z) (t) {};
  \node[draw,shape=XOR,minimum size=1cm] at ([shift=(-30:3cm)]t) (v) {};   
  \draw[dashed,ultra thick] (x) -- (y) -- (z)--(t) -- (v);
\end{tikzpicture}

\end{document}
Alain Matthes
  • 95,075
  • Inclusive Decision (ID) and XOR are easy to draw. The only problem is Event-Based ... but it's possible with time – Alain Matthes Feb 24 '12 at 18:57
  • Almost perfect. Can you maybe add the exclusive OR with the 'X' in it? – DodoFXP Feb 25 '12 at 09:44
  • yes I'm working on the last shapes – Alain Matthes Feb 25 '12 at 09:58
  • Could you publish your style at github? Similar to the rather incomplete tikz-bpmn.sty at https://github.com/sbadia/gdeploy/blob/master/francegrilles/tikz-bpmn.sty? Furthermore, I have to say that the event-based gateway is BPMN 1.x and not BPMN 2.0. See this poster for a complete list of symbols of BPMN2.0. Maybe it helps to complete your solution? http://www.bpmb.de/images/BPMN2_0_Poster_EN.pdf – koppor Oct 05 '13 at 00:49
1

I had similar request couple years ago. I wrote a helper library. Feel free to use: https://blog.kubovy.eu/2013/10/04/latex-tikz-bpmn-2-0-gateways/