# \unidirectionalAssociation usage problem in pgf-umlcd?

I use pgf-umlcd manual as manual to create uml diagrum. But, when I use \unidirectionalAssociation command there occurs a problem.
My code here -

\documentclass{article}
\usepackage{pgf-umlcd}
\usepackage[a4paper,textwidth=8in]{geometry}
\begin{document}
\begin{tikzpicture}

\begin{class}{VocabularyObserver}{-3, -6}
\attribute{\# vocabulary : Vocabulary}
\operation{\# update(word : String) : void}
\end{class}

\begin{class}[text width = 12 cm]{Vocabulary}{-3,-10}
\attribute{- vocabularyObservers : List<VocabularyObserver>}
\attribute{+ MAXWORD : int}
\attribute{+ wordCounter : int}
\attribute{+ wordList : String[]}
\operation{+ addWord() : Boolean}
\operation{+ addObservers(vocabularyObserver : VocabularyObserver) : void}
\operation{- notifyAllObservers(word : String) : void}
\end{class}
\unidirectionalAssociation{uses}{VocabularyObserver}{0..*}{Vocabulary}
\end{tikzpicture}
\end{document}


compilation error is here -

*geometry* driver: auto-detecting
*geometry* detected driver: pdftex

! Package pgf Error: No shape named uses is known.

See the pgf package documentation for explanation.
Type  H <return>  for immediate help.
...

l.21 ...ses}{VocabularyObserver}{0..*}{Vocabulary}

?


How can I solve this problem?

• Shouldn't it be at least within tikzpicture? – TeXnician Aug 31 '17 at 4:24
• @TeXnician I put it within tikzpicture. Now the error is *geometry* driver: auto-detecting *geometry* detected driver: pdftex ! Package pgf Error: No shape named uses is known. See the pgf package documentation for explanation. Type H <return> for immediate help. ... l.21 ...ses}{VocabularyObserver}{0..*}{Vocabulary} ? – alhelal Aug 31 '17 at 5:22
• The first argument has to be the first class, the last argument the second class and in between the description and the relation. You mixed it up. – TeXnician Aug 31 '17 at 5:25
• @TeXnician this works, but the description shown on the association line. thanks. – alhelal Aug 31 '17 at 5:28
• What do you mean with "but the description shown on the association line"? – TeXnician Aug 31 '17 at 5:32

## 1 Answer

As TeXnician said, the reason you're getting the error is that your arguments to \unidirectionalAssociation is in the wrong order. You should have

\unidirectionalAssociation{<name of first class>}{<text above>}{<text below>}{<name of second class>}


but what you have is

\unidirectionalAssociation{<text above>}{<name of first class>}{<text below>}{<name of second class>}


The reason you're getting the text on top of the line is the definition of \unidirectionalAssociation, which seems to be designed with only horizontal lines in mind, as the two nodes are placed above and below, respectively.

A more general approach would be

\renewcommand{\unidirectionalAssociation}[4]{
\draw [umlcd style, ->] (#1) -- (#4)
node[near end, auto]{#2}
node[near end, auto,swap]{#3};
}


where above has been replaced with auto, and below with auto,swap. With this definition it will work for lines with other orientations as well, as seen from the example below. (The two demo classes are there purely to demonstrate this.)

\documentclass{article}
\usepackage{pgf-umlcd}
\usepackage[a4paper,textwidth=8in]{geometry}

\renewcommand{\unidirectionalAssociation}[4]{
\draw [umlcd style, ->] (#1) -- (#4)
node[near end, auto]{#2}
node[near end, auto,swap]{#3};
}
\begin{document}
\begin{tikzpicture}

\begin{class}{demo}{-10, -6}
\attribute{foo}
\operation{bar}
\end{class}

\begin{class}{demo2}{-12, -10}
\attribute{foo2}
\operation{bar2}
\end{class}

\begin{class}{VocabularyObserver}{-3, -6}
\attribute{\# vocabulary : Vocabulary}
\operation{\# update(word : String) : void}
\end{class}

\begin{class}[text width = 12 cm]{Vocabulary}{-3,-10}
\attribute{- vocabularyObservers : List<VocabularyObserver>}
\attribute{+ MAXWORD : int}
\attribute{+ wordCounter : int}
\attribute{+ wordList : String[]}
\operation{+ addWord() : Boolean}
\operation{+ addObservers(vocabularyObserver : VocabularyObserver) : void}
\operation{- notifyAllObservers(word : String) : void}
\end{class}
\unidirectionalAssociation{VocabularyObserver}{uses}{0..*}{Vocabulary}

\unidirectionalAssociation{demo}{bar}{baz}{VocabularyObserver}
\unidirectionalAssociation{demo2}{here}{there}{VocabularyObserver}
\end{tikzpicture}
\end{document}

• I intent to edit the "pgf-umlcd.sty" file with this style so that for all uml it acts same. but I don't understand why first position is auto and second is both auto and swap. – alhelal Sep 15 '17 at 13:41
• @BandaMuhammadAlHelal auto places the node on the left side of the line (if you look from the start point to the end point), auto,swap places it on the right side. Without swap the two nodes would be placed in the same place. – Torbjørn T. Sep 15 '17 at 13:48
• From where you know the option auto and swap? I was motivated to change "pgf-umlcd.sty" by your comment on another my question – alhelal Sep 15 '17 at 13:49
• @alhelal 1) \draw [umlcd style,->] (WindowManagerApplication) -- node[above]{<<instantiate>>} (WindowManager); puts it in the middle. 2) \unidirectionalAssociation doesn't put those labels in the middle of the line. If you want it to do that, you have to redefine it somehow. 3) You could possibly use an ugly hack like \unidirectionalAssociation{WindowManagerApplication}{$<<$ins‌​tantiate$>>$ \hspace{1cm}\null}{}{Wind‌​owManager}. 4) If you have a lot of these, making a new macro might be worthwhile. – Torbjørn T. Oct 20 '17 at 6:08
• @alhelal Relative to the previous coordinate. If a is at (1,2) and b is at (3,1), when you do \draw (a) -- ++(b); the endpoint is at (4,3), not at (3,1). – Torbjørn T. Oct 21 '17 at 12:56