| 1 | # @mermaid-js/mermaid-zenuml |
| 2 | |
| 3 | MermaidJS plugin for ZenUML integration - A powerful sequence diagram rendering engine. |
| 4 | |
| 5 | > A Sequence diagram is an interaction diagram that shows how processes operate with one another and in what order. |
| 6 | |
| 7 | Mermaid can render sequence diagrams with [ZenUML](https://zenuml.com). Note that ZenUML uses a different |
| 8 | syntax than the original Sequence Diagram in mermaid. |
| 9 | |
| 10 | ```mermaid |
| 11 | zenuml |
| 12 | BookLibService.Borrow(id) { |
| 13 | User = Session.GetUser() |
| 14 | if(User.isActive) { |
| 15 | try { |
| 16 | BookRepository.Update(id, onLoan, User) |
| 17 | receipt = new Receipt(id, dueDate) |
| 18 | } catch (BookNotFoundException) { |
| 19 | ErrorService.onException(BookNotFoundException) |
| 20 | } finally { |
| 21 | Connection.close() |
| 22 | } |
| 23 | } |
| 24 | return receipt |
| 25 | } |
| 26 | ``` |
| 27 | |
| 28 | ## Installation |
| 29 | |
| 30 | ### With bundlers |
| 31 | |
| 32 | ```sh |
| 33 | npm install @mermaid-js/mermaid-zenuml |
| 34 | ``` |
| 35 | |
| 36 | ```ts |
| 37 | import mermaid from 'mermaid'; |
| 38 | import zenuml from '@mermaid-js/mermaid-zenuml'; |
| 39 | |
| 40 | await mermaid.registerExternalDiagrams([zenuml]); |
| 41 | ``` |
| 42 | |
| 43 | ### With CDN |
| 44 | |
| 45 | ```html |
| 46 | <script type="module"> |
| 47 | import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs'; |
| 48 | import zenuml from 'https://cdn.jsdelivr.net/npm/@mermaid-js/mermaid-zenuml@0.2.0/dist/mermaid-zenuml.core.mjs'; |
| 49 | await mermaid.registerExternalDiagrams([zenuml]); |
| 50 | </script> |
| 51 | ``` |
| 52 | |
| 53 | > [!NOTE] |
| 54 | > ZenUML uses experimental lazy loading & async rendering features which could change in the future. |
| 55 | |
| 56 | ## Basic Usage |
| 57 | |
| 58 | Once the plugin is registered, you can create ZenUML diagrams using the `zenuml` syntax: |
| 59 | |
| 60 | ```mermaid |
| 61 | zenuml |
| 62 | Controller.Get(id) { |
| 63 | Service.Get(id) { |
| 64 | item = Repository.Get(id) |
| 65 | if(item) { |
| 66 | return item |
| 67 | } else { |
| 68 | return null |
| 69 | } |
| 70 | } |
| 71 | return result |
| 72 | } |
| 73 | ``` |
| 74 | |
| 75 | ## ZenUML Syntax Reference |
| 76 | |
| 77 | ### Participants |
| 78 | |
| 79 | The participants can be defined implicitly as in the first example on this page. The participants or actors are |
| 80 | rendered in order of appearance in the diagram source text. Sometimes you might want to show the participants in a |
| 81 | different order than how they appear in the first message. It is possible to specify the actor's order of |
| 82 | appearance by doing the following: |
| 83 | |
| 84 | ```mermaid |
| 85 | zenuml |
| 86 | title Declare participant (optional) |
| 87 | Bob |
| 88 | Alice |
| 89 | Alice->Bob: Hi Bob |
| 90 | Bob->Alice: Hi Alice |
| 91 | ``` |
| 92 | |
| 93 | ### Annotators |
| 94 | |
| 95 | If you specifically want to use symbols instead of just rectangles with text you can do so by using the annotator syntax to declare participants as per below. |
| 96 | |
| 97 | ```mermaid |
| 98 | zenuml |
| 99 | title Annotators |
| 100 | @Actor Alice |
| 101 | @Database Bob |
| 102 | Alice->Bob: Hi Bob |
| 103 | Bob->Alice: Hi Alice |
| 104 | ``` |
| 105 | |
| 106 | Available annotators include: |
| 107 | |
| 108 | - `@Actor` - Human figure |
| 109 | - `@Database` - Database symbol |
| 110 | - `@Boundary` - Boundary symbol |
| 111 | - `@Control` - Control symbol |
| 112 | - `@Entity` - Entity symbol |
| 113 | - `@Queue` - Queue symbol |
| 114 | |
| 115 | ### Aliases |
| 116 | |
| 117 | The participants can have a convenient identifier and a descriptive label. |
| 118 | |
| 119 | ```mermaid |
| 120 | zenuml |
| 121 | title Aliases |
| 122 | A as Alice |
| 123 | J as John |
| 124 | A->J: Hello John, how are you? |
| 125 | J->A: Great! |
| 126 | ``` |
| 127 | |
| 128 | ## Messages |
| 129 | |
| 130 | Messages can be one of: |
| 131 | |
| 132 | 1. Sync message |
| 133 | 2. Async message |
| 134 | 3. Creation message |
| 135 | 4. Reply message |
| 136 | |
| 137 | ### Sync message |
| 138 | |
| 139 | You can think of a sync (blocking) method in a programming language. |
| 140 | |
| 141 | ```mermaid |
| 142 | zenuml |
| 143 | title Sync message |
| 144 | A.SyncMessage |
| 145 | A.SyncMessage(with, parameters) { |
| 146 | B.nestedSyncMessage() |
| 147 | } |
| 148 | ``` |
| 149 | |
| 150 | ### Async message |
| 151 | |
| 152 | You can think of an async (non-blocking) method in a programming language. Fire an event and forget about it. |
| 153 | |
| 154 | ```mermaid |
| 155 | zenuml |
| 156 | title Async message |
| 157 | Alice->Bob: How are you? |
| 158 | ``` |
| 159 | |
| 160 | ### Creation message |
| 161 | |
| 162 | We use `new` keyword to create an object. |
| 163 | |
| 164 | ```mermaid |
| 165 | zenuml |
| 166 | new A1 |
| 167 | new A2(with, parameters) |
| 168 | ``` |
| 169 | |
| 170 | ### Reply message |
| 171 | |
| 172 | There are three ways to express a reply message: |
| 173 | |
| 174 | ```mermaid |
| 175 | zenuml |
| 176 | // 1. assign a variable from a sync message. |
| 177 | a = A.SyncMessage() |
| 178 | |
| 179 | // 1.1. optionally give the variable a type |
| 180 | SomeType a = A.SyncMessage() |
| 181 | |
| 182 | // 2. use return keyword |
| 183 | A.SyncMessage() { |
| 184 | return result |
| 185 | } |
| 186 | |
| 187 | // 3. use @return or @reply annotator on an async message |
| 188 | @return |
| 189 | A->B: result |
| 190 | ``` |
| 191 | |
| 192 | The third way `@return` is rarely used, but it is useful when you want to return to one level up. |
| 193 | |
| 194 | ```mermaid |
| 195 | zenuml |
| 196 | title Reply message |
| 197 | Client->A.method() { |
| 198 | B.method() { |
| 199 | if(condition) { |
| 200 | return x1 |
| 201 | // return early |
| 202 | @return |
| 203 | A->Client: x11 |
| 204 | } |
| 205 | } |
| 206 | return x2 |
| 207 | } |
| 208 | ``` |
| 209 | |
| 210 | ## Advanced Features |
| 211 | |
| 212 | ### Nesting |
| 213 | |
| 214 | Sync messages and Creation messages are naturally nestable with `{}`. |
| 215 | |
| 216 | ```mermaid |
| 217 | zenuml |
| 218 | A.method() { |
| 219 | B.nested_sync_method() |
| 220 | B->C: nested async message |
| 221 | } |
| 222 | ``` |
| 223 | |
| 224 | ### Comments |
| 225 | |
| 226 | It is possible to add comments to a sequence diagram with `// comment` syntax. |
| 227 | Comments will be rendered above the messages or fragments. Comments on other places |
| 228 | are ignored. Markdown is supported. |
| 229 | |
| 230 | ```mermaid |
| 231 | zenuml |
| 232 | // a comment on a participant will not be rendered |
| 233 | BookService |
| 234 | // a comment on a message. |
| 235 | // **Markdown** is supported. |
| 236 | BookService.getBook() |
| 237 | ``` |
| 238 | |
| 239 | ### Loops |
| 240 | |
| 241 | It is possible to express loops in a ZenUML diagram. This is done by any of the |
| 242 | following notations: |
| 243 | |
| 244 | 1. while |
| 245 | 2. for |
| 246 | 3. forEach, foreach |
| 247 | 4. loop |
| 248 | |
| 249 | ```zenuml |
| 250 | while(condition) { |
| 251 | ...statements... |
| 252 | } |
| 253 | ``` |
| 254 | |
| 255 | Example: |
| 256 | |
| 257 | ```mermaid |
| 258 | zenuml |
| 259 | Alice->John: Hello John, how are you? |
| 260 | while(true) { |
| 261 | John->Alice: Great! |
| 262 | } |
| 263 | ``` |
| 264 | |
| 265 | ### Alt (Alternative paths) |
| 266 | |
| 267 | It is possible to express alternative paths in a sequence diagram. This is done by the notation |
| 268 | |
| 269 | ```zenuml |
| 270 | if(condition1) { |
| 271 | ...statements... |
| 272 | } else if(condition2) { |
| 273 | ...statements... |
| 274 | } else { |
| 275 | ...statements... |
| 276 | } |
| 277 | ``` |
| 278 | |
| 279 | Example: |
| 280 | |
| 281 | ```mermaid |
| 282 | zenuml |
| 283 | Alice->Bob: Hello Bob, how are you? |
| 284 | if(is_sick) { |
| 285 | Bob->Alice: Not so good :( |
| 286 | } else { |
| 287 | Bob->Alice: Feeling fresh like a daisy |
| 288 | } |
| 289 | ``` |
| 290 | |
| 291 | ### Opt (Optional) |
| 292 | |
| 293 | It is possible to render an `opt` fragment. This is done by the notation |
| 294 | |
| 295 | ```zenuml |
| 296 | opt { |
| 297 | ...statements... |
| 298 | } |
| 299 | ``` |
| 300 | |
| 301 | Example: |
| 302 | |
| 303 | ```mermaid |
| 304 | zenuml |
| 305 | Alice->Bob: Hello Bob, how are you? |
| 306 | Bob->Alice: Not so good :( |
| 307 | opt { |
| 308 | Bob->Alice: Thanks for asking |
| 309 | } |
| 310 | ``` |
| 311 | |
| 312 | ### Parallel |
| 313 | |
| 314 | It is possible to show actions that are happening in parallel. |
| 315 | |
| 316 | This is done by the notation |
| 317 | |
| 318 | ```zenuml |
| 319 | par { |
| 320 | statement1 |
| 321 | statement2 |
| 322 | statement3 |
| 323 | } |
| 324 | ``` |
| 325 | |
| 326 | Example: |
| 327 | |
| 328 | ```mermaid |
| 329 | zenuml |
| 330 | par { |
| 331 | Alice->Bob: Hello guys! |
| 332 | Alice->John: Hello guys! |
| 333 | } |
| 334 | ``` |
| 335 | |
| 336 | ### Try/Catch/Finally (Break) |
| 337 | |
| 338 | It is possible to indicate a stop of the sequence within the flow (usually used to model exceptions). |
| 339 | |
| 340 | This is done by the notation |
| 341 | |
| 342 | ``` |
| 343 | try { |
| 344 | ...statements... |
| 345 | } catch { |
| 346 | ...statements... |
| 347 | } finally { |
| 348 | ...statements... |
| 349 | } |
| 350 | ``` |
| 351 | |
| 352 | Example: |
| 353 | |
| 354 | ```mermaid |
| 355 | zenuml |
| 356 | try { |
| 357 | Consumer->API: Book something |
| 358 | API->BookingService: Start booking process |
| 359 | } catch { |
| 360 | API->Consumer: show failure |
| 361 | } finally { |
| 362 | API->BookingService: rollback status |
| 363 | } |
| 364 | ``` |
| 365 | |
| 366 | ## Contributing |
| 367 | |
| 368 | This package is part of the [Mermaid](https://github.com/mermaid-js/mermaid) project. See the main repository for contributing guidelines. |
| 369 | |
| 370 | ## Contributors |
| 371 | |
| 372 | - [Peng Xiao](https://github.com/MrCoder) |
| 373 | - [Sidharth Vinod](https://sidharth.dev) |
| 374 | - [Dong Cai](https://github.com/dontry) |
| 375 | |
| 376 | ## License |
| 377 | |
| 378 | MIT |
| 379 | |
| 380 | ## Links |
| 381 | |
| 382 | - [ZenUML Official Website](https://zenuml.com) |
| 383 | - [Mermaid Documentation](https://mermaid.js.org) |
| 384 | - [GitHub Repository](https://github.com/mermaid-js/mermaid) |
| 385 | |