UML Sequence Diagram
Hylimo is able to efficiently draw sequence diagrams. On top of that, it is the most efficient tool we know to draw any typical sequence diagram: Sequence diagrams defined in Hylimo are the most maintainable sequence diagrams you will have ever created.
Basic principle
Since sequence diagrams model when (and where) something happens, it should be modeled in a way that shows the when at a glance.
In other words: Order matters!
The sequence diagram always knows only the currently available information and nothing on top.
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 one of the following:- an
instance
without a name (User
) - an
instance
with a name (Bob: User
) - an
actor
(a stickman symbolizing a user), optionally with a name
- an
- Lifeline: the entire duration a participant is alive, symbolized by the dotted line downwards
- Event: an x/y coordinate linking a point in time to a participant, accessed by using the syntax
event.participant
, so i.e.startPayment.User
.\ - Message: arrow between two
event
s with a semantic meaning - Activity: the time a participant is active
- Frame: A box around some events. Can optionally contain a name (i.e.
if
,while
), and sub compartments
Order matters
Below, you'll find the order in which you should declare things so that they work as expected.
Hylimo walks through the diagram from left to right, and then from top to bottom.
First, declare all participants (instance
, actor
) in the order you want to display them as they will be positioned on the x axis in this order:
INFO
This example creates three participants, reading from left to right as Bob
, Shop
and lastly a user called Admin
.
Now that we've populated our x
axis, let's move on with the y
axis.
The main way to move forward on the y
axis in a sequence diagram is through events
.
An event
needs a name to refer to it later on and automatically moves downward on the y axis.
To illustrate this, we've enabled the debugging mode here and below that visualizes exactly where Hylimo places the given coordinates.
You can enable the debugging mode yourself by setting enableDebugging = true
, or disabling it by omitting it/setting it to false
.
This is the precise purpose of it: It should help you understand what action will lead to what outcome.
Of course, once you want to finish your diagram, we recommend to turn it off again to not confuse your diagram readers.
INFO
As you can see above, the name should be understandable for you to know exactly which action is symbolized by this event. This name will never be shown anywhere.
For most cases, the default value for how far away the next event will be good-enough. Nevertheless, in cases where you want an explicit distance to the predecessor, you are free to do so:
INFO
This positions the event 50
pixels below its predecessor. Note that while negative values are allowed here, they won't make any sense: Instead, you can also move the previous event up by that amount and invert their meanings.
Both event
and participant
names will be registered as variables if they didn't 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:
INFO
Sometimes, you want to send messages where some time delta happens in between.
However, the normal Hylimo behavior for A --> B
is to use the most recent event as y coordinate, not any y coordinate.
To achieve the time delta in spite of these inherent limitations, use the notation participant.on(event)
which forces Hylimo to use the participant at the specified point in time:
INFO
Now, we have the basic knowledge to go on with the remaining features that are all relative to the latest event.
Interacting with participants
There is a bunch of things you can do with participants, depending on if there is a latest defined event:
- you can postpone the creation of a participant by defining it after an event:
INFO
- You can destroy a participant:
INFO
- You can reanimate a dead participant:
INFO
- You can activate and deactivate a participant, meaning that it is actively working on something:
INFO
Note as well that there are three dots when an event meets an activity indicator, except for the initial event. This has the following reason:
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 indicator (this is a simplified, slightly incorrect explanation for the sake of brevity). These left
and right
coordinates show exactly the points where a message will be send/received from.
The third point, the center
shows where the event would have been located originally. It is "missing" when creating a new indicator as it is located behind the indicator (remember: Hylimo only knows what is currently available, and the indicator does not yet exist when it creates the points)
- Even multiple times simultaneously:
INFO
As you can see in this example, you can also use events to simulate margins, as we explicitly defined a pseudo-event whose only purpose is to add 5 pixels on the y-axis between the first indicator and the second one.
important: Since Hylimo only has access to the currently known state, we recommend the following order of execution:activate
operations are the first operations after defining an event.
Messages are sent after activate
operations.deactivate
operations are the last operations for this event.
Messages
The following messages are available within sequence diagrams (in both directions, of course):
INFO
Global variables within sequence diagrams
The following global variables are available and modifiable within 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 | - |
destroyingCrossSize | The width and height of a participant-destruction cross | 20 | - |
enableDebugging | Toggles the debugging mode for sequence diagrams printing additional info | false | Rarely useful |
eventDistance | How far to move downward on the y axis with the next event | 25 | Do not use a multiple of 10 for your own sake |
externalMessageDiameter | Width and height of the circle of lost and found messages | 20 | - |
externalMessageDistance | 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 | 20 | - |
frameMarginY | Default margin to apply on the top and bottom of frames | 5 | margin , we recommend keeping them in sync |
margin | Margin to add to almost any interaction, i.e. to activity indicator endings | 5 | A non-0 value makes the diagram slightly inaccurate but more visually appealing |
participantDistance | How far apart subsequent participants should be | 200 | Multiple of 100 to align participants on the grid |
Precise method documentation
activate
Activates a participant at the y coordinate (minus margin
) of the most recent event. The same participant can be activated multiple times simultaneously.
params:
- 0: the participant (instance or actor) to activate
xShift
: an optional shift on the x-axis when using multiple activity indicators simultaneously on the same instance. Defaults toactivityShift
yOffset
: an optional offset on the y-axis where to start being active. Defaults tomargin
returms: the created indicator
actor
Creates a stickman figure symbolising a user.
An actor can optionally be instanced, meaning that they possess certain attributes.
An instanced actor is an actor that has a stickman on top and an instance
below it.
params:
- 0: the optional name of the user. Defaults to
User
- 1: A function that sets the instance values of this actor, making this actor instanced.
If this function is set, the stickman will be placed on top of a newly createdinstance
The stickman specifically can then be styled/layouted usinginstanced-actor(-element)
.
To access the created instance, use<return value>.instance
below
: 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 event
returns: the created stickman. If this actor is instanced, you can access the instance using <return value>.instance
deactivate
Deactivates the most recent indicator of the given participant
params:
- 0: the participant to deactivate
destroy
Destroys the given participant.
params:
- 0: the participant to destroy
crossSize
: The width and height of the cross to draw. Defaults todestroyingCrossSize
returns: the created cross
event
Creates a new event. params:
- 0: the name of the event. Can be used as variable afterward if not already declared
- 1: an optional distance on the y-axis to the previous event. Defaults to
eventDistance
returns: the created event
foundMessage
Creates the dot signaling a message from an external source. Should always be used inline as a message from something else:
INFO
Is exactly the same as lostMessage
, the meaning comes from the direction in which you declare the message
params:
distance
: the optional distance of the message on the x axis. Defaults toexternalMessageDistance
diameter
: the optional diameter of the dot. Defaults toexternalMessageDiameter
returns: the created dot
fragment
Only available within the function of a frame
. Adds a new fragment to this frame. A fragment is the following:
- An optional line on top separating the previous fragment,
- An optional name of this fragment (i.e.
if
,else
,while
, …) - An optional border around the name
- An optional subtext, i.e. a condition
params:
- 0: the event or y axis coordinate to use for the top line, so the uppermost y coordinate of this frame
text
: The optional name of this fragmentsubtext
: The optional subtext of this fragmenthasLine
: Whether to draw the line on top. Defaults totrue
hasIcon
: Whether to draw the border around the name. Defaults totext != null
returns: A data object containing all this data plus the newly created elements
frame
Creates a new frame around the given coordinates.
params:
topLeft
: The top left coordinate (event) to draw the frame around. The border will be extended byframeMarginX
to the left andframeMarginY
to the top by defaultbottomRight
: The bottom right coordinate (event) to draw the frame around. The border will be extended byframeMarginX
to the right andframeMarginY
at the bottom by defaulttext
: The optional name of this frame, i.e.if
orwhile
subtext
: The optional subtext of this fragment, i.e. a conditionhasIcon
: Whether to draw the border around the name. Defaults totext != null
marginRight
: An optional margin to use on the right sidemarginBelow
: An optional margin to use on the bottommarginLeft
: An optional margin to use on the left sidemarginTop
: An optional margin to use on the top
returns: The created frame
instance
Creates an instance which is an abstract concept of someone who participates in the diagram.
params:
- 0: the optional name of the instance. If the next argument is missing, this will be treated as the class name of the instance
- 1: the optional class name of the instance
- 2: A function determining the content of the instance
below
: 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 event
returns: the created actor
lostMessage
Creates the dot signaling a message to an external source. Should always be used inline as a message to something else:
INFO
Is exactly the same as foundMessage
, the meaning comes from the direction in which you declare the message
params:
distance
: the optional distance of the message on the x axis. Defaults toexternalMessageDistance
diameter
: the optional diameter of the dot. Defaults toexternalMessageDiameter
returns: the created dot
Available class names
The following class names are available for styling/layout purposes within sequence diagrams:
activity-indicator-element
to layout activity indicator elementsactivity-indicator
to style activity indicatorsactor-element
to layout actorsactor
to style actorsdestroy-cross-path-element
to layout the cross of a destroyed participantdestroy-cross-path
to style the cross of a destroyed participantfound-message-element
to layout found message elementsfound-message
to style found messagesfragment-name-border
to style the border around fragment namesfragment-name-element
to layout both the border and name of fragmentsfragment-name
to style the text display of fragment namesfragment-subtext-element
to layout the subtext of fragmentsfragment-subtext
to style the subtext of fragmentsframe-element
to layout the subtext of framesframe
to style framesinstance-element
to layout instancesinstance
to style instancesinstanced-actor-element
to layout the stickman of instanced actorsinstanced-actor
to style the stickman of instanced actorslost-message-element
to layout lost message elementslost-message
to style lost messagesnon-top-level-participant-element
to style any participant after an event was declared, so itsy
is not0
top-level-participant-element
to style any participant before any event was declared, so itsy
is0
Advanced functionality
Sequence diagrams offer many features that are rather intended for experienced users.
Frames
A frame
is a rectangle containing a bunch of events, optionally with a text naming it and a subtext for further explanation.
To declare a frame, you have to supply two mandatory attributes:
Its top-left and bottom-right corner.
Or in Hylimo terms, event coordinates symbolising these two corners.
Here's an example frame:
INFO
Unfortunately, as you need to know both start and end to create a frame, frames will always need to be the most recent component and thus hide any underlying element. We haven't found a better way around that yet. If you want to graphically edit i.e. a message below a frame, please comment out the frame and then edit the message for the time being.
Nested Frames
You can nest frames arbitrarily if you have enough events and participants.
Simply declare a frame containing a subset of events/participants after the first one, and your subframe:
INFO
Frames with fragments
A frame can receive a number of fragments.
A fragment is a separate section inside the frame, i.e. a else if
for an if
.
In other words, a frame can have an optional line on the top to separate it from its predecessor, and text/subtext just like the frame.
To declare a fragment, pass a function behind the frame where you can use the fragment
function:
INFO
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 second parameter to actor
, the function declaring instance variables:
INFO
Frames as per the UML standard
Use the following code snippets to create frames that are explicitly recommended according to the UML specification:
alt-frame
An alt
frame only executes the given code only if the condition applies.
It represents an if (else)
in the code.
It can be used for example as follows:
INFO
opt-frame
An opt
frame only executes the fragment where the condition is true.
It represents a switch
in the code.
It can be used for example as follows:
INFO
loop-frame
A loop
frame executes the code within the frame as long as the condition is true.
It represents a switch
in the code.
You can optionally stop executing early using a nested break
frame. When the break
frame is encountered and its condition (the subtext) is true, the loop is exited.
It can be used for example as follows:
INFO
par-frame
A par
frame executes its fragments simultaneously.
It represents parallel execution in code.
It can be used for example as follows:
INFO
ref-frame
A ref
frame signifies that another part of this diagram/ another sequence diagram should be executed for the components contained inside of it.
It represents a method call in code.
It can be used for example as follows:
INFO
Example
Here is an example for a webshop order:
INFO