Sometimes it is desired to express that two (or more) separate processes happen
side-by-side. Parallel blocks allow this. Simply place the the parallel
blocks between ‘{}
’ marks and write them one after the other, as in
Drawing Things in Parallel. You can specify as many parallel blocks as you
want. The last (and only the las) parallel block shall be followed by a semicolon. The order of
the blocks is not much relevant, with the exception of numbering, which goes in the
order the blocks are specified in the source file. It is possible to place
anything in a parallel block, arrows, boxes, or other parallel blocks, as well.
Below the series of parallel blocks the next element will be drawn after the
longest of the parallel blocks.
There are two ways to lay out parallel blocks. They differ in how they handle
cases when elements from the individual blocks would overlap. For non-overlapping
cases they function the same way. The first algorithm, called one-by-one
places elements from blocks one by one always taking the next element from the
block which is currently the shortest (has its bottom end the highest). Elements
are placed so as to avoid overlap between them. The other algorithm, called
overlap
lays out the blocks independently and allows overlap.
The algorithm to use can be selected by the layout
attribute that can be
specified for the entire parallel block series before the first block.
![]() |
![]() |
The one_by_one
algorithm has a variant, called one_by_one_merge
,
which behaves differently in case of nested parallel blocks. If you apply this
algorithm to the inner parallel block, they will be merged with the outer
blocks. In contrast, one_by_one
results in laying out the inner parallel
blocks on their own as if they were a single element.
![]() |
![]() |
Note that with one_by_one
and one_by_one_merge
Msc-generator
not only avoids overlap between elements, but in addition keeps a minimum distance
between two elements. This means that arrows to/from the same entity cannot be
drawn completely besides each other, since in that case they would touch.
Thus one of them is drawn a little lower. If this is not intended, use overlap
.
![]() |
![]() |
If you use the overlap
algorithm, you can also specify vertical alignment
of the individual blocks via the vertical_ident
attribute, which can be
set to top
, middle
or bottom
.
![]() |
![]() |
The default behaviour is one_by_one_merge
, which allows fine parallelism,
but avoids ugly overlaps[34].
You can mark entire parallel block series, with the parallel
and overlap
keywords
(and attributes). This results in elements after the entire parallel block series to be
laid out besides and over the elements in the parallel blocks, respectively. In addition,
you can set the keep_with_next
and keep_together
attributes to influence
automatic pagination.
Parallel block serieses also have compress
and vspacing
attributes. These
govern, how they are laid out under the previous element.
For block series with layout=overlap
and layout=one_by_one
, first the entire
block series is laid out without regard to already placed elements. Then, if compress is
on (or vspace=compress
is set, which is equivalent) the whole block series
is moved upwards as one until some parts of it bump into an already placed element.
If a nonzero vertical spacing is used, the whole block series is shifted down such that the
requested spacing appears between the top of the block series and the prior element.
For layout=one_by_one_merge
with compress=yes
the first elements of
the parallel blocks are individually moved upwards until they hit one of the elements above.
In case a positive vspacing
is specified, the behaviour is the same as for
layout=one_by_one
. The compress
and the vspacing
attribute of
the first element in each parallel block can modify this behaviour (e.g., by adding vertical spacing).
Note that if the vspacing
chart option is set to a positive number, the vspacing
attribute of parallel blocks is set to zero instead of this number by default. This is to avoid
having this vertical space twice: once for the parallel block series and once for the first elements
in the blocks. You can nevertheless assign a nonzero vertical space for the block series
by manually specifying the vspacing
attribute for the parallel block.
If case of vspacing=compress
or compress=yes
chart options, the corresponding
attribute of parallel block series is set according to the value of the chart option.
One design goal with layout=one_by_one_merge
was that in case the parallel
block series contains just one block, it should get laid out exactly as if its content were not
enclosed between ‘{}
’ marks. This allows you to put ‘{}
’ marks
around any set of elements, creating a new scope (see Scoping), where any changes
to styles or options take effect only inside the scope.
Specifying the keyword parallel
in front of an element will make the
rest of the chart be drawn in parallel with it. To be more precise the effect only
lasts till the end of the scope, so elements after the next closing brace
will be drawn sequentially under[35].
You can place parallel
in front of really any element, including
entity definitions or even series of parallel blocks. You can even combine several
elements using braces.
![]() |
![]() |
Sometime one explicitly wants two elements to overlap. One prime case is
to show slanted messages to cross each other. You could do it via parallel blocks
allowing overlap via ‘layout=overlap
’ but that is a bit cumbersome for
overlapping short parts. A shorthand is offered by the overlap
keyword.
Specifying this keyword in front of any element will result in ignoring this
element at the layout of subsequent elements. The next element will be laid out
exactly at the same vertical position as the element marked with overlap
drawing on top of it. Subsequent are then laid out below and can still overlap
the element marked with overlap
. This effect is in place till the next
closing brace (or the end of the file).
Thus this keyword is similar to the parallel
keyword, but it allows direct
overlap, not just side-by-side layout.
![]() |
![]() |
[34] Setting the classic_parallel_layout
chart
option to yes
causes the default to be overlap
, because prior v3.6
the only algorithm available was overlap
. This chart option is now deprecated
and will be removed in future releases. Use layout=overlap
instead.
[35] This is how this works exactly: first, the
element marked with parallel
is placed. Then the rest of the elements
in the scope are placed below it and are moved as one block up at most to
the top of the element marked with parallel
. The move stops if any
element in the block being moved bumps into an already placed element,
thus overlaps are avoided.