4

From the tikz uml documentation I have this example.

enter image description here

If I used the umlsimpleclass the two rectangles below the class name wouldn't have be drawn. My question is... is there a way to have only the sections for data members or the sections for methods? It doesn't seem the documentation provides anything.

Update: the full view would be

enter image description here

For data members the syntax is visibility_attribute name : type, while the syntax for method is visibility_atribute name([name : type, name : type, ... ]) : return_type . That's the difference, what I want to achieve is removing one of the two sections, and keeping just one. Instead of doing both them or none of them.

Something like the "ParentClass" of the diagram below it's what I'm trying to achieve.

enter image description here

Some working code to hack:

\documentclass[tikz,14pt,border=10pt]{standalone}
\usepackage{verbatim}
\usepackage{tikz}
\usepackage{tikz-uml}
\usepackage{xcolor}
\usepackage{pgf-umlsd}
\usetikzlibrary{er}
\usetikzlibrary{decorations}
\usetikzlibrary{shapes,arrows}
\usetikzlibrary{shapes.misc}
\usetikzlibrary{positioning,calc}

\tikzstyle{int}=[draw, fill=blue!20, minimum size=3em]
\tikzstyle{init} = [pin edge={to-,thin,black}]

\begin{document}
\begin{tikzpicture} 
\umlclass{namespace::A} {
 + n : uint \\ \umlstatic{-- i : int} \\
    \# r : const float} {
    + setA(i : int) : void \\ \umlvirt{\# getA() : A}
}   
\end{tikzpicture}
\end{document}
  • 2
    For those of us not familiar with UML: what are the data members, what are the methods? (In other words, can you explain what you want to change about the graphic without using any UML-lingo?) – Torbjørn T. Aug 31 '17 at 15:10
  • I hope I clarified. – user8469759 Aug 31 '17 at 15:17
  • 1
    Not really, that was basically all UML-lingo ... I meant in relation to the diagram. Are you asking about how to remove one of the two lower rectangles? Ideally, post the code you have (as code, not as a screenshot), show the output of that code, and describe what you want change about the presentation. Perhaps make a mockup in Paint or similar showing what you want to achieve. – Torbjørn T. Aug 31 '17 at 15:28
  • Shall I show the picture basically of what I'm trying to do? – user8469759 Aug 31 '17 at 15:30
  • 1
    That would help, yes, as I have no idea what that is. But please post the code as well (a complete example, while you're at it). – Torbjørn T. Aug 31 '17 at 15:32
  • I don't actually see the problem with the UML-lingo anyway... given you have a tag "tikz-uml" I assumed people know what I'm talking about... – user8469759 Aug 31 '17 at 15:35
  • 1
    Sure, some people here might have understood you perfectly. I on the other hand know quite a bit TikZ, but zero about UML-stuff. So while I might be perfectly able to answer your question, that doesn't help if I don't understand what you mean. This is why I think it's always helpful to explain what you want to do in terms of the diagram itself, not in terms of the theory of what it represents. – Torbjørn T. Aug 31 '17 at 15:39
  • Added the code. – user8469759 Aug 31 '17 at 15:42
  • 1
    For the non-uml-speaker amongst us: Can your question be summarised with "draw one of the yellow boxes with only two rows"? – samcarter_is_at_topanswers.xyz Aug 31 '17 at 16:10

1 Answers1

4

So as I understand it, you want something like the following, without the bottom, empty rectangle.

output of first code block

\documentclass[tikz,border=10pt]{standalone}
\usepackage{tikz-uml}
\begin{document}
\begin{tikzpicture} 
\umlclass{foo}{bar}{}   
\end{tikzpicture}
\end{document}

At the heart of it, this is just a construct like

\node [
   fill=\tikzumlNoteDefaultFillColor,
   draw,
   rectangle split,
   rectangle split parts=3,
   every one node part/.style={font=\bfseries}
   ] {\nodepart{one} foo \nodepart{two} bar \nodepart{three} };

which looks like

what the above \node looks like

The quickest workaround is therefore actually this:

\documentclass[tikz,border=10pt]{standalone}
\usepackage{tikz-uml}
\begin{document}
\begin{tikzpicture} 
\umlclass[rectangle split parts=2]{foo}{bar}{}   
\end{tikzpicture}
\end{document}

output of the above code


Another approach is to make a new macro based on \umlclass, where rectangle split parts is set to 2, and the third \nodepart is removed. tikz-uml does a lot of stuff though. In the \umlfoobar macro defined below I've just done as little changes as possible. It works for the given example, but I don't know if there are cases where it might break.

output of last code blocl

\documentclass[tikz,border=10pt]{standalone}
\usepackage{tikz-uml}
\tikzset{tikzuml foobar style/.style={rectangle split, rectangle split parts=2, rectangle split part align={center, left, left}, minimum height=2em, node distance=2em}}

\makeatletter
%
\newcommand{\umlfoobar}[3][]{%
  \pgfkeys{/tikzuml/class/.cd, x/.initial=\tikzumlDefaultX, y/.initial=\tikzumlDefaultX, width/.initial=\tikzumlClassDefaultWidth, type/.initial=\tikzumlClassDefaultType,%
                               tags/.initial={}, style/.style={},%
                               template/.initial={}, name/.initial=tikzumlEmpty,%
                               draw/.initial=\tikzumlDefaultDrawColor,%
                               fill template/.initial=\tikzumlClassTemplateFillColorDefaultFillColor,%
                               fill/.initial=\tikzumlClassDefaultFillColor,%
                               text/.initial=\tikzumlDefaultTextColor,%
                               simple/.is if=tikzumlclassSimpleStyle, circle/.is if=tikzumlclassCircleShape, no coords/.is if=tikzumlclassWithoutCoords,%
                               simple=false, circle=false, no coords=false,%
                               .unknown/.code={%
                                 \let\keyname=\pgfkeyscurrentname%
                                 \let\keyvalue=\pgfkeyscurrentvalue%
                                 \ifthenelse{\equal{\keyname}{above}\OR%
                                             \equal{\keyname}{left}\OR%
                                             \equal{\keyname}{below}\OR%
                                             \equal{\keyname}{right}\OR%
                                             \equal{\keyname}{above left}\OR%
                                             \equal{\keyname}{above right}\OR%
                                             \equal{\keyname}{below left}\OR%
                                             \equal{\keyname}{below right}}{%
                                   \IfSubStr{\keyvalue}{ of }{%
                                     \pgfkeys{/tikzuml/class/.cd, no coords}%
                                   }{}%
                                 }{}%
                                 \ifx\keyvalue\pgfkeysnovalue%
                                   \pgfkeys{/tikzuml/class/.cd, style/.append style/.expand once={\keyname}}%
                                 \else%
                                   \pgfkeys{/tikzuml/class/.cd, style/.append style/.expand twice={\expandafter\keyname\expandafter=\keyvalue}}%
                                 \fi%
                                 %\errmessage{TIKZUML ERROR : in umlclass, invalid option \keyname}%
                               }%
  }%
  \pgfkeys{/tikzuml/class/.cd,#1}%
  %
  \iftikzumlclassSimpleStyle%
    \iftikzumlclassCircleShape%
      \pgfkeys{/tikzuml/class/.cd, width/.initial=\tikzumlSimpleInterfaceDefaultWidth}%
    \fi%
  \fi%
  %
  \pgfkeys{/tikzuml/class/.cd, x/.get=\tikzumlClassX, y/.get=\tikzumlClassY, width/.get=\tikzumlClassMinimumWidth,% 
                               type/.get=\tikzumlClassTypeTmp, tags/.get=\tikzumlClassTagsTmp, template/.get=\tikzumlClassTemplateFillColorParam,%
                               name/.get=\tikzumlClassName,%
                               draw/.get=\tikzumlClassDrawColor, fill/.get=\tikzumlClassFillColor,%
                               text/.get=\tikzumlClassTextColor, fill template/.get=\tikzumlClassTemplateFillColor%
  }%
  %
  \ifthenelse{\equal{\tikzumlClassTypeTmp}{class}\OR\equal{\tikzumlClassTypeTmp}{abstract}}{%
    \def\tikzumlClassType{}%
  }{%
    \expandafter\def\expandafter\tikzumlClassType\expandafter{$\ll$\tikzumlClassTypeTmp$\gg$ \\}%
  }%
  %
  \ifthenelse{\equal{\tikzumlClassTagsTmp}{}}{%
    \def\tikzumlClassTags{}%
  }{%
    \def\tikzumlClassTags{\\ \{\tikzumlClassTagsTmp\}}%
  }%
  %
  \ifthenelse{\equal{\tikzumlClassTemplateFillColorParam}{}}{%
    \def\tikzumlClassVPadding{}%
    \def\tikzumlClassHPadding{}%
  }{%
    \def\tikzumlClassVPadding{\vspace{0.1em} \\}%
    \def\tikzumlClassHPadding{\hspace{0.5ex} $ $}%
  }%
  %
  \def\tikzumlClassName{#2}%
  %
  \begingroup%
    \def\_{_}\edef\x{\endgroup%
      \def\noexpand\tikzumlClassNodeName{\tikzumlClassName}}\x%
  %
  \ifthenelse{\equal{\tikzumlClassName}{tikzumlEmpty}}{}{%
    \def\tikzumlClassNodeName{\tikzumlClassName}%
  }%
  %
  \StrSubstitute{\tikzumlClassNodeName}{:}{@COLON@}[\tikzumlClassNodeName]%
  \StrSubstitute{\tikzumlClassNodeName}{\_}{@UNDERSCORE@}[\tikzumlClassNodeName]%
  %
  \ifthenelse{\equal{\tikzumlClassTypeTmp}{abstract}}{%
    \let\tikzumlClassNameOld\tikzumlClassName%
    \def\tikzumlClassName{{\it \tikzumlClassNameOld}}%
  }{}%
  %
  \def\tikzumlClassPos{\tikzumlClassX,\tikzumlClassY}%
  \def\tikzumlClassAttributes{#3}%
%  \def\tikzumlClassOperations{}%
  %
  \iftikzumlclassSimpleStyle%
    \iftikzumlclassWithoutCoords%
      \iftikzumlclassCircleShape%
        \node[tikzuml simpleinterface style, draw=\tikzumlClassDrawColor, fill=\tikzumlClassFillColor, text=\tikzumlClassTextColor, font=\tikzumlDefaultFont, minimum width=\tikzumlClassMinimumWidth, /tikzuml/class/style] (\tikzumlClassNodeName) {};%
        \node[anchor=south] (\tikzumlClassNodeName-label) at (\tikzumlClassNodeName.north) {\begin{tabular}{c}\tikzumlClassVPadding \tikzumlClassType \tikzumlClassHPadding \textbf{\tikzumlClassName} \tikzumlClassHPadding \tikzumlClassTags \end{tabular}%
        };%
      \else%
        \node[tikzuml simpleclass style, draw=\tikzumlClassDrawColor, fill=\tikzumlClassFillColor, text=\tikzumlClassTextColor, font=\tikzumlDefaultFont, minimum width=\tikzumlClassMinimumWidth, /tikzuml/class/style] (\tikzumlClassNodeName) {\begin{tabular}{c}\tikzumlClassVPadding \tikzumlClassType \tikzumlClassHPadding \textbf{\tikzumlClassName} \tikzumlClassHPadding \tikzumlClassTags \end{tabular}%
        };%
      \fi%
    \else%
      \iftikzumlclassCircleShape%
        \node[tikzuml simpleinterface style, draw=\tikzumlClassDrawColor, fill=\tikzumlClassFillColor, text=\tikzumlClassTextColor, font=\tikzumlDefaultFont, minimum width=\tikzumlClassMinimumWidth, /tikzuml/class/style] (\tikzumlClassNodeName) at (\tikzumlClassPos) {};
        \node[anchor=south] (\tikzumlClassNodeName-label) at (\tikzumlClassNodeName.north){\begin{tabular}{c}\tikzumlClassVPadding \tikzumlClassType \tikzumlClassHPadding \textbf{\tikzumlClassName} \tikzumlClassHPadding \tikzumlClassTags \end{tabular}%
        };%
      \else%
        \node[tikzuml simpleclass style, draw=\tikzumlClassDrawColor, fill=\tikzumlClassFillColor, text=\tikzumlClassTextColor, font=\tikzumlDefaultFont, minimum width=\tikzumlClassMinimumWidth, /tikzuml/class/style] (\tikzumlClassNodeName) at (\tikzumlClassPos) {\begin{tabular}{c}\tikzumlClassVPadding \tikzumlClassType \tikzumlClassHPadding \textbf{\tikzumlClassName} \tikzumlClassHPadding \tikzumlClassTags \end{tabular}%
        };%
      \fi%
    \fi%
  \else%
    \iftikzumlclassWithoutCoords%
      \node[tikzuml foobar style, draw=\tikzumlClassDrawColor, fill=\tikzumlClassFillColor, text=\tikzumlClassTextColor, font=\tikzumlDefaultFont, minimum width=\tikzumlClassMinimumWidth, /tikzuml/class/style] (\tikzumlClassNodeName) {\begin{tabular}{c}\tikzumlClassVPadding \tikzumlClassType \tikzumlClassHPadding \textbf{\tikzumlClassName} \tikzumlClassHPadding \tikzumlClassTags \end{tabular}%
      \nodepart{second}%
      \begin{tabular}{l}%
      \tikzumlClassAttributes%
      \end{tabular}%
      };%
    \else%
      \node[tikzuml foobar style, draw=\tikzumlClassDrawColor, fill=\tikzumlClassFillColor, text=\tikzumlClassTextColor, font=\tikzumlDefaultFont, minimum width=\tikzumlClassMinimumWidth, /tikzuml/class/style] (\tikzumlClassNodeName) at (\tikzumlClassPos) {\begin{tabular}{c}\tikzumlClassVPadding \tikzumlClassType \tikzumlClassHPadding \textbf{\tikzumlClassName} \tikzumlClassHPadding \tikzumlClassTags \end{tabular}%
      \nodepart{second}%
      \begin{tabular}{l}%
      \tikzumlClassAttributes%
      \end{tabular}%
      };%
    \fi%
  \fi%
  %
  \ifthenelse{\equal{\tikzumlClassTemplateFillColorParam}{}}{}{%
    \draw (\tikzumlClassNodeName.north east) node[tikzuml template style, name=\tikzumlClassNodeName-template, draw=\tikzumlClassDrawColor, fill=\tikzumlClassTemplateFillColor, text=\tikzumlClassTextColor, font=\tikzumlDefaultFont] {\tikzumlClassTemplateFillColorParam};%
  }%
  %
  % add to fit
  \ifnum\c@tikzumlPackageLevel>0%
    \edef\tikzumlPackageFitOld{\csname tikzumlPackageFit\tikzumlPackage@parent @@\tikzumlPackage@fitname\endcsname}%
    \ifthenelse{\equal{\tikzumlClassTemplateFillColorParam}{}}{%
      \expandafter\xdef\csname tikzumlPackageFit\tikzumlPackage@parent @@\tikzumlPackage@fitname\endcsname{\tikzumlPackageFitOld (\tikzumlClassNodeName)}%
    }{%
      \expandafter\xdef\csname tikzumlPackageFit\tikzumlPackage@parent @@\tikzumlPackage@fitname\endcsname{\tikzumlPackageFitOld (\tikzumlClassNodeName) (\tikzumlClassNodeName-template)}%
    }%
    \stepcounter{tikzumlPackageClassNum}%
  \fi%
  \ifnum\c@tikzumlComponentLevel>0%
    \def\tikzumlComponentFitTmp{\csname tikzumlComponentFit\tikzumlComponent@parent @@\tikzumlComponent@fitname\endcsname}%
    \ifthenelse{\equal{\tikzumlClassTemplateFillColorParam}{}}{%
      \expandafter\xdef\csname tikzumlComponentFit\tikzumlComponent@parent @@\tikzumlComponent@fitname\endcsname{\tikzumlComponentFitTmp (\tikzumlClassNodeName)}%
    }{%
      \expandafter\xdef\csname tikzumlComponentFit\tikzumlComponent@parent @@\tikzumlComponent@fitname\endcsname{\tikzumlComponentFitTmp (\tikzumlClassNodeName) (\tikzumlClassNodeName-template)}%
    }%
    \stepcounter{tikzumlComponentSubComponentNum}%
  \fi%
}
\makeatother
\begin{document}
\begin{tikzpicture} 
\umlfoobar{foo}{bar}
\umlfoobar[x=4]{foo2}{bar}
\umlclass[x=2,y=-2]{foo}{bar}{baz}
\end{tikzpicture}
\end{document}
Torbjørn T.
  • 206,688
  • So basically I have to create a new command for that, is that right? how do I keep the properties I described above? you kept the rectangle, which is fine, but of course I'd like to keep their meaning as well. – user8469759 Sep 01 '17 at 09:10
  • @user8469759 How is the meaning communicated in the diagram? What is it you need to keep? Both the second and third mandatory argument to \umlclass (called respectively "attributes" and "operation" in the code) is handled exactly the same way: saved in a macro with e.g. \def\tikzumlClassAttributes{#3}, and that macro is later used inside a tabular (\begin{tabular}{l} \tikzumlClassAttributes \end{tabular}) which is placed inside a TikZ node. – Torbjørn T. Sep 01 '17 at 09:23
  • @user8469759 Of course you can choose to rename macros so that they are semantically correct. – Torbjørn T. Sep 01 '17 at 09:27
  • by meaning I meant attributes with identifiers etc, or methods with identifiers etc (in terms of the syntax I exposed above). – user8469759 Sep 01 '17 at 10:26
  • @user8469759 I still don't understand how that is supposed to be reflected in the code, apart from perhaps the inputs to the macro. – Torbjørn T. Sep 01 '17 at 10:30
  • Could you kindly add the code that realizes the class namespace::a in my original post without the method section for example? – user8469759 Sep 01 '17 at 10:40
  • @user8469759 I don't get it, isn't that precisely what I've done? And you still haven't said in plain English what the methods section is. – Torbjørn T. Sep 01 '17 at 12:28