diff --git a/capellambse_context_diagrams/collectors/default.py b/capellambse_context_diagrams/collectors/default.py index 99229ab..f4c5353 100644 --- a/capellambse_context_diagrams/collectors/default.py +++ b/capellambse_context_diagrams/collectors/default.py @@ -7,6 +7,7 @@ from __future__ import annotations +import collections import collections.abc as cabc import typing as t from itertools import chain @@ -74,6 +75,7 @@ def process_context(self): "output": -makers.NEIGHBOR_VMARGIN, } self._process_ports(stack_heights) + self._process_cycles() if self.diagram._display_parent_relation and self.diagram.target.owner: current = self.diagram.target.owner @@ -95,9 +97,7 @@ def process_context(self): self.data.children.extend(self.global_boxes.values()) if self.diagram._display_parent_relation: owner_boxes: dict[str, _elkjs.ELKInputChild] = { - uuid: box - for uuid, box in self.made_boxes.items() - if box.children + uuid: box for uuid, box in self.made_boxes.items() } generic.move_parent_boxes_to_owner( owner_boxes, self.diagram.target, self.data @@ -267,6 +267,16 @@ def _process_ports(self, stack_heights: dict[str, float | int]) -> None: stack_heights[side] += makers.NEIGHBOR_VMARGIN + height + def _process_cycles(self) -> None: + ex_count = collections.Counter([ex.uuid for ex in self.exchanges]) + cycles = set(uuid for uuid, count in ex_count.items() if count == 2) + for ex in self.exchanges[:]: + if ex.uuid in cycles: + self.exchanges.remove(ex) + cycles.remove(ex.uuid) + if not cycles: + break + def _make_box( self, obj: t.Any, diff --git a/capellambse_context_diagrams/collectors/generic.py b/capellambse_context_diagrams/collectors/generic.py index a89ea00..f495cff 100644 --- a/capellambse_context_diagrams/collectors/generic.py +++ b/capellambse_context_diagrams/collectors/generic.py @@ -234,11 +234,15 @@ def move_edges( source_owner_uuids.remove(c.source.uuid) target_owner_uuids.remove(c.source.uuid) + cycle_detected = c.source.owner.uuid == c.target.owner.uuid common_owner_uuid = None for owner in source_owner_uuids: if owner in target_owner_uuids: common_owner_uuid = owner - break + if cycle_detected: + cycle_detected = False + else: + break if not common_owner_uuid or not ( owner_box := boxes.get(common_owner_uuid) @@ -249,6 +253,7 @@ def move_edges( if edge.id == c.uuid: owner_box.edges.append(edge) edges_to_remove.append(edge.id) + data.edges = [e for e in data.edges if e.id not in edges_to_remove]