1

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?

alhelal
  • 2,451

1 Answers1

2

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.)

output of code

\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}
Torbjørn T.
  • 206,688
  • 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
  • @BandaMuhammadAlHelal The TikZ manual ... – Torbjørn T. Sep 15 '17 at 13:50
  • by your comment I learned a great things of LaTeX. thank you. – alhelal Sep 15 '17 at 13:52
  • I edit my pgf-umlcd.sty file, it works well. thanks. – alhelal Sep 15 '17 at 14:09
  • how to put level in middle from each node in pgf-umlcd? I do this \unidirectionalAssociation{WindowManagerApplication}{$<<$instantiate$>>$}{}{WindowManager} that result this – alhelal Oct 19 '17 at 10:03
  • @alhelal You should be able to work that out given the info I've provided in some of your other questions I think. \draw [umlcd style,->] (WindowManagerApplication) -- node[above]{instantiate} (WindowManager); The \unidirectionalAssociation macro just isn't very flexible as it is defined, the position of the two nodes that hold the text you provide in the second and third argument is fixed at near end, and to modify that the macro has to be rewritten somehow. – Torbjørn T. Oct 19 '17 at 10:16
  • I didn't understand your comment. Can I shift the <<instantiate>> left so that it doesn't overlap WindowManager? – alhelal Oct 20 '17 at 02:45
  • 1
    @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 06:08
  • Why does \draw[umlcd style] (WindowManagerApplication.south) -- ++(DesignFactory.north) give unexpected line? – alhelal Oct 21 '17 at 12:44
  • @alhelal Because of the ++, which indicates relative coordinates. Remove the ++. (Probably, I haven’t tested.) – Torbjørn T. Oct 21 '17 at 12:46
  • Isn't it relative coordinates? when I will change the position of DesignFactory the line will be changed? – alhelal Oct 21 '17 at 12:49
  • 1
    @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
  • why this results ! Package tikz Error: Giving up on this path. Did you forget a semicolon?. I tried long time but didn't find any error. – alhelal Oct 28 '17 at 05:44
  • @alhelal Ask a new question, and include a code example. – Torbjørn T. Oct 28 '17 at 07:34