UML Sequence Diagram
To create a UML sequence diagram, one uses the sequenceDiagram diagram function:
sequenceDiagram {
// define elements
}In contrast to the other diagram types, the elements of a sequence diagram are not positioned by hand. Since a sequence diagram models when (and where) something happens, it is defined in the order in which it happens: participants are placed on the x axis in the order in which they are declared, and everything else is placed on the y axis in the order in which it is declared. In other words: order matters. The diagram always knows only the currently available information and nothing on top, which is what makes sequence diagrams defined in HyLiMo maintainable: inserting an interaction moves everything after it down, without having to touch a single coordinate.
Terminology
In a sequence diagram, we have the following concepts:
- Participant: a component that "participates" in the diagram, so something/someone whose behavior should be modeled. It can be a
participant, aninstance, anactoror acomponent - Lifeline: the entire duration a participant is alive, symbolized by the dotted line downwards
- Activity indicator: the time a participant is active, visualized by a white rectangle on the lifeline
- Message: arrow between two participants at specific y positions with a semantic meaning
- Frame: a box around a section of the diagram. Can optionally contain a name (i.e.
if,while), and sub compartments (fragments)
Elements
All participants are declared first, in the order in which they should appear from left to right:
Participant names are registered as variables if they did not exist already. In case they existed already, the existing name takes precedence. If their name is already used by something else, you can assign the result of these functions to a variable of your own choosing:
participant
Creates a participant, which is an abstract concept of someone who participates in the diagram. The name is not underlined, and it can be given a class name, which is rendered as name:Class:
params:
- 0: the optional name of the participant, if not given, the second parameter must be provided
- 1: the optional class name of this participant
- 2: the callback function of this participant
keywords: the keywords of the participantbelow: the optional participant below which this participant should be placed. If set, this participant will have the same x coordinate as the given value and the y coordinate of the current positionat: the absolute y position where to create the participant. If set, takes priority overafterafter: the relative y offset from the current position. Only used ifatis not setmargin: horizontal margin between this and the previous participant. Defaults toparticipantMargin
returns: The created participant
With at and after, the creation of a participant can be postponed, which is how object creation is expressed:
instance
Creates an instance, a participant with an underlined name and support for values:
params:
- 0: the optional name of the instance, if not given, the second parameter must be provided
- 1: the optional class name of this instance
- 2: the callback function of this instance
keywords: the keywords of the instancebelow: the optional participant below which this instance should be placed. If set, this instance will have the same x coordinate as the given value and the y coordinate of the current positionat: the absolute y position where to create the instance. If set, takes priority overafterafter: the relative y offset from the current position. Only used ifatis not setmargin: horizontal margin between this and the previous instance. Defaults toparticipantMargin
returns: The created instance
actor
Creates a stickman figure symbolizing a user:
params:
- 0: the name of the actor
- 1: the optional class name of this actor, or a function that sets the instance values of this actor, making this actor instanced
- 2: the callback function of this actor
keywords: the keywords of the actorbelow: the optional participant below which this actor should be placed. If set, this actor will have the same x coordinate as the given value and the y coordinate of the current positionat: the absolute y position where to create the actor. If set, takes priority overafterafter: the relative y offset from the current position. Only used ifatis not setmargin: horizontal margin between this and the previous actor. Defaults toparticipantMargin
returns: The created actor
Instanced actors
An actor can be seen as an instance too if you need it to. In this case, the actor is an instance with a stickman on top. To build an instanced actor, pass the function declaring the instance values as second parameter:
The stickman can then be styled/layouted using actor-element. To access the created instance, use <return value>.instance.
component
Creates a component as a participant, see UML Component Diagram:
comment
Creates a comment, see UML Class Diagram. As a comment is not part of the sequence itself, it is positioned manually:
frame
Creates a frame, a rectangle containing a section of the diagram, optionally with a text naming it and a subtext for further explanation. To declare a frame, you provide a callback function that contains the interactions within the frame. The frame automatically determines its height based on the current position after the callback executes.
The frame also automatically determines its width by detecting which participants are used within it (through activations, messages, subframes, etc.). You can optionally override this by explicitly specifying left and right.
The frame automatically includes Alice and Bob based on the interactions within it.
params:
- 0: The text to display in the upper-left corner
- 1: A function generating all fragments (additional compartments within the frame)
subtext: The text to display right of the main text, i.e. a condition for an if or whileat: The absolute y position marking the upper border of the frame. If set, takes priority overafterafter: The relative y offset from the current position for the top border. Only used ifatis not setright: The participant marking the right border of the frame. The border will be extended bymarginRightto the right. Optional if a callback is providedleft: The participant marking the left border of the frame. The border will be extended bymarginLeftto the left. Optional if a callback is providedmarginLeft: How much margin to use on the left. Defaults to the configframeMarginXmarginRight: How much margin to use on the right. Defaults to the configframeMarginXmarginBottom: How much margin to use on the bottom. Defaults to the configframeMarginBottomsubtextMargin: the horizontal margin for the subtext label. Defaults to the configframeSubtextMargin
returns: The created frame
If no callback is provided, you must specify the bottom of the frame with bottomAt or bottomAfter, and its width with left and right.
fragment
A frame can contain multiple fragments. A fragment is a separate section inside the frame, i.e. an else for an if or different parallel branches. Fragments are created by calling the fragment function within the frame's callback, and are only available there:
params:
- 0: The text to display right of the main text, i.e. a condition for an else if
at: the absolute y position where to start the fragment. If set, takes priority overafterafter: the relative y offset from the current position. Only used ifatis not setsubtextMargin: the horizontal margin for the subtext label. Defaults to the configframeSubtextMargin
returns: The created fragment
Nested frames
You can nest frames by simply placing one frame inside another's callback function. Both frames will automatically detect their width based on the participants used:
Manual frame width specification
If you need precise control over which participants are included in a frame, you can manually specify left and right. This is useful when you want to include participants that aren't directly interacted with:
Frames as per the UML standard
The UML specification recommends the following frames, all of which are created by passing their name as the first argument:
alt: alternatives, one fragment per branch, of which the one whose condition holds is executed. Represents anif/else if/elseopt: an optional section, which is only executed if its condition holds. Represents anifwithout anelseloop: a section which is executed as long as its condition holds. Represents a loop, which can be left early with a nestedbreakframepar: a frame whose fragments are executed in parallelref: a reference to another sequence diagram, or to another part of this one. Represents a method call
A loop frame with a nested break frame, which leaves the loop when its condition holds:
A par frame, whose fragments are executed in parallel:
A ref frame, which refers to another sequence diagram:
Positioning
The y axis is managed automatically by HyLiMo as you add interactions to your diagram. Each interaction (like activate, message sending, or frame creation) has a margin that determines its vertical spacing:
- By default, each element uses a configurable margin that is applied after the element (see Config properties for available margin settings)
- The actual margin depends on the next declared element - different elements cause different margins to be used
- Use
atto specify an absolute y position, completely overriding the automatic margin calculation - Use
afterto specify a relative offset that is added to the default margin
delay and moveTo
delay moves the current position down by a relative offset, moveTo moves it to an absolute y position:
params:
- 0: the relative y offset from the current position (
delay), respectively the absolute y position to move to (moveTo)
returns: void
participant.at and participant.after
Sometimes, you want to send messages at specific positions or with time delays. participant.at(position) creates a virtual participant at an absolute y position, and participant.after(offset) creates one at a relative offset from the current position. Both can be used to create messages to arbitrary points in time:
params:
- 0: the absolute y position where to pinpoint the participant (
at), respectively the offset from the current position (after). Ifatis called without a position, the participant itself is used, positioned at its declaring position
returns: the new virtual participant to use for i.e. messages
Activity indicators
An activity indicator is the white rectangle on a lifeline marking the time a participant is active. HyLiMo automatically infers where to place the arrow between participants sending/receiving a message: in general, a sent message is sent on the right and a received message is received on the left side of the activity indicator.
activate
Activates an activity indicator at a calculated position:
params:
- 0: the participant (instance or actor) to activate
- 1: optional callback function to execute within this activation. After execution, deactivate is called automatically
at: the absolute y position where to activate. If set, takes priority overafterafter: the relative y offset from the current position. Only used ifatis not setxShift: an optional shift on the x-axis when using multiple activity indicators simultaneously on the same participant. Defaults toactivityShift
returns: The created activity indicator
You can activate multiple indicators simultaneously for the same participant, using after to add spacing between the activations:
With the callback function, the indicator is deactivated automatically once the callback has been executed:
deactivate
Deactivates the most recent activity indicator of a participant at a calculated position.
params:
- 0: the participant to deactivate
at: the absolute y position where to deactivate. If set, takes priority overafterafter: the relative y offset from the current position. Only used ifatis not set
returns: nothing
Destroying participants
destroy
Destroys a participant at a calculated position, which ends its lifeline with a cross:
params:
- 0: the participant to destroy
at: the absolute y position where to destroy. If set, takes priority overafterafter: the relative y offset from the current position. Only used ifatis not setcrossSize: the size of the cross to draw. Defaults todestroyingCrossSize
returns: the created cross
A destroyed participant can be reanimated by creating a new participant below it:
Messages
The following messages are available within sequence diagrams (in both directions, of course):
Labels
Oftentimes, you want to display text on a message. To do this in HyLiMo you can use the following construct (not exclusive to sequence diagrams, works in every other diagram as well):
lostMessage and foundMessage
A lost message is one you sent to a participant not included within the diagram, a found message is one you received from such a participant. Both are exactly the same, the meaning comes from the direction in which you declare the message, and both should always be used inline:
params:
distance: the optional distance of the message on the x axis. Defaults toexternalMessageMargin
returns: The created lost / found message to be used with a message operator
Config properties
The following config properties are available for sequence diagrams:
| Variable | Meaning | Default value (in pixels) | Comment |
|---|---|---|---|
activityShift | How far on the x axis subsequent simultaneously active activity indicators on the same participant are shifted | 3 | - |
activityWidth | How wide an activity indicator should be | 10 | - |
minActivityHeight | Minimum height of an activity indicator | 10 | - |
strokeMargin | Margin for strokes | 1 | - |
connectionMargin | Default distance required after a connection between participants | 20 | - |
deactivateMargin | Default distance required after a deactivation | 10 | - |
destroyingCrossSize | The width and height of a participant-destruction cross | 20 | - |
externalMessageDiameter | Width and height of the circle of lost and found messages | 20 | - |
frameMargin | Default distance required after a frame | 20 | - |
fragmentMargin | Default distance required after a fragment | 20 | - |
externalMessageMargin | How far away on the x axis a lost or found message should be drawn | 95 | 100-(0.5*activityWidth), chosen so that it aligns on the grid when sending a message against one activity indicator |
frameMarginX | Default margin to apply on the left and right side of frames | 15 | - |
frameMarginTop | Default margin to apply on the top of frames | 30 | - |
frameMarginBottom | Default margin to apply on the bottom of frames | 5 | - |
frameSubtextMargin | Default horizontal margin for frame subtexts | 10 | - |
eventDefaultMargin | Default margin for events on a participant when no other margin is specified | 5 | - |
participantMargin | How far apart subsequent participants should be | 200 | Multiple of 100 to align participants on the grid |
initialMargin | Default distance required after a new participant | 20 | - |
Available class names
The following class names are available for styling/layout purposes within sequence diagrams:
activity-indicator-elementto layout activity indicator elementsactivity-indicatorto style activity indicatorsactor-elementto layout actorsactorto style actorsdestroy-cross-path-elementto layout the cross of a destroyed participantdestroy-cross-pathto style the cross of a destroyed participantfound-message-elementto layout found message elementsfound-messageto style found messagesfragment-name-borderto style the border around fragment namesfragment-name-elementto layout both the border and name of fragmentsfragment-nameto style the text display of fragment namesfragment-subtext-elementto layout the subtext of fragmentsfragment-subtextto style the subtext of fragmentsframe-elementto layout the subtext of framesframeto style framesinstance-elementto layout instancesinstanceto style instanceslost-message-elementto layout lost message elementslost-messageto style lost messagesnon-top-level-participant-elementto style any participant created after the position has moved, so itsyis not0participant-elementto layout participantsparticipantto style participantstop-level-participant-elementto style any participant created at the initial position, so itsyis0
Example
Here is an example for a webshop order, using most of the features described above: