diff options
author | Karl Berry <karl@freefriends.org> | 2016-01-16 22:46:06 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2016-01-16 22:46:06 +0000 |
commit | 1629fa910035b872b0791f328cd558c10d27e079 (patch) | |
tree | aeacfd0fc48bef08372385abc77724cc67b3f9e5 /Master/texmf-dist/tex/latex/tkz-orm | |
parent | 106ad151a3e9d062d40f48f230e57f8a4765329a (diff) |
tkz-orm (16jan16)
git-svn-id: svn://tug.org/texlive/trunk@39408 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/latex/tkz-orm')
-rw-r--r-- | Master/texmf-dist/tex/latex/tkz-orm/tkz-orm.sty | 809 |
1 files changed, 620 insertions, 189 deletions
diff --git a/Master/texmf-dist/tex/latex/tkz-orm/tkz-orm.sty b/Master/texmf-dist/tex/latex/tkz-orm/tkz-orm.sty index 498656a04b2..749a1f55ee7 100644 --- a/Master/texmf-dist/tex/latex/tkz-orm/tkz-orm.sty +++ b/Master/texmf-dist/tex/latex/tkz-orm/tkz-orm.sty @@ -8,10 +8,10 @@ % 1. under the LaTeX Project Public License and/or % 2. under the GNU Public License. % -% Copyright 2009 by Jakob Voss +% Copyright 2009-2016 by Jakob Voss, Camil Staps %<–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––> \NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{tkz-orm}[2010/01/20 v0.1 Object-Role Modeling] +\ProvidesPackage{tkz-orm}[2016/01/15 v0.1.4 Object-Role Modeling] %<–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––> \RequirePackage{tikz}[2009/09/04] @@ -21,6 +21,7 @@ \usetikzlibrary{shadows} \usetikzlibrary{positioning} \usetikzlibrary{calc} +\usetikzlibrary{fit} \makeatletter @@ -33,23 +34,21 @@ \def\orm@error#1{\relax}% TODO %\def\orm@error#1{\PackageWarning{tkz-orm}{#1}}% +%\pgfkeysdefargs{/tikz/ormcolorlet}{#1}{\colorlet{#2}{#1}} +% \pgfkeys{/orm/.is family} % TODO -%%%% Stuff missing in TikZ (should become part if TikZ) +\def\tkzorm{\textsf{tkz-orm}} -\pgfarrowsdeclare{none}{none}{ - \arrowsize=0pt - \pgfarrowsleftextend{0} - \pgfarrowsrightextend{0} -}{ - \arrowsize=0pt - \pgfarrowsleftextend{0} - \pgfarrowsrightextend{0} -} -\tikzstyle{noarrows}=[arrows=none-none] +%%%% ORM color constants +\colorlet{constraintcolor}{magenta!100} +\colorlet{ormconstraintcolor}{magenta!100} +\colorlet{ormdeonticcolor}{blue!100} +\colorlet{ormimpliedcolor}{gray!100} +\def\orm@constraint@stroke{magenta} +\def\orm@constraint@fill{magenta} -%%%% ORM color constants -\definecolor{constraintcolor}{rgb}{1,0,1} +\pgfkeysdefargs{/tikz/constraintcolor}{#1}{\colorlet{constraintcolor}{#1}} %%%% ORM width and length \newlength{\orm@linewidth} @@ -64,10 +63,8 @@ %%%% Text markup -% textsubscript like textsuperscript -\DeclareRobustCommand*\textsubscript[1]{% - \@textsubscript{\selectfont#1}} -\newcommand{\@textsubscript}[1]{% +% textsubscript may not be defined like textsuperscript +\newcommand{\orm@textsubscript}[1]{% {\m@th\ensuremath{_{\mbox{\fontsize\sf@size\z@#1}}}}} % similar to \blacktriangle (could better be implemented directly in pgf) @@ -85,9 +82,10 @@ \def\ormbf{\orm@font@bold} \def\ormc{\orm@font\color{constraintcolor}} \def\ormsup#1{\textsuperscript{\orm@font@scriptsize #1}} -\def\ormsub#1{\textsubscript{\orm@font@scriptsize #1}} -\def\ormind#1{\textsuperscript{\orm@font@bold@scriptsize #1}} +\def\ormsub#1{\orm@textsubscript{\orm@font@scriptsize #1}} +\def\ormind#1{\textsuperscript{\orm@font@bold@scriptsize\color{constraintcolor} #1}} \def\ormbraces#1{{\orm@font\textbraceleft#1\textbraceright}} +\def\ormvalues#1{\ormc{\ormbraces{#1}}} \def\ormleft#1{{\ormarrowleft\ormtext #1}} \def\ormup#1{{\ormtext #1\ormarrowup}} @@ -102,33 +100,42 @@ %%%% ORM styles -\tikzstyle{every orm line}= [solid,draw,line width=\orm@linewidth] +\pgfkeys{/tikz/constraint stroke/.store in=\orm@constraint@stroke} +\pgfkeys{/tikz/constraint fill/.store in=\orm@constraint@fill} +\pgfkeys{/tikz/constraint color/.style={constraint stroke=#1,constraint fill=#1}} + + +\tikzstyle{every orm line}= [solid,draw=black,line width=\orm@linewidth,-] \tikzstyle{orm}= [font=\orm@font,node distance=4mm, %label distance=1.5mm, - line width=\orm@linewidth, + %line width=\orm@linewidth, label distance=1.25mm ] +\tikzstyle{orm-spacious}= [orm, + every object/.style={shape=circle} + ] \tikzstyle{every orm}= [every orm line,fill=white,orm] \tikzstyle{zoomed}= [line width=\orm@linewidth*1.5] -\tikzstyle{every object type}= [] +\tikzstyle{every object}= [] \tikzstyle{every entity}= [] \tikzstyle{entity}= [every orm, shape=rectangle,rounded corners, align=center,minimum size=6mm, - every object type,every entity] + every object,every entity] \tikzstyle{every value}= [] \tikzstyle{value}= [every orm, shape=rectangle,rounded corners,densely dashed, align=center,minimum size=6mm, - every object type,every value] + every object,every value] \tikzstyle{relationship}= [every orm line,every relationship] \tikzstyle{relation}= [relationship] +\tikzstyle{plays}= [relationship] \tikzstyle{every relationship}= [] @@ -159,6 +166,10 @@ \tikzaddtikzonlycommandshortcutdef{\rules}{\matrix[row sep=0mm,nodes={right}]} \tikzaddtikzonlycommandshortcutdef{\limits}{\draw[limits]} +\tikzaddtikzonlycommandshortcutdef{\limited}{\draw[limits]} +\tikzaddtikzonlycommandshortcutdef{\limitsto}{\draw[limits to]} + +\tikzaddtikzonlycommandshortcutdef{\constraint}{\node[text=constraintcolor]} %%%% Textual rules @@ -167,7 +178,7 @@ \bgroup% [current point is local=true] (\tikzlastnode.north west) node[font=\orm@font@bold@scriptsize, - anchor=north east,inner sep=0] {#1} + anchor=north east,inner sep=0,text=constraintcolor] {#1} \egroup% }, orm,inner sep=0.5mm, @@ -205,6 +216,97 @@ % TODO: read % http://www.latex-project.org/guides/clsguide.pdf +\pgfkeyssetvalue{/tkzorm/constraintstroke}{constraintcolor} +\pgfkeyssetvalue{/tkzorm/constraintfill}{constraintcolor} + +%%% +% arrow heads + +% dot as arrow head (no color) +\pgfarrowsdeclare{dot}{dot}{ + \pgfutil@tempdima=0.2pt% + \advance\pgfutil@tempdima by.2\pgflinewidth% + \pgfutil@tempdimb=5.5\pgfutil@tempdima\advance\pgfutil@tempdimb + by\pgflinewidth + \pgfarrowsleftextend{+-\pgfutil@tempdimb} + \pgfutil@tempdimb=1.5\pgfutil@tempdima\advance\pgfutil@tempdimb + by.5\pgflinewidth + \pgfarrowsrightextend{+\pgfutil@tempdimb} +}{ + \pgfutil@tempdima=0.2pt% + \advance\pgfutil@tempdima by.2\pgflinewidth% + \pgfsetdash{}{+0pt} + \pgfpathcircle{\pgfqpoint{+3\pgfutil@tempdima}{0pt}}{+4.5\pgfutil@tempdima} + \pgfsetstrokecolor{\orm@constraint@stroke} + \pgfsetfillcolor{\orm@constraint@fill} + %\pgfsetfillcolor{\pgfkeysvalueof{/tkzorm/constraintfill}} + \pgfusepathqfillstroke +} + +% mandatory constraint dot arrow head +\pgfarrowsdeclare{mdot}{mdot}{ + \pgfarrowsrightextend{0pt}% put arrow head over the tip + \pgfutil@tempdima=0.25mm\advance\pgfutil@tempdima by 0.5\pgflinewidth% lw + \pgfarrowsleftextend{+-\pgfutil@tempdima}% for arrow composing +}{ + \pgfutil@tempdima=0.5mm\advance\pgfutil@tempdima by \pgflinewidth% radius + \pgfutil@tempdimb=0.25mm\advance\pgfutil@tempdimb by 0.5\pgflinewidth% lw + \pgfpathcircle{\pgfqpoint{0.5\pgflinewidth}{0pt}}{\pgfutil@tempdima} + \pgfsetfillcolor{ormconstraintcolor} + \pgfusepathqfill +} + +% implied mandatory constraint dot arrow head +\pgfarrowsdeclare{idot}{idot}{ + \pgfarrowsrightextend{0pt}% put arrow head over the tip + \pgfutil@tempdima=0.25mm\advance\pgfutil@tempdima by 0.5\pgflinewidth% lw + \pgfarrowsleftextend{+-\pgfutil@tempdima}% for arrow composing +}{ + \pgfutil@tempdima=0.5mm\advance\pgfutil@tempdima by \pgflinewidth% radius + \pgfpathcircle{\pgfqpoint{0.5\pgflinewidth}{0pt}}{\pgfutil@tempdima} + \pgfsetfillcolor{ormimpliedcolor} + \pgfusepathqfill +} + +% deontic mandatory constraint dot arrow head +\pgfarrowsdeclare{odot}{odot}{ + \pgfutil@tempdima=0.5mm\advance\pgfutil@tempdima by 1.0\pgflinewidth% radius + \pgfarrowsrightextend{0.5\pgfutil@tempdima}% put arrow head over the tip + \pgfarrowsleftextend{0pt}% for arrow composing +}{ + %\pgfutil@tempdima=0.5mm\advance\pgfutil@tempdima by 1.0\pgflinewidth% radius + %\pgfutil@tempdimb=0.25mm\advance\pgfutil@tempdimb by 0.5\pgflinewidth% lw + %\advance\pgfutil@tempdima by -0.5\pgfutil@tempdimb% -linewidth + \pgfutil@tempdima=0.475mm\advance\pgfutil@tempdima by 0.75\pgflinewidth% r-lw + \pgfutil@tempdimb=0.25mm\advance\pgfutil@tempdimb by 1\pgflinewidth% lw + \pgfpathcircle{\pgfqpoint{\pgfutil@tempdimb}{0pt}}{\pgfutil@tempdima} + \pgfutil@tempdima=0.25mm\advance\pgfutil@tempdima by 0.5\pgflinewidth% lw + \pgfsetdash{}{+0pt} + \pgfsetlinewidth{\pgfutil@tempdima} + \pgfsetstrokecolor{ormdeonticcolor} + \pgfsetfillcolor{white} + \pgfusepathqfillstroke +} + +% implied deontic mandatory constraint dot arrow head +\pgfarrowsdeclare{iodot}{iodot}{ + \pgfutil@tempdima=0.5mm\advance\pgfutil@tempdima by 1.0\pgflinewidth% radius + \pgfarrowsrightextend{0.5\pgfutil@tempdima}% put arrow head over the tip + \pgfarrowsleftextend{0pt}% for arrow composing +}{ + \pgfutil@tempdima=0.475mm\advance\pgfutil@tempdima by 0.75\pgflinewidth% r-lw + \pgfutil@tempdimb=0.25mm\advance\pgfutil@tempdimb by 1\pgflinewidth% lw + \pgfpathcircle{\pgfqpoint{\pgfutil@tempdimb}{0pt}}{\pgfutil@tempdima} + \pgfutil@tempdima=0.25mm\advance\pgfutil@tempdima by 0.5\pgflinewidth% lw + \pgfsetdash{}{+0pt} + \pgfsetlinewidth{\pgfutil@tempdima} + \pgfsetstrokecolor{ormimpliedcolor} + \pgfsetfillcolor{white} + \pgfusepathqfillstroke +} + + +% filled arrow for subtyping, subset constraints and value-comparision constraints \pgfarrowsdeclare{orm arrow}{orm arrow} { \pgfutil@tempdima=0.5pt% @@ -222,54 +324,44 @@ \pgfpathlineto{\pgfqpoint{0.5\pgfutil@tempdima}{0\pgfutil@tempdima}} \pgfpathlineto{\pgfpointadd{\pgfqpoint{0.5\pgfutil@tempdima}{0pt}}{\pgfqpointpolar{-157}{10\pgfutil@tempdima}}} \pgfpathclose + \pgfsetfillcolor{ormconstraintcolor} % TODO: change if implied, deontic etc. + %\pgfsetstrokefillcolor{ormconstraintcolor} % TODO: change if implied, deontic etc. \pgfusepathqfillstroke } -% enables the 'mandatory' arrow tip -%\tikzstyle{mandatory}= [relationship,cdot-] -%\tikzstyle{required}= [relationship,cdot-] -%\tikzstyle{optional}= [relationship] -%\tikzstyle{required by}= [relationship,-cdot] -%\tikzstyle{both required}= [relationship,cdot-cdot] -%\tikzstyle{both mandatory}= [relationship,cdot-cdot] - -% TODO: save the current 'to path' parameters and restore it or use execute -\tikzstyle{mandatory}= [relationship, - to path={-- (\tikztotarget) {[to path={-- (\tikztotarget) \tikztonodes}] \tikztonodes} node[cdot,pos=0]{}} -] - -\tikzstyle{required by}= [relationship, - to path={-- (\tikztotarget) {[to path={-- (\tikztotarget) \tikztonodes}] \tikztonodes} node[cdot,pos=1]{}} -] - -\tikzstyle{both mandatory}= [relationship, - to path={-- (\tikztotarget) {[to path={-- (\tikztotarget) \tikztonodes}] \tikztonodes} - node[cdot,pos=0]{} node[cdot,pos=1]{}} -] -\tikzstyle{required}= [mandatory] -\tikzstyle{both required}= [both mandatory] -\tikzstyle{optional}= [relationship] +% line styles that enable the mandatory constraint arrow tip +\tikzstyle{required} =[relationship,mdot-] +\tikzstyle{required by} =[relationship,-mdot] +\tikzstyle{both required} =[relationship,mdot-mdot] +% aliases +\tikzstyle{mandatory} =[required] +\tikzstyle{both mandatory}=[both required] +\tikzstyle{optional} =[relationship] -\tikzstyle{constraint dot} = [fill=constraintcolor,minimum size=1.5mm,draw=none,shape=circle,inner sep=0] -\tikzstyle{cdot}=[constraint dot] +% draw a mandatory constraint arrow tip over a node +\tikzset{constraint dot/.style={append after command={ + (\tikzlastnode.center) edge[required] (\tikzlastnode.center) +}}} +\tikzstyle{cdot} =[constraint dot] %%%% Constraint symbols -\tikzstyle{every constraint}= [draw=constraintcolor] -\tikzstyle{every constraint line}= [line width=\orm@linewidth,draw=constraintcolor,solid] +\tikzstyle{every constraint}= [] +% TODO: every uniqueness bar +\tikzstyle{every constraint line}= [every orm line,draw=constraintcolor,every constraint] +%\tikzstyle{every constraint line}= [line width=\orm@linewidth,draw=constraintcolor,solid] \tikzstyle{every constraint circle}=[] -\tikzstyle{constraint circle}= [every orm,every constraint, +\tikzstyle{constraint circle}= [every orm,every constraint line, shape=circle, font=\orm@font@scriptsize, minimum size=4mm,,inner sep=0pt, every constraint circle] \tikzstyle{constraint no circle}= [constraint circle,draw=none,fill=none] -\tikzstyle{limits}= [line width=\orm@linewidth,draw=constraintcolor,dotted] -\tikzstyle{limits to}= [line width=\orm@linewidth,draw=constraintcolor,dashed, - color=constraintcolor,-orm arrow] +\tikzstyle{limits}= [every constraint line,dotted] +\tikzstyle{limits to}= [every constraint line,dashed,-orm arrow] % internal uniqueness constraint @@ -280,9 +372,29 @@ \tikzstyle{duplicated model}= [every orm/.append style={drop shadow}, every predicate/.append style={drop shadow}] -\tikzstyle{implied}= [fill=gray!30,thin] -\tikzstyle{implied model}= [every orm/.append style={fill=gray!30}, - every orm line/.append style={thin}] +\tikzstyle{every implied line}= [constraintcolor=gray!80,thin] +\tikzstyle{every implied}= [fill=gray!30,every implied line] + +\tikzstyle{implied}=[ + every orm/.append style={every implied}, + every orm line/.append style={every implied line},, + constraint color=gray!100,thin, + every relationship/.style={fill=gray!30}, + required/.append style={idot-}, + required by/.append style={-idot}, + both required/.append style={idot-idot} +] +\tikzstyle{implied model}=[implied] + +\tikzstyle{deontic}= [ + every orm line/.append style={constraintcolor=blue!100}, + constraintcolor=blue!100, + constraint color=blue!100, + required/.append style={odot-}, + required by/.append style={-odot}, + both required/.append style={odot-odot} +] + %%%% Constraints @@ -313,7 +425,7 @@ % style /tikz/constraint and its keys \tikzset{constraint/.is choice} -\tikzset{constraint/misc/.style={constraint circle,text=constraintcolor}}% +%\tikzset{constraint/misc/.style={constraint circle,text=constraintcolor}}% %\constraintdeclarealias{le}{symmetric} @@ -371,85 +483,17 @@ %\tikzstyle{entity}= [every orm, % shape=rectangle,rounded corners, % align=center,minimum size=6mm, -% every object type,every entity] +% every object,every entity] \tikzset{constraint/text/.style={color=constraintcolor,font=\orm@font,align=center}} \tikzset{constraint/.default=text} % TODO: color=constraintcolor -\constraintdeclare{custom}{} % empty constraint circle -% inclusive-or (disjunctive mandatory role) constraint -\constraintdeclareasnode{mandatory}{ - \fill[every constraint,fill=constraintcolor] (0,0) circle (1mm); -} -\constraintdeclarealias{required}{mandatory} -\constraintdeclarealias{total}{mandatory} -\constraintdeclarealias{or}{mandatory} - -% exclusive constraint ('x') -\constraintdeclare{exclusive}{ - ($(\tikzlastnode.center) +(45:2mm)$) edge[every constraint line] +(225:4mm) - ($(\tikzlastnode.center) +(-45:2mm)$) edge[every constraint line] +(-225:4mm) -} -\constraintdeclarealias{x}{exclusive} - -% exclusive-or constraint ('xor' or 'partition') -\constraintdeclareasnode{xor}{ - \fill[every constraint,fill=constraintcolor] (0,0) circle (1mm); - \draw[every constraint line] (45:2mm) -- (225:2mm) - (-45:2mm) -- (-225:2mm); -} -\constraintdeclarealias{partition}{xor} - -% external uniqueness constraint -\constraintdeclare{unique}{ - (\tikzlastnode.east) edge [every constraint line] (\tikzlastnode.west) -} - -\constraintdeclare{preferred unique}{ - ($(\tikzlastnode.west) +(0,-.4mm)$) edge[every constraint line] +(4mm,0mm) - ($(\tikzlastnode.west) +(0, .4mm)$) edge[every constraint line] +(4mm,0mm) -} - -\constraintdeclare{equal}{ - ($(\tikzlastnode.center) +(-.8mm,-.4mm)$) edge[every constraint line] +(1.6mm,0mm) - ($(\tikzlastnode.center) +(-.8mm, .4mm)$) edge[every constraint line] +(1.6mm,0mm) -} - -\constraintdeclareasnode{subset}{ - \draw [every constraint line,rounded corners=0] - (.8mm,0mm) -- (-.2mm, 0mm) arc (270:90:0.5mm) -- (.8mm,.9mm) - (.8mm,-.9mm) -- (-.8mm,-.9mm); -} - -\constraintdeclareasnode{supset}{ - \draw [every constraint line,rounded corners=0] - (-.8mm,0mm) -- (.2mm, 0mm) arc (-90:90:0.5mm) -- (-.8mm,.9mm) - (.8mm,-.9mm) -- (-.8mm,-.9mm); -} - -% Collection constraints (no standard ORM2) - -\constraintdeclareasnode{ordered}{ - \draw [every constraint line,rounded corners=0] - (1.6mm,.8mm) -- (0,0) -- (1.6mm,-.8mm); -} -\constraintdeclarealias{sorted}{ordered} - -\constraintdeclareasnode{counted}{ - \draw [every constraint line] - (-.9mm,-.4mm) -- (+.9mm,-.4mm) - (-.9mm,+.4mm) -- (+.9mm,+.4mm) - (-.4mm,-.9mm) -- (-.4mm,+.9mm) - (+.4mm,-.9mm) -- (+.4mm,+.9mm); -} -\constraintdeclarealias{in bag}{counted} -\constraintdeclarealias{in multiset}{counted} %%%% Ring constraints -% TODO: join +% TODO: possibly join with cdot \tikzstyle{ormdot}= [fill=constraintcolor,radius=.6mm,draw=none] @@ -471,13 +515,47 @@ \draw[every constraint line] (270:0mm) to (270:1.75mm); } +% TODO: document +\constraintdeclareasnode{strongly intransitive}{ + \fill[every constraint line,fill=white,draw=white] circle (2.2mm); + \path [ormdot] (90:2mm) circle; + \path [ormdot] (30:1mm) circle; + \path [ormdot] (210:2mm) circle; + \path [ormdot] (330:2mm) circle; + \path[every constraint line,rounded corners=0] (90:2mm) -- (210:2mm) -- (330:2mm) -- (90:2mm); + \draw[every constraint line] (270:0mm) to (270:1.75mm); +} + +% TODO: document tree and otree +\constraintdeclareasnode{tree}{ + \fill[every constraint line,fill=white,draw=white] circle (2.2mm); + \path [ormdot] (90:2mm) circle; + \path [ormdot] (210:2mm) circle; + \path [ormdot] (330:2mm) circle; + \path[every constraint line,rounded corners=0] (339:2mm) -- (90:2mm) -- (210:2mm); +} + +\constraintdeclareasnode{otree}{ + \fill[every constraint line,fill=white,draw=white] circle (2.2mm); + \path [ormdot] (90:2mm) circle; + \path [ormdot] (210:2mm) circle; + \path [ormdot] (330:2mm) circle; + \path[every constraint line,rounded corners=0] (339:2mm) -- (90:2mm) -- (210:2mm); + \path[every constraint line,rounded corners=0] + (.8mm,-0mm) -- (-.6mm,-1mm) -- (.8mm,-2mm); +} \constraintdeclareasnode{purely reflexive}{ + \path[use as bounding box] (270:2.75mm) -- (90:2.75mm); + \path [ormdot] (180:2mm) circle; + \draw[every constraint line] (90:1.25mm) to (270:1.25mm); +% (-.8mm, .4mm) -- (.8mm, .4mm) +% (-.8mm,-.4mm) -- (.8mm,-.4mm); +} + +\constraintdeclareasnode{reflexive}{ + \path[use as bounding box] (270:2.75mm) -- (90:2.75mm); \path [ormdot] (180:2mm) circle; - \path [ormdot] ( 0:2mm) circle; - \draw[every constraint line] - (-.8mm, .4mm) -- (.8mm, .4mm) - (-.8mm,-.4mm) -- (.8mm,-.4mm); } \constraintdeclareasnode{irreflexive}{ @@ -525,11 +603,9 @@ } \constraintdeclareasnode{antisymmetric}{ - \path[use as bounding box] (270:2.75mm) -- (90:2.75mm); \path [ormdot] (180:2mm) circle; \path [ormdot] ( 0:2mm) circle; - \path [every constraint line,fill=white,radius=.7mm] (0:2mm) circle; - \draw [every constraint line] (270:1mm) to (270:2.75mm); + \draw[every constraint line] (90:2.75mm) to (270:2.75mm); } \constraintdeclareasnode{tree}{ @@ -543,7 +619,7 @@ % TODO: strictly order, total, connected, etc. - +% TODO: test and document this \tikzset{objectification/.style={ entity,fill=none, append after command={ @@ -556,11 +632,13 @@ %%%% Subtypes - -\tikzstyle{subtype}= [line width=\orm@linewidth*1.5, % TODO: how to get current line width? - >=orm arrow,<-,solid,draw] -\tikzstyle{suptype}= [subtype,->] - + % TODO: how to get current line width? +\tikzstyle{inheritance}=[line width=\orm@linewidth*1.5,>=orm arrow, + draw,color=constraintcolor] +\tikzstyle{subtype}=[inheritance,<-,solid] +\tikzstyle{suptype}=[inheritance,->,solid] +\tikzstyle{subinterface}=[subtype,dashed] +\tikzstyle{supinterface}=[suptype,dashed] %%%% Role indices @@ -605,87 +683,440 @@ \ifnum#1<0-\fi0.5*\orm@role@height+#1*\orm@rolebar@shift% } -\tikzstyle{uniqueness bar}=[every constraint line] +\tikzstyle{uniqueness bar}=[every constraint line,-] \tikzstyle{skipped uniqueness bar}=[ - every constraint line,dotted,preaction={every constraint line,white} + every constraint line,-,dotted,preaction={every constraint line,-,white} ] \def\orm@unique@bar@normal{uniqueness bar} \def\orm@unique@bar@skipped{skipped uniqueness bar} \global\let\orm@unique@bar@style=\orm@unique@bar@normal -\tikzset{ - unique/.code={\orm@parse@unique#1:\pgf@nil}, - unique/.default=1, +%% +% Styles to draw external constraints +% +\pgfkeys{ + /orm/external constraint/.style={ + every constraint line, + fill=white,text=constraintcolor,align=center, + font=\orm@font@scriptsize,minimum size=4mm,inner sep=0pt + } +} + +% Defines an external constraints as node shape, based on the circle shape +% The symbol is *always* drawn but circle and fill can be modified. +% You can still modify the layout via color, line width, stroke opacity. +% The shapes do not respect outer sep (outer xsep/outer ysep) yet (TODO). +\newcommand{\constraintdeclareshape}[2]{% + \expandafter\pgfdeclareshape{#1}{ + \inheritsavedanchors[from=circle] + \inheritanchor[from=circle]{north} + \inheritanchor[from=circle]{north west} + \inheritanchor[from=circle]{north east} + \inheritanchor[from=circle]{center} + \inheritanchor[from=circle]{west} + \inheritanchor[from=circle]{east} + \inheritanchor[from=circle]{mid} + \inheritanchor[from=circle]{mid west} + \inheritanchor[from=circle]{mid east} + \inheritanchor[from=circle]{base} + \inheritanchor[from=circle]{base west} + \inheritanchor[from=circle]{base east} + \inheritanchor[from=circle]{south} + \inheritanchor[from=circle]{south west} + \inheritanchor[from=circle]{south east} + \inheritanchorborder[from={circle}] + \backgroundpath{% \behindbackgroundpath and \beforebackgroundpath don't do. + \pgfsetdash{}{0pt}% solid circle + \pgfutil@tempdima=\radius% + \pgfmathsetlength{\pgf@xb}{\pgfkeysvalueof{/pgf/outer xsep}}% + \pgfmathsetlength{\pgf@yb}{\pgfkeysvalueof{/pgf/outer ysep}}% + \ifdim\pgf@xb<\pgf@yb% + \advance\pgfutil@tempdima by-\pgf@yb% + \else% + \advance\pgfutil@tempdima by-\pgf@xb% + \fi% + \pgfpathcircle{\centerpoint}{\pgfutil@tempdima}% + } + \foregroundpath{% + \pgfsetdash{}{0pt}% + \pgfsetbuttcap% + \pgfsetmiterjoin% + #2 \pgfusepathqstroke% + } + } + \tikzset{constraint/#1/.style={/orm/external constraint,shape=#1}} + \tikzset{#1 constraint/.style={/orm/external constraint,shape=#1}} +} + + +\constraintdeclareshape{unique}{ + \pgfpathmoveto{\centerpoint\advance\pgf@x by-\radius}% + \pgfpathlineto{\centerpoint\advance\pgf@x by\radius}% +} + +\constraintdeclareshape{preferred unique}{ + \centerpoint \pgf@xc=\pgf@x \pgf@yc=\pgf@y% + \pgfutil@tempdima=\pgflinewidth% + \pgfutil@tempdima1.5\pgfutil@tempdima% + \pgfpathmoveto{\centerpoint\advance\pgf@x by-\radius\advance\pgf@y by-\pgfutil@tempdima}% + \pgfpathlineto{\centerpoint\advance\pgf@x by\radius\advance\pgf@y by-\pgfutil@tempdima}% + \pgfpathmoveto{\centerpoint\advance\pgf@x by-\radius\advance\pgf@y by\pgfutil@tempdima}% + \pgfpathlineto{\centerpoint\advance\pgf@x by\radius\advance\pgf@y by\pgfutil@tempdima}% +} + +\constraintdeclareshape{equal}{ + \pgfutil@tempdima=\radius% x + \pgfutil@tempdima0.4\pgfutil@tempdima% + \pgfutil@tempdimb=\radius% y + \pgfutil@tempdimb0.2\pgfutil@tempdimb% + \pgfpathmoveto{\centerpoint\advance\pgf@x by-\pgfutil@tempdima\advance\pgf@y by\pgfutil@tempdimb}% + \pgfpathlineto{\centerpoint\advance\pgf@x by\pgfutil@tempdima\advance\pgf@y by\pgfutil@tempdimb}% + \pgfpathmoveto{\centerpoint\advance\pgf@x by-\pgfutil@tempdima\advance\pgf@y by-\pgfutil@tempdimb}% + \pgfpathlineto{\centerpoint\advance\pgf@x by\pgfutil@tempdima\advance\pgf@y by-\pgfutil@tempdimb}% +} + +\constraintdeclareshape{subset}{ + \pgf@xa=\radius \pgf@xa0.4\pgf@xa% xa = 0.5 r + \pgf@ya=\radius \pgf@ya0.4\pgf@ya% ya = 0.4 r + \pgf@yb0.5\pgf@ya% yb = 0.5 ya = 0.2 r + \pgf@xb=\pgf@xa \advance\pgf@xb by -\pgf@yb% + + \pgfpathmoveto{\centerpoint\advance\pgf@x by-\pgf@xa\advance\pgf@y by-\pgf@ya}% + \pgfpathlineto{\centerpoint\advance\pgf@x by \pgf@xa\advance\pgf@y by-\pgf@ya}% + \pgfpathmoveto{\centerpoint\advance\pgf@x by \pgf@xa}% + \pgfpathlineto{\centerpoint\advance\pgf@x by-\pgf@xb}% + \pgfpathmoveto{\centerpoint\advance\pgf@x by \pgf@xa\advance\pgf@y by\pgf@ya}% + \pgfpathlineto{\centerpoint\advance\pgf@x by-\pgf@xb\advance\pgf@y by\pgf@ya}% + \pgfpatharc{90}{270}{\pgf@yb} +} + +\constraintdeclareshape{supset}{ + \pgf@xa=\radius \pgf@xa0.4\pgf@xa% xa = 0.5 r + \pgf@ya=\radius \pgf@ya0.4\pgf@ya% ya = 0.4 r + \pgf@yb0.5\pgf@ya% yb = 0.5 ya = 0.2 r + \pgf@xb=\pgf@xa \advance\pgf@xb by -\pgf@yb% + + \pgfpathmoveto{\centerpoint\advance\pgf@x by-\pgf@xa\advance\pgf@y by-\pgf@ya}% + \pgfpathlineto{\centerpoint\advance\pgf@x by \pgf@xa\advance\pgf@y by-\pgf@ya}% + \pgfpathmoveto{\centerpoint\advance\pgf@x by-\pgf@xa}% + \pgfpathlineto{\centerpoint\advance\pgf@x by \pgf@xb}% + \pgfpathmoveto{\centerpoint\advance\pgf@x by-\pgf@xa\advance\pgf@y by\pgf@ya}% + \pgfpathlineto{\centerpoint\advance\pgf@x by \pgf@xb\advance\pgf@y by\pgf@ya}% + \pgfpatharc{90}{-90}{\pgf@yb} +} + +\constraintdeclareshape{exclusive}{% exclusive constraint ('x') + \pgfpathmoveto{\pgfpointadd{\centerpoint}{\pgfqpointpolar{45}{\radius}}}% + \pgfpathlineto{\pgfpointadd{\centerpoint}{\pgfqpointpolar{225}{\radius}}}% + \pgfpathmoveto{\pgfpointadd{\centerpoint}{\pgfqpointpolar{135}{\radius}}}% + \pgfpathlineto{\pgfpointadd{\centerpoint}{\pgfqpointpolar{-45}{\radius}}}% +} + +% inclusive-or (disjunctive mandatory role) constraint +\constraintdeclareshape{mandatory}{ + \pgf@xa=\radius \pgf@xa0.4\pgf@xa% + \pgfpathcircle{\centerpoint}{\pgf@xa} + \pgfsetfillcolor{constraintcolor} % TODO: constraitfillcolor / not for deontic + % use deontic dot instead? + \pgfusepathqfillstroke +} + +% exclusive-or constraint ('xor' or 'partition') +\constraintdeclareshape{partition}{ + \pgf@xa=\radius \pgf@xa0.4\pgf@xa% + \pgfpathcircle{\centerpoint}{\pgf@xa} + \pgfsetfillcolor{constraintcolor} % TODO: constraitfillcolor / not for deontic + \pgfusepathqfillstroke + \pgfpathmoveto{\pgfpointadd{\centerpoint}{\pgfqpointpolar{45}{\radius}}}% + \pgfpathlineto{\pgfpointadd{\centerpoint}{\pgfqpointpolar{225}{\radius}}}% + \pgfpathmoveto{\pgfpointadd{\centerpoint}{\pgfqpointpolar{135}{\radius}}}% + \pgfpathlineto{\pgfpointadd{\centerpoint}{\pgfqpointpolar{-45}{\radius}}}% +} + +% Collection constraints (not standard ORM2) +\constraintdeclareshape{rank}{% aka ordered set + \pgf@xa=\radius \pgf@xa0.3\pgf@xa% + \pgf@ya=\radius \pgf@ya0.4\pgf@ya% + \pgfpathmoveto{\centerpoint\advance\pgf@x by\pgf@xa\advance\pgf@y by\pgf@ya}% + \pgfpathlineto{\centerpoint\advance\pgf@x by-\pgf@ya}% + \pgfpathlineto{\centerpoint\advance\pgf@x by\pgf@xa\advance\pgf@y by-\pgf@ya}% +} +\constraintdeclareshape{sequence}{% + \pgf@xa=\radius \pgf@xa0.3\pgf@xa% + \pgf@ya=\radius \pgf@ya0.4\pgf@ya% + \pgf@xc=\radius \pgf@xc0.2\pgf@xc% + + \pgfpathmoveto{\centerpoint\advance\pgf@x by\pgf@xa\advance\pgf@y by\pgf@ya}% + \pgfpathlineto{\centerpoint\advance\pgf@x by-\pgf@ya}% + \pgfpathlineto{\centerpoint\advance\pgf@x by\pgf@xa\advance\pgf@y by-\pgf@ya}% + \pgfusepathqstroke + + \pgfsetdash{{\pgflinewidth}{1pt}}{0pt}% dotted + \pgfpathmoveto{\centerpoint\advance\pgf@x by-\radius}% + \pgfpathlineto{\centerpoint\advance\pgf@x by\radius}% +} +\constraintdeclareshape{weak sequence}{% + \pgf@xa=\radius \pgf@xa0.3\pgf@xa% + \pgf@xb=\pgflinewidth% + \pgf@yb=\radius \pgf@yb0.15\pgf@yb% + \pgf@ya=\radius \pgf@ya0.4\pgf@ya% + + \pgfpathmoveto{\centerpoint\advance\pgf@x by\pgf@xa\advance\pgf@y by\pgf@ya\advance\pgf@y by\pgf@yb}% + \pgfpathlineto{\centerpoint\advance\pgf@x by-\pgf@xa\advance\pgf@y by\pgf@yb}% + \pgfpathlineto{\centerpoint\advance\pgf@x by\pgf@xa\advance\pgf@y by-\pgf@ya\advance\pgf@y by\pgf@yb}% + + \pgfpathmoveto{\centerpoint\advance\pgf@x by-\pgf@xa\advance\pgf@x by-\pgf@xb\advance\pgf@y by-\pgf@yb}% + \pgfpathlineto{\centerpoint\advance\pgf@x by\pgf@xa\advance\pgf@x by-\pgf@xb\advance\pgf@y by-\pgf@ya\advance\pgf@y by-\pgf@yb}% + \pgfusepathqstroke + + \pgfsetdash{{\pgflinewidth}{1pt}}{0pt}% dotted + \pgfpathmoveto{\centerpoint\advance\pgf@x by-\radius\advance\pgf@y by\pgf@yb}% + \pgfpathlineto{\centerpoint\advance\pgf@x by\radius\advance\pgf@y by\pgf@yb}% +} + +\constraintdeclareshape{weak rank}{% aka poset + \pgf@xa=\radius \pgf@xa0.3\pgf@xa% + \pgf@xb=\pgflinewidth% + \pgf@yb=\radius \pgf@yb0.15\pgf@yb% + \pgf@ya=\radius \pgf@ya0.4\pgf@ya% + + \pgfpathmoveto{\centerpoint\advance\pgf@x by\pgf@xa\advance\pgf@y by\pgf@ya\advance\pgf@y by\pgf@yb}% + \pgfpathlineto{\centerpoint\advance\pgf@x by-\pgf@xa\advance\pgf@y by\pgf@yb}% + \pgfpathlineto{\centerpoint\advance\pgf@x by\pgf@xa\advance\pgf@y by-\pgf@ya\advance\pgf@y by\pgf@yb}% + \pgfpathmoveto{\centerpoint\advance\pgf@x by-\pgf@xa\advance\pgf@x by-\pgf@xb\advance\pgf@y by-\pgf@yb}% + \pgfpathlineto{\centerpoint\advance\pgf@x by\pgf@xa\advance\pgf@x by-\pgf@xb\advance\pgf@y by-\pgf@ya\advance\pgf@y by-\pgf@yb}% +} + +\constraintdeclareshape{counted}{ + \pgf@xa=\radius \pgf@xa0.5\pgf@xa% + \pgf@xb=\radius \pgf@xb0.25\pgf@xb% + \pgfpathmoveto{\centerpoint\advance\pgf@x by-\pgf@xa\advance\pgf@y by\pgf@xb} + \pgfpathlineto{\centerpoint\advance\pgf@x by\pgf@xa\advance\pgf@y by\pgf@xb} + \pgfpathmoveto{\centerpoint\advance\pgf@x by-\pgf@xa\advance\pgf@y by-\pgf@xb} + \pgfpathlineto{\centerpoint\advance\pgf@x by\pgf@xa\advance\pgf@y by-\pgf@xb} + \pgfpathmoveto{\centerpoint\advance\pgf@x by\pgf@xb\advance\pgf@y by\pgf@xa} + \pgfpathlineto{\centerpoint\advance\pgf@x by\pgf@xb\advance\pgf@y by-\pgf@xa} + \pgfpathmoveto{\centerpoint\advance\pgf@x by-\pgf@xb\advance\pgf@y by\pgf@xa} + \pgfpathlineto{\centerpoint\advance\pgf@x by-\pgf@xb\advance\pgf@y by-\pgf@xa} } +%\constraintdeclarealias{in bag}{counted} +%\constraintdeclarealias{in multiset}{counted} + +\constraintdeclareshape{external}{} % needed because shapes are in /orm/... +\constraintdeclareshape{misc}{} % alias for 'external' + +%\constraintdeclare{custom}{} % empty constraint circle + +\constraintdeclarealias{required}{mandatory} +\constraintdeclarealias{total}{mandatory} +\constraintdeclarealias{or}{mandatory} +\constraintdeclarealias{x}{exclusive} +\constraintdeclarealias{xor}{partition} + +%% +% Styles to draw uniqueness bars +% +\pgfkeys{/orm/.cd, + uniqueness bar from/.initial=1,% + uniqueness bar to/.initial=1,% + uniqueness bar level/.initial=1,% + uniqueness bar roles/.initial=1,% + uniqueness bar set roles/.style={% + /orm/uniqueness bar roles=#1, + /pgf/minimum width=#1*4mm + }, + uniqueness bar lower/.initial=0,% + uniqueness bar from/.value required,% + uniqueness bar to/.value required,% + uniqueness bar level/.value required,% + uniqueness bar roles/.value required,% + uniqueness bar set roles/.value required,% + uniqueness bar lower/.value required,% + uniqueness bar style/.style={} +} + +% +% This node shape draws a uniqueness bar above or below a predicate node. +% You should use is to shape an invisible node of same size and position +% as the predicate to constraint. The bar is affected by several styles +% named '/orm/uniqueness bar ...' each. +% +\pgfdeclareshape{uniqueness bar}{ + \inheritsavedanchors[from=rectangle] + \inheritanchorborder[from=rectangle] + \inheritanchor[from=rectangle]{north} + \inheritanchor[from=rectangle]{west} + \inheritanchor[from=rectangle]{east} + \inheritanchor[from=rectangle]{south} + \inheritanchor[from=rectangle]{center} + \savedmacro\barlevel{% + \edef\barlevel{\pgfkeysvalueof{/orm/uniqueness bar level}}% + \edef\barfrom{\pgfkeysvalueof{/orm/uniqueness bar from}}% + \edef\barto{\pgfkeysvalueof{/orm/uniqueness bar to}}% + \edef\barroles{\pgfkeysvalueof{/orm/uniqueness bar roles}}% + \edef\barlower{\pgfkeysvalueof{/orm/uniqueness bar lower}}% + } + \foregroundpath{ + \southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y + \northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y + \pgfmathsetlength\pgfutil@tempdima{ + (\pgf@xb-\pgf@xa-\pgflinewidth) / (\barroles>0 ? \barroles : 1) + }% role width + \pgf@xb=\pgf@xa + \advance\pgf@xa by 1.5\pgflinewidth% + \advance\pgf@xa by -1\pgfutil@tempdima% + \advance\pgf@xa by \barfrom\pgfutil@tempdima% + \advance\pgf@xb by-0.5\pgflinewidth% + \advance\pgf@xb by \barto\pgfutil@tempdima% + \pgfmathsetlength\pgfutil@tempdima{\barlevel}% + \pgfutil@tempdimb=3\pgflinewidth% level distance + \ifdim\pgfutil@tempdima<0pt% + \advance\pgf@ya by +0.5\pgflinewidth% + \advance\pgf@ya by \barlower\pgfutil@tempdimb% + \advance\pgf@ya by \barlevel\pgfutil@tempdimb% + \pgf@yb=\pgf@ya% + \else% + \advance\pgf@yb by-0.5\pgflinewidth% + \advance\pgf@yb by -\barlower\pgfutil@tempdimb% + \advance\pgf@yb by \barlevel\pgfutil@tempdimb% + \fi% + \pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@yb}}% + \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@yb}}% + } +} + + +% Power types +\tikzset{power/.style args={#1}{ + append after command={ + \pgfextra{ + \node[entity,shape=rectangle,rounded corners,fit={(\tikzlastnode)},label={[font=\orm@font]#1}] at (\tikzlastnode) (\tikzlastnode-power) {}; + } + } + } +} + + +% Sequence types +\tikzset{sequence/.style args={#1}{ + append after command={ + \pgfextra{ + \node[entity,shape=rectangle,rounded corners=0pt,fit={(\tikzlastnode)},label={[font=\orm@font]#1}] at (\tikzlastnode) (\tikzlastnode-sequence) {}; + } + } + } +} + \tikzset{ - skip unique/.code={\orm@parse@unique@skipped#1:\pgf@nil}, - skip unique/.default=1, + unique/.code={\orm@parse@xunique#1:\pgf@nil}, + unique/.default=1, } -% parses b:l and b -\def\orm@parse@unique#1:#2\pgf@nil{% +% parses '<which>:<level>' and '<which>' +\def\orm@parse@xunique#1:#2\pgf@nil{% \def\orm@temp{#2}% \ifx\orm@temp\pgfutil@empty% - \orm@@parse@unique#1:0_1:\pgf@nil% + \orm@@parse@xunique#1:1:\pgf@nil% \else% - \orm@@parse@unique#1:0_#2\pgf@nil% + \orm@@parse@xunique#1:#2\pgf@nil% \fi% } -\def\orm@parse@unique@skipped#1:#2\pgf@nil{% +% parses n-m:<level> and n:<level> +\def\orm@@parse@xunique#1:#2:\pgf@nil{% + \pgfutil@in@{-}{#1}% + \ifpgfutil@in@% + \orm@parse@xunique@@bar#1:#2\pgf@nil% + \else% + \orm@parse@xunique@@bar#1-#1:#2\pgf@nil% + \fi% +} + +\def\orm@parse@xunique@@bar#1-#2:#3\pgf@nil{% + \def\orm@tempA{#1}% + \ifx\orm@tempA\pgfutil@empty% + \relax% + \orm@parse@xunique@@bar#2-#2:-1\pgf@nil + \else% +\tikzset{append after command={ + \bgroup% + [current point is local=true] + let \p1 = (\tikzlastnode.west), \p2 = (\tikzlastnode.east) + in \pgfextra{\pgfmathparse{(\x2-\x1)/4mm}} + (\tikzlastnode) node[ + /orm/uniqueness bar from/.expand once=#1, + /orm/uniqueness bar to/.expand once=#2, + /orm/uniqueness bar set roles/.expand once=\pgfmathresult, + /orm/uniqueness bar level=#3, + shape=uniqueness bar, + \orm@unique@bar@style, + minimum height=2.5mm, + /orm/uniqueness bar style + ]{} + \egroup + }}% + \fi% +} + +%% Skipped uniqueness bar +% TODO: remove this duplicated code. + +\tikzset{ + skip unique/.code={\orm@parse@sunique#1:\pgf@nil}, + skip unique/.default=1, +} + +% parses '<which>:<level>' and '<which>' +\def\orm@parse@sunique#1:#2\pgf@nil{% \def\orm@temp{#2}% \ifx\orm@temp\pgfutil@empty% - \orm@@parse@unique#1:1_1:\pgf@nil% + \orm@@parse@sunique#1:1:\pgf@nil% \else% - \orm@@parse@unique#1:1_#2\pgf@nil% + \orm@@parse@sunique#1:#2\pgf@nil% \fi% } -% parses n-m:l and n:l -\def\orm@@parse@unique#1:#2_#3:\pgf@nil{% +% parses n-m:<level> and n:<level> +\def\orm@@parse@sunique#1:#2:\pgf@nil{% \pgfutil@in@{-}{#1}% \ifpgfutil@in@% - \orm@parse@unique@@bar#1:#3_#2\pgf@nil% + \orm@parse@sunique@@bar#1:#2\pgf@nil% \else% - \orm@parse@unique@@bar#1-#1:#3_#2\pgf@nil% + \orm@parse@sunique@@bar#1-#1:#2\pgf@nil% \fi% } -% Appends a uniqueness bar at the current predicate node. -% -% #1 - from role (1,2,..) -% #2 - to role (1,2,..) -% #3 - level (above: 1,2,.., below: -1,-2,..) -% #4 - 1 if skipped, 0 otherwise -\def\orm@parse@unique@@bar#1-#2:#3_#4\pgf@nil{% +\def\orm@parse@sunique@@bar#1-#2:#3\pgf@nil{% \def\orm@tempA{#1}% \ifx\orm@tempA\pgfutil@empty% \relax% - \orm@parse@unique@@bar#2-#2:-1_#4\pgf@nil + \orm@parse@xunique@@bar#2-#2:-1\pgf@nil \else% - \tikzset{append after command={% - \bgroup% - [current point is local=true] - \pgfextra{% - \ifnum#4>0% - \let\orm@unique@bar@style=\orm@unique@bar@skipped% - \fi% - } - let - \n1 = {\orm@rolebar@xshifta{#1}}, - \n2 = {\orm@rolebar@xshiftb{#2}}, - \n3 = {\orm@rolebar@yshift{#3}}, - \p1 = ($(\tikzlastnode.west)!-\n3!-90:(\tikzlastnode.east)$), - \p2 = ($(\tikzlastnode.east)!-\n3!90:(\tikzlastnode.west)$) - in - ($(\p1)!\n1!(\p2)$) edge [\orm@unique@bar@style] ($(\p1)!\n2!(\p2)$) - \egroup% +\tikzset{append after command={ + \bgroup% + [current point is local=true] + let \p1 = (\tikzlastnode.west), \p2 = (\tikzlastnode.east) + in \pgfextra{\pgfmathparse{(\x2-\x1)/4mm}} + \pgfextra{\let\orm@unique@bar@style=\orm@unique@bar@skipped}% + (\tikzlastnode) node[ + /orm/uniqueness bar from/.expand once=#1, + /orm/uniqueness bar to/.expand once=#2, + /orm/uniqueness bar set roles/.expand once=\pgfmathresult, + /orm/uniqueness bar level=#3, + shape=uniqueness bar, + \orm@unique@bar@style, + minimum height=2.5mm + ]{} + \egroup }}% \fi% } +% TODO: add optional parameters and document this +\tikzstyle{preferred unique}=[unique=1:1,unique=1:2] + \makeatother %<–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––> |