If you define multiple arrows between two blocks normally they would overlap. If you specify multiple arrows from a block using the same port and direction, they will start overlapping. Normally neither of these overlaps are pleasant, so Msc-generator aims to de-overlap arrow ends by shifting them apart a bit.78
For each arrow you can specify the routing.arrow_distance
attribute to specify
how many pixels to set them apart. Msc-generator takes the width of the arrows into
account, but not the width of their arrowhead. If you specify zero, then the given arrow
will not be modified.
![]() | ![]() |
After shifting the endpoints, arrows may still overlap, for example if they go around
the same block they will follow the contour of that block. By setting
routing.block_others
to yes
(the default) on the arrow drawn earlier
will prevent any later arrows that had overlapping ends with it from crossing it
or getting closer to it than routing.arrow_distance
. You can specify
a number via routing.order
to govern in which the arrows in overlapping by their
end are re-laid out after their endpoints have been shifted. Note that arrows never block
other arrows that have no overlapping ending with them.
![]() | ![]() |
Below we show a more complicated example, where we want all three arrows to go between
blocks y
and v
. This is complicated, because if we draw the either the
black or the arrow first, it will go very close both to y
and v
and will
leave no room for the other arrow (red or black, respectively). So we engineer
to draw the red before, but proscribe a larger distance between it and y
to leave
room for the black arrow. The black arrow is then assigned a routing.order
of 1.
(Which is larger than the default of 0 and will cause the black arrow to be drawn after
the red.) Adding the same distance to the blue arrow will ensure its overlap with the
red one (and hence the proper de-overlapping and no crossing).
![]() | ![]() |
You can specify routing.try_harder
to yes
to make Msc-generator
try all permutations in the order of how the arrow ends are shifted. Doing a complete
search is quite slow, so this is not recommended for a large set of overlapped arrow
ends. If not set, we stop the search as soon as a layout is found, where no arrow
overlaps with another in the group of overlapping arrow ends.
Note that if two arrows go on the exact same path they will be routed together. To split
them to different paths, set the routing.allow_joint_layout
attribute to no
for one of them. (This attribute defaults to yes
.)
In the below example we have the same situation for two pairs of arrows
(one pair from block A
to C
and another pair from block C
to E
).
The first pair is routed together, but the second pair is not.
![]() | ![]() |
Arrow ends specified via coordinates, where both the X and Y coordinate uses the same, single block and the arrow endpoint is inside that block, will also get de-overlapped. This is a good way to specify a port for a block, whose shape does not have the port position, you need.