11.5.4 Automatic De-Overlapping at Arrow Ends

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.

exI8_cshexI8

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.

exI9_cshexI9

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).

exJ1_cshexJ1

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.

exJ7_cshexJ7

Footnotes

(78)

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.