diff --git a/docs/extras/derived.md b/docs/extras/derived.md index 796833f4..7f063db5 100644 --- a/docs/extras/derived.md +++ b/docs/extras/derived.md @@ -12,15 +12,15 @@ i.e. the system of interest on which `context_diagram` was called on. The render parameter to enable this feature is called `display_derived_interfaces` and is available on: -- `LogicalComponent`s and -- `SystemComponent`s +- `LogicalComponent`s and +- `SystemComponent`s !!! example "Context Diagram with derived elements" ```py from capellambse import MelodyModel - lost = model.by_uuid("0d18f31b-9a13-4c54-9e63-a13dbf619a69") + lost = model.by_uuid("47c3130b-ec39-4365-a77a-5ab6365d1e2e") diag = obj.context_diagram diag.render( "svgdiagram", display_derived_interfaces=True @@ -32,6 +32,6 @@ and is available on: </figure> See [`the derivator -functions`][capellambse_context_diagrams.collectors.default.DERIVATORS] to gain +functions`][capellambse_context_diagrams.collectors.custom.DERIVATORS] to gain an overview over all supported capellambse types and the logic to derive elements. diff --git a/pyproject.toml b/pyproject.toml index 45400239..3a96d127 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -46,6 +46,7 @@ context_diagrams = "capellambse_context_diagrams:init" [dependency-groups] dev = [ "coverage>=7.6.9", + "ipykernel>=6.29.5", "pre-commit>=4.0.1", "pyls-isort>=0.2.2", "pylsp-mypy>=0.6.9", diff --git a/src/capellambse_context_diagrams/__init__.py b/src/capellambse_context_diagrams/__init__.py index 06b1f782..f833a08e 100644 --- a/src/capellambse_context_diagrams/__init__.py +++ b/src/capellambse_context_diagrams/__init__.py @@ -354,5 +354,5 @@ def register_custom_diagram() -> None: m.set_accessor( class_, "custom_diagram", - context.CustomContextAccessor(dgcls.value, {}), + context.CustomAccessor(dgcls.value, {}), ) diff --git a/src/capellambse_context_diagrams/collectors/__init__.py b/src/capellambse_context_diagrams/collectors/__init__.py index 566fe85e..c9bca6c4 100644 --- a/src/capellambse_context_diagrams/collectors/__init__.py +++ b/src/capellambse_context_diagrams/collectors/__init__.py @@ -20,7 +20,7 @@ def get_elkdata( - diagram: context.ContextDiagram, params: dict[str, t.Any] | None = None + diagram: context.ContextDiagram, params: dict[str, t.Any] ) -> _elkjs.ELKInputData: """High level collector function to collect needed data for ELK. diff --git a/src/capellambse_context_diagrams/collectors/custom.py b/src/capellambse_context_diagrams/collectors/custom.py index e17c3a5b..4238457d 100644 --- a/src/capellambse_context_diagrams/collectors/custom.py +++ b/src/capellambse_context_diagrams/collectors/custom.py @@ -5,14 +5,33 @@ from __future__ import annotations +import collections.abc as cabc import copy import typing as t import capellambse.model as m +from capellambse.metamodel import cs, fa, la, sa from .. import _elkjs, context from . import generic, makers +if t.TYPE_CHECKING: + from .. import context + + DerivatorFunction: t.TypeAlias = cabc.Callable[ + [ + context.CustomDiagram, + dict[str, _elkjs.ELKInputChild], + dict[str, _elkjs.ELKInputEdge], + ], + None, + ] + + Filter: t.TypeAlias = cabc.Callable[ + [cabc.Iterable[m.ModelElement]], + cabc.Iterable[m.ModelElement], + ] + def _is_edge(obj: m.ModelElement) -> bool: return hasattr(obj, "source") and hasattr(obj, "target") @@ -27,7 +46,7 @@ class CustomCollector: def __init__( self, - diagram: context.ContextDiagram, + diagram: context.CustomDiagram, params: dict[str, t.Any], ) -> None: self.diagram = diagram @@ -48,21 +67,29 @@ def __init__( self.edges: dict[str, _elkjs.ELKInputEdge] = {} self.ports: dict[str, _elkjs.ELKInputPort] = {} self.boxes_to_delete: set[str] = set() + self.edges_to_flip: dict[str, dict[bool, set[str]]] = {} if self.diagram._display_parent_relation: self.edge_owners: dict[str, str] = {} + self.common_owners: set[str] = set() + + if self.diagram._display_parent_relation or self.diagram._blackbox: self.diagram_target_owners = list( generic.get_all_owners(self.boxable_target) ) - self.common_owners: set[str] = set() if self.diagram._unify_edge_direction != "NONE": self.directions: dict[str, bool] = {} + + if self.diagram._unify_edge_direction == "UNIFORM": + self.directions[self.boxable_target.uuid] = False + self.min_heights: dict[str, dict[str, float]] = {} def __call__(self) -> _elkjs.ELKInputData: if _is_port(self.target): - self._make_port_and_owner(self.target) + port = self._make_port_and_owner(self.target, "right") + self._update_min_heights(self.boxable_target.uuid, "left", port) else: self._make_target(self.target) @@ -71,12 +98,11 @@ def __call__(self) -> _elkjs.ELKInputData: _elkjs.EDGE_STRAIGHTENING_LAYOUT_OPTIONS ) - if self.diagram._unify_edge_direction == "UNIFORM": - self.directions[self.boxable_target.uuid] = False - for elem in self.collection: self._make_target(elem) + self._flip_edges() + if self.diagram._display_parent_relation: current = self.boxable_target while ( @@ -94,6 +120,10 @@ def __call__(self) -> _elkjs.ELKInputData: if box := self.boxes.get(box_uuid): box.edges.append(self.edges.pop(edge_uuid)) + derivator = DERIVATORS.get(type(self.target)) + if self.diagram._display_derived_interfaces and derivator is not None: + derivator(self.diagram, self.boxes, self.edges) + self._fix_box_heights() for uuid in self.boxes_to_delete: del self.boxes[uuid] @@ -104,6 +134,25 @@ def _get_data(self) -> t.Any: self.data.edges = list(self.edges.values()) return self.data + def _flip_edges(self) -> None: + if self.diagram._unify_edge_direction == "NONE": + return + + def flip(edge_uuid: str) -> None: + edge = self.edges[edge_uuid] + edge.sources[-1], edge.targets[-1] = ( + edge.targets[-1], + edge.sources[-1], + ) + + def flip_small_side(edges: dict[bool, set[str]]) -> None: + side = len(edges[True]) < len(edges[False]) + for edge_uuid in edges[side]: + flip(edge_uuid) + + for edges in self.edges_to_flip.values(): + flip_small_side(edges) + def _fix_box_heights(self) -> None: if self.diagram._unify_edge_direction != "NONE": for uuid, min_heights in self.min_heights.items(): @@ -138,8 +187,9 @@ def _make_box( for attr in generic.DIAGRAM_TYPE_TO_CONNECTOR_NAMES[ self.diagram.type ]: - for port in getattr(obj, attr, []): - self._make_port_and_owner(port) + for port_obj in getattr(obj, attr, []): + side = "left" if attr == "inputs" else "right" + self._make_port_and_owner(port_obj, side) if self.diagram._display_parent_relation: self.common_owners.add( generic.make_owner_boxes( @@ -158,17 +208,37 @@ def _make_edge_and_ports( ) -> _elkjs.ELKInputEdge | None: if self.edges.get(edge_obj.uuid): return None - src_obj = edge_obj.source - tgt_obj = edge_obj.target + ex_data = generic.ExchangeData( + edge_obj, + self.data, + self.diagram.filters, + self.params, + ) + src_obj, tgt_obj = generic.exchange_data_collector(ex_data) + edge = self.data.edges.pop() src_owner = src_obj.owner tgt_owner = tgt_obj.owner src_owners = list(generic.get_all_owners(src_obj)) tgt_owners = list(generic.get_all_owners(tgt_obj)) - if self.diagram._hide_direct_children and ( - self.boxable_target.uuid in src_owners - or self.boxable_target.uuid in tgt_owners - ): - return None + is_src = self.boxable_target.uuid in src_owners + is_tgt = self.boxable_target.uuid in tgt_owners + + if self.diagram._blackbox: + if is_src and is_tgt: + return None + if is_src and src_owner.uuid != self.boxable_target.uuid: + edge.id = ( + f"{makers.STYLECLASS_PREFIX}-ComponentExchange:{edge.id}" + ) + src_owner = self.boxable_target + src_owners = self.diagram_target_owners + elif is_tgt and tgt_owner.uuid != self.boxable_target.uuid: + edge.id = ( + f"{makers.STYLECLASS_PREFIX}-ComponentExchange:{edge.id}" + ) + tgt_owner = self.boxable_target + tgt_owners = self.diagram_target_owners + if self.diagram._display_parent_relation: common_owner = None for owner in src_owners: @@ -178,27 +248,22 @@ def _make_edge_and_ports( if common_owner: self.edge_owners[edge_obj.uuid] = common_owner - if self._need_switch( + flip_needed, unc = self._need_flip( src_owners, tgt_owners, src_owner.uuid, tgt_owner.uuid - ): + ) + self.edges_to_flip.setdefault(unc, {True: set(), False: set()})[ + flip_needed + ].add(edge_obj.uuid) + if flip_needed: src_obj, tgt_obj = tgt_obj, src_obj src_owner, tgt_owner = tgt_owner, src_owner + is_src, is_tgt = is_tgt, is_src if not self.ports.get(src_obj.uuid): - port = self._make_port_and_owner(src_obj) - self._update_min_heights(src_owner.uuid, "right", port) + self._make_port_and_owner(src_obj, "right", src_owner) if not self.ports.get(tgt_obj.uuid): - port = self._make_port_and_owner(tgt_obj) - self._update_min_heights(tgt_owner.uuid, "left", port) - - edge = _elkjs.ELKInputEdge( - id=edge_obj.uuid, - sources=[src_obj.uuid], - targets=[tgt_obj.uuid], - labels=makers.make_label( - edge_obj.name, - ), - ) + self._make_port_and_owner(tgt_obj, "left", tgt_owner) + self.edges[edge_obj.uuid] = edge return edge @@ -212,62 +277,78 @@ def _update_min_heights( sum(label.height for label in port.labels), ) - def _need_switch( + def _need_flip( self, src_owners: list[str], tgt_owners: list[str], src_uuid: str, tgt_uuid: str, - ) -> bool: - if self.diagram._unify_edge_direction == "SMART": - if src_uuid != self.boxable_target.uuid: - src_uncommon = [ - owner for owner in src_owners if owner not in tgt_owners - ][-1] - src_dir = self.directions.setdefault(src_uncommon, False) - else: - src_dir = None - if tgt_uuid != self.boxable_target.uuid: - tgt_uncommon = [ - owner for owner in tgt_owners if owner not in src_owners - ][-1] - tgt_dir = self.directions.setdefault(tgt_uncommon, True) - else: - tgt_dir = None - if (src_dir is True) or (tgt_dir is False): - return True - elif self.diagram._unify_edge_direction == "UNIFORM": + ) -> tuple[bool, str]: + def _get_direction( + uuid: str, + owners: list[str], + opposite_owners: list[str], + default: bool, + ) -> tuple[bool | None, str]: + if uuid == self.boxable_target.uuid: + return None, "" + uncommon_owner = [ + owner for owner in owners if owner not in opposite_owners + ][-1] + return ( + self.directions.setdefault(uncommon_owner, default), + uncommon_owner, + ) + + def _initialize_directions( + src_uuid: str, tgt_uuid: str, default_src: bool, default_tgt: bool + ) -> tuple[bool | None, bool | None]: src_dir = self.directions.get(src_uuid) tgt_dir = self.directions.get(tgt_uuid) - if (src_dir is None) and (tgt_dir is None): - self.directions[src_uuid] = False - self.directions[tgt_uuid] = True + if src_dir is None and tgt_dir is None: + self.directions[src_uuid] = default_src + self.directions[tgt_uuid] = default_tgt elif src_dir is None: self.directions[src_uuid] = not tgt_dir elif tgt_dir is None: self.directions[tgt_uuid] = not src_dir - if self.directions[src_uuid]: - return True - elif self.diagram._unify_edge_direction == "TREE": - src_dir = self.directions.get(src_uuid) - tgt_dir = self.directions.get(tgt_uuid) - if (src_dir is None) and (tgt_dir is None): - self.directions[src_uuid] = True - self.directions[tgt_uuid] = True - elif src_dir is None: - self.directions[src_uuid] = True - return True - elif tgt_dir is None: - self.directions[tgt_uuid] = True - return False + + return src_dir, tgt_dir + + edge_direction: str = self.diagram._unify_edge_direction + if edge_direction == "SMART": + src_dir, src_unc = _get_direction( + src_uuid, src_owners, tgt_owners, False + ) + tgt_dir, tgt_unc = _get_direction( + tgt_uuid, tgt_owners, src_owners, True + ) + return src_dir is True or tgt_dir is False, (src_unc or tgt_unc) + + if edge_direction == "UNIFORM": + src_dir, _ = _initialize_directions( + src_uuid, tgt_uuid, False, True + ) + return self.directions[src_uuid], self.boxable_target.uuid + + if edge_direction == "TREE": + src_dir, tgt_dir = _initialize_directions( + src_uuid, tgt_uuid, True, True + ) + return tgt_dir is not None, self.boxable_target.uuid + + return False, self.boxable_target.uuid def _make_port_and_owner( - self, port_obj: m.ModelElement + self, + port_obj: m.ModelElement, + side: str, + owner: m.ModelElement | None = None, ) -> _elkjs.ELKInputPort: - owner_obj = port_obj.owner + owner_obj = owner if owner else port_obj.owner box = self._make_box( owner_obj, - layout_options=makers.DEFAULT_LABEL_LAYOUT_OPTIONS, + layout_options=makers.CENTRIC_LABEL_LAYOUT_OPTIONS, ) if port := self.ports.get(port_obj.uuid): return port @@ -282,11 +363,92 @@ def _make_port_and_owner( box.layoutOptions["portLabels.placement"] = plp.name box.ports.append(port) self.ports[port_obj.uuid] = port + self._update_min_heights(owner_obj.uuid, side, port) return port def collector( - diagram: context.ContextDiagram, params: dict[str, t.Any] + diagram: context.CustomDiagram, params: dict[str, t.Any] ) -> _elkjs.ELKInputData: """Collect data for rendering a custom diagram.""" return CustomCollector(diagram, params)() + + +def derive_from_functions( + diagram: context.CustomDiagram, + boxes: dict[str, _elkjs.ELKInputChild], + edges: dict[str, _elkjs.ELKInputEdge], +) -> None: + """Derive Components from allocated functions of the context target. + + A Component, a ComponentExchange and two ComponentPorts are added + to ``data``. These elements are prefixed with ``Derived-`` to + receive special styling in the serialization step. + """ + assert isinstance(diagram.target, cs.Component) + ports: list[m.ModelElement] = [] + for fnc in diagram.target.allocated_functions: + inc, out = generic.port_collector(fnc, diagram.type) + ports.extend((inc | out).values()) + + derived_components: dict[str, cs.Component] = {} + for port in ports: + for fex in port.exchanges: + if isinstance(port, fa.FunctionOutputPort): + attr = "target" + else: + attr = "source" + + try: + derived_comp = getattr(fex, attr).owner.owner + if ( + derived_comp == diagram.target + or derived_comp.uuid in boxes + ): + continue + + if derived_comp.uuid not in derived_components: + derived_components[derived_comp.uuid] = derived_comp + except AttributeError: # No owner of owner. + pass + + # Idea: Include flow direction of derived interfaces from all functional + # exchanges. Mixed means bidirectional. Just even out bidirectional + # interfaces and keep flow direction of others. + + centerbox = boxes[diagram.target.uuid] + i = 0 + for i, (uuid, derived_component) in enumerate( + derived_components.items(), 1 + ): + box = makers.make_box( + derived_component, + no_symbol=diagram._display_symbols_as_boxes, + ) + class_ = diagram.serializer.get_styleclass(derived_component.uuid) + box.id = f"{makers.STYLECLASS_PREFIX}-{class_}:{uuid}" + boxes[uuid] = box + source_id = f"{makers.STYLECLASS_PREFIX}-CP_INOUT:{i}" + target_id = f"{makers.STYLECLASS_PREFIX}-CP_INOUT:{-i}" + box.ports.append(makers.make_port(source_id)) + centerbox.ports.append(makers.make_port(target_id)) + if i % 2 == 0: + source_id, target_id = target_id, source_id + + uid = f"{makers.STYLECLASS_PREFIX}-ComponentExchange:{i}" + edges[uid] = _elkjs.ELKInputEdge( + id=uid, + sources=[source_id], + targets=[target_id], + ) + + centerbox.height += ( + makers.PORT_PADDING + (makers.PORT_SIZE + makers.PORT_PADDING) * i // 2 + ) + + +DERIVATORS: dict[type[m.ModelElement], DerivatorFunction] = { + la.LogicalComponent: derive_from_functions, + sa.SystemComponent: derive_from_functions, +} +"""Supported objects to build derived contexts for.""" diff --git a/src/capellambse_context_diagrams/collectors/dataflow_view.py b/src/capellambse_context_diagrams/collectors/dataflow_view.py index 3e06b541..8e5388d2 100644 --- a/src/capellambse_context_diagrams/collectors/dataflow_view.py +++ b/src/capellambse_context_diagrams/collectors/dataflow_view.py @@ -14,14 +14,14 @@ from capellambse.metamodel import fa, oa from .. import _elkjs, context -from . import default, generic, makers, portless +from . import generic, makers, portless COLLECTOR_PARAMS: dict[m.DiagramType, dict[str, t.Any]] = { m.DiagramType.OAIB: {"attribute": "involved_activities"}, m.DiagramType.SDFB: { "attribute": "involved_functions", "filter_attrs": ("source.owner", "target.owner"), - "port_collector": default.port_collector, + "port_collector": generic.port_collector, }, } @@ -90,7 +90,7 @@ def _collect_data( data.children.append(box := makers.make_box(elem)) if port_collector: _ports = port_collector(elem, diagram.type) - connections = default.port_exchange_collector( + connections = generic.port_exchange_collector( _ports, filter=filter ) edges = list(chain.from_iterable(connections.values())) diff --git a/src/capellambse_context_diagrams/collectors/default.py b/src/capellambse_context_diagrams/collectors/default.py index d54acd0b..894d91ac 100644 --- a/src/capellambse_context_diagrams/collectors/default.py +++ b/src/capellambse_context_diagrams/collectors/default.py @@ -14,514 +14,67 @@ from itertools import chain import capellambse.model as m -from capellambse import helpers -from capellambse.metamodel import cs, fa, la, sa -from capellambse.model import DiagramType as DT from .. import _elkjs -from . import exchanges, generic, makers +from . import custom, generic if t.TYPE_CHECKING: from .. import context - DerivatorFunction: t.TypeAlias = cabc.Callable[ - [ - context.ContextDiagram, - _elkjs.ELKInputData, - dict[str, _elkjs.ELKInputChild], - ], - None, - ] - Filter: t.TypeAlias = cabc.Callable[ [cabc.Iterable[m.ModelElement]], cabc.Iterable[m.ModelElement], ] -class ContextProcessor: - def __init__( - self, - diagram: context.ContextDiagram, - data: _elkjs.ELKInputData, - *, - params: dict[str, t.Any] | None = None, - ) -> None: - self.diagram = diagram - self.data = data - self.params = params or {} - self.centerbox = self.data.children[0] - self.global_boxes = {self.centerbox.id: self.centerbox} - self.made_boxes = {self.centerbox.id: self.centerbox} - self.boxes_to_delete = {self.centerbox.id} - self.exchanges: dict[str, fa.AbstractExchange] = {} - if self.diagram._display_parent_relation: - self.diagram_target_owners = list( - generic.get_all_owners(self.diagram.target) - ) - self.common_owners: set[str] = set() - - def process_context(self): - if ( - self.diagram._display_parent_relation - and getattr(self.diagram.target, "owner", None) is not None - and not isinstance(self.diagram.target.owner, generic.PackageTypes) - ): - box = self._make_box( - self.diagram.target.owner, - layout_options=makers.DEFAULT_LABEL_LAYOUT_OPTIONS, - ) - box.children = [self.centerbox] - del self.data.children[0] - - self._process_ports() - - if self.diagram._display_parent_relation and self.diagram.target.owner: - current = self.diagram.target.owner - while ( - current - and self.common_owners - and hasattr(current, "owner") - and not isinstance(current.owner, generic.PackageTypes) - ): - current = generic.make_owner_box( - current, - self._make_box, - self.global_boxes, - self.boxes_to_delete, - ) - self.common_owners.discard(current.uuid) - - for uuid in self.boxes_to_delete: - del self.global_boxes[uuid] - - self.data.children.extend(self.global_boxes.values()) - if self.diagram._display_parent_relation: - generic.move_parent_boxes_to_owner( - self.made_boxes, self.diagram.target, self.data - ) - generic.move_edges( - self.made_boxes, self.exchanges.values(), self.data - ) - - if self.diagram._hide_direct_children: - self.centerbox.children = [] - hidden = {edge.id for edge in self.centerbox.edges} - centerbox_ports = {port.id for port in self.centerbox.ports} - port_uuids: set[str] = set() - for ex in self.exchanges.values(): - if ex.uuid not in hidden: - if ex.source.uuid in centerbox_ports: - port_uuids.add(ex.source.uuid) - if ex.target.uuid in centerbox_ports: - port_uuids.add(ex.target.uuid) - - self.centerbox.edges = [] - self.centerbox.ports = [ - p for p in self.centerbox.ports if p.id in port_uuids - ] - for label in self.centerbox.labels: - label.layoutOptions = makers.CENTRIC_LABEL_LAYOUT_OPTIONS - - def _process_port_spread( - self, - exs: list[fa.AbstractExchange], - attr: str, - inc: int, - port_spread: dict[str, int], - owners: dict[str, str], - ) -> None: - for ex in exs: - elem = getattr(ex, attr).owner - if (owner := owners.get(elem.uuid)) is None: - try: - owner = [ - uuid - for uuid in generic.get_all_owners(elem) - if uuid not in self.diagram_target_owners - ][-1] - except (IndexError, AttributeError): - owner = elem.uuid - assert owner is not None - owners[elem.uuid] = owner - port_spread.setdefault(owner, 0) - port_spread[owner] += inc - - def _process_exchanges( - self, - ) -> tuple[ - list[m.ModelElement], - list[generic.ExchangeData], - ]: - inc, out = port_collector(self.diagram.target, self.diagram.type) - inc_c = port_exchange_collector(inc.values()) - out_c = port_exchange_collector(out.values()) - inc_exchanges = list(chain.from_iterable(inc_c.values())) - out_exchanges = list(chain.from_iterable(out_c.values())) - port_spread: dict[str, int] = {} - owners: dict[str, str] = {} - self._process_port_spread( - inc_exchanges, "source", 1, port_spread, owners - ) - self._process_port_spread( - out_exchanges, "target", -1, port_spread, owners - ) - self.exchanges = {ex.uuid: ex for ex in inc_exchanges + out_exchanges} - ex_datas: list[generic.ExchangeData] = [] - seen_exchanges: set[str] = set() - for ex in self.exchanges.values(): - if ex.uuid in seen_exchanges: - continue - - seen_exchanges.add(ex.uuid) - if is_hierarchical := exchanges.is_hierarchical( - ex, self.centerbox - ): - if not self.diagram._display_parent_relation: - continue - self.centerbox.labels[ - 0 - ].layoutOptions = makers.DEFAULT_LABEL_LAYOUT_OPTIONS - elkdata: _elkjs.ELKInputData = self.centerbox - else: - elkdata = self.data - try: - ex_data = generic.ExchangeData( - ex, - elkdata, - self.diagram.filters, - self.params, - is_hierarchical, - ) - src, tgt = generic.exchange_data_collector(ex_data) - src_owner = owners.get(src.owner.uuid, "") - tgt_owner = owners.get(tgt.owner.uuid, "") - is_inc = tgt.parent == self.diagram.target - is_out = src.parent == self.diagram.target - if is_inc and is_out: - pass # Support cycles - elif (is_out and (port_spread.get(tgt_owner, 0) > 0)) or ( - is_inc and (port_spread.get(src_owner, 0) <= 0) - ): - elkdata.edges[-1].sources = [tgt.uuid] - elkdata.edges[-1].targets = [src.uuid] - ex_datas.append(ex_data) - except AttributeError: - continue - - ports = list((inc | out).values()) - if not self.diagram._display_unused_ports: - ports = [ - p for p in ports if (inc_c.get(p.uuid) or out_c.get(p.uuid)) - ] - - self.centerbox.height = max( - self.centerbox.height, - (makers.PORT_SIZE + 2 * makers.PORT_PADDING) * (len(ports) + 1), - ) - for p in ports: - port, height = self._make_port(p) - self.centerbox.height += height - - self.centerbox.ports.append(port) - self.centerbox.layoutOptions["portLabels.placement"] = "OUTSIDE" - - return ports, ex_datas - - def _process_ports(self) -> None: - ports, ex_datas = self._process_exchanges() - for owner, local_ports in port_context_collector(ex_datas, ports): - _, label_height = helpers.get_text_extent(owner.name) - height = max( - label_height + 2 * makers.LABEL_VPAD, - (makers.PORT_SIZE + 2 * makers.PORT_PADDING) - * (len(local_ports) + 1), - ) - local_port_objs = [] - for j in local_ports: - port, label_heights = self._make_port(j) - height += label_heights - local_port_objs.append(port) - - if box := self.global_boxes.get(owner.uuid): - if box is self.centerbox: - continue - box.ports.extend(local_port_objs) - box.height += height - else: - box = self._make_box( - owner, - height=height, - ) - box.ports = local_port_objs - - box.layoutOptions["portLabels.placement"] = "OUTSIDE" - - if self.diagram._display_parent_relation: - self.common_owners.add( - generic.make_owner_boxes( - owner, - self.diagram_target_owners, - self._make_box, - self.global_boxes, - self.boxes_to_delete, - ) - ) - - def _make_port( - self, port_obj: t.Any - ) -> tuple[_elkjs.ELKInputPort, int | float]: - port = makers.make_port(port_obj.uuid) - height = 0.0 - if self.diagram._display_port_labels: - port.labels = makers.make_label(port_obj.name) - height += max( - 0, - sum(label.height for label in port.labels) - - 2 * makers.PORT_PADDING, - ) - return port, height - - def _make_box( - self, - obj: t.Any, - **kwargs: t.Any, - ) -> _elkjs.ELKInputChild: - if box := self.global_boxes.get(obj.uuid): - return box - box = makers.make_box( - obj, - no_symbol=self.diagram._display_symbols_as_boxes, - **kwargs, - ) - self.global_boxes[obj.uuid] = box - self.made_boxes[obj.uuid] = box - return box - - def collector( - diagram: context.ContextDiagram, params: dict[str, t.Any] | None = None + diagram: context.ContextDiagram, params: dict[str, t.Any] ) -> _elkjs.ELKInputData: """Collect context data from ports of centric box.""" - data = generic.collector(diagram, no_symbol=True) - processor = ContextProcessor(diagram, data, params=params) - processor.process_context() - derivator = DERIVATORS.get(type(diagram.target)) - if diagram._display_derived_interfaces and derivator is not None: - derivator( - diagram, - data, - processor.made_boxes, - ) - return data - - -def port_collector( - target: m.ModelElement | m.ElementList, diagram_type: DT -) -> tuple[dict[str, m.ModelElement], dict[str, m.ModelElement]]: - """Collect ports from `target` savely.""" - - def __collect(target): - port_types = fa.FunctionPort | fa.ComponentPort | cs.PhysicalPort - incoming_ports: dict[str, m.ModelElement] = {} - outgoing_ports: dict[str, m.ModelElement] = {} - for attr in generic.DIAGRAM_TYPE_TO_CONNECTOR_NAMES[diagram_type]: - try: - ports = getattr(target, attr) - if not ports or not isinstance(ports[0], port_types): - continue - - if attr == "inputs": - incoming_ports.update({p.uuid: p for p in ports}) - elif attr == "ports": - for port in ports: - if port.direction == "IN": - incoming_ports[port.uuid] = port - else: - outgoing_ports[port.uuid] = port - else: - outgoing_ports.update({p.uuid: p for p in ports}) - except AttributeError: - pass - return incoming_ports, outgoing_ports - - if isinstance(target, cabc.Iterable): - assert not isinstance(target, m.ModelElement) - incoming_ports: dict[str, m.ModelElement] = {} - outgoing_ports: dict[str, m.ModelElement] = {} - for obj in target: - inc, out = __collect(obj) - incoming_ports.update(inc) - outgoing_ports.update(out) - else: - incoming_ports, outgoing_ports = __collect(target) - return incoming_ports, outgoing_ports - - -def _extract_edges( - obj: m.ModelElement, - attribute: str, - filter: Filter, -) -> cabc.Iterable[m.ModelElement]: - return filter(getattr(obj, attribute, [])) - - -def port_exchange_collector( - ports: t.Iterable[m.ModelElement], - filter: Filter = lambda i: i, -) -> dict[str, list[fa.AbstractExchange]]: - """Collect exchanges from `ports` savely.""" - edges: dict[str, list[fa.AbstractExchange]] = {} - - for port in ports: - if exs := _extract_edges(port, "exchanges", filter): - edges[port.uuid] = t.cast(list[fa.AbstractExchange], exs) - continue - - if links := _extract_edges(port, "links", filter): - edges[port.uuid] = t.cast(list[fa.AbstractExchange], links) - - return edges - - -class ContextInfo(t.NamedTuple): - """ContextInfo data.""" - - element: m.ModelElement - """An element of context.""" - ports: list[m.ModelElement] - """The context element's relevant ports. - - This list only contains ports that at least one of the exchanges - passed into ``collect_exchanges`` sees. - """ - - -def port_context_collector( - exchange_datas: t.Iterable[generic.ExchangeData], - local_ports: t.Container[m.ModelElement], -) -> t.Iterator[ContextInfo]: - """Collect the context objects. - - Parameters - ---------- - exchange_datas - The ``ExchangeData``s to look at to find new elements. - local_ports - Connectors/Ports lookup where ``exchange_datas`` is checked - against. If an exchange connects via a port from ``local_ports`` - it is collected. - - Returns - ------- - contexts - An iterator over - [`ContextDiagram.ContextInfo`s][capellambse_context_diagrams.context.ContextDiagram]. - """ - - ctx: dict[str, ContextInfo] = {} - for exd in exchange_datas: - try: - source, target = generic.collect_exchange_endpoints(exd) - except AttributeError: - continue - - if source in local_ports: - port = target - elif target in local_ports: - port = source - else: - continue - - try: - owner = port.owner - except AttributeError: - continue - - info = ContextInfo(owner, []) - info = ctx.setdefault(owner.uuid, info) - if port not in info.ports: - info.ports.append(port) - - return iter(ctx.values()) - - -def derive_from_functions( - diagram: context.ContextDiagram, - data: _elkjs.ELKInputData, - boxes: dict[str, _elkjs.ELKInputChild], -) -> None: - """Derive Components from allocated functions of the context target. - - A Component, a ComponentExchange and two ComponentPorts are added - to ``data``. These elements are prefixed with ``Derived-`` to - receive special styling in the serialization step. - """ - assert isinstance(diagram.target, cs.Component) - ports: list[m.ModelElement] = [] - for fnc in diagram.target.allocated_functions: - inc, out = port_collector(fnc, diagram.type) - ports.extend((inc | out).values()) - - derived_components: dict[str, cs.Component] = {} - for port in ports: - for fex in port.exchanges: - if isinstance(port, fa.FunctionOutputPort): - attr = "target" - else: - attr = "source" - - try: - derived_comp = getattr(fex, attr).owner.owner - if ( - derived_comp == diagram.target - or derived_comp.uuid in boxes - ): - continue - - if derived_comp.uuid not in derived_components: - derived_components[derived_comp.uuid] = derived_comp - except AttributeError: # No owner of owner. - pass - - # Idea: Include flow direction of derived interfaces from all functional - # exchanges. Mixed means bidirectional. Just even out bidirectional - # interfaces and keep flow direction of others. - - centerbox = boxes[diagram.target.uuid] - i = 0 - for i, (uuid, derived_component) in enumerate( - derived_components.items(), 1 - ): - box = makers.make_box( - derived_component, - no_symbol=diagram._display_symbols_as_boxes, + visited: set[str] = set() + outside_components: dict[str, m.ModelElement] = {} + + def _collect( + target: m.ModelElement, + filter: Filter = lambda i: i, + ) -> cabc.Iterator[m.ModelElement]: + if target.uuid in visited: + return + visited.add(target.uuid) + + inc, out = generic.port_collector(target, diagram.type) + ports = generic.port_exchange_collector( + (inc | out).values(), filter=filter ) - class_ = diagram.serializer.get_styleclass(derived_component.uuid) - box.id = f"{makers.STYLECLASS_PREFIX}-{class_}:{uuid}" - data.children.append(box) - source_id = f"{makers.STYLECLASS_PREFIX}-CP_INOUT:{i}" - target_id = f"{makers.STYLECLASS_PREFIX}-CP_INOUT:{-i}" - box.ports.append(makers.make_port(source_id)) - centerbox.ports.append(makers.make_port(target_id)) - if i % 2 == 0: - source_id, target_id = target_id, source_id - - data.edges.append( - _elkjs.ELKInputEdge( - id=f"{makers.STYLECLASS_PREFIX}-ComponentExchange:{i}", - sources=[source_id], - targets=[target_id], + exchanges = chain.from_iterable(ports.values()) + for ex in exchanges: + yield ex + if ex.source.uuid in ports and ex.target.uuid not in ports: + outside_components[ex.target.owner.uuid] = ex.target.owner + elif ex.target.uuid in ports and ex.source.uuid not in ports: + outside_components[ex.source.owner.uuid] = ex.source.owner + + if diagram._include_children_context or diagram._blackbox: + for cmp in list(getattr(target, "components", [])): + yield from _collect(cmp) + + def _collect_extended_context( + target: m.ModelElement, + ) -> cabc.Iterator[m.ModelElement]: + yield from _collect(target) + if not diagram._display_actor_relation: + return + oc_copy = outside_components.copy() + for cmp in oc_copy.values(): + yield from _collect( + cmp, + filter=lambda items: ( + item + for item in items + if item.source.owner.uuid in oc_copy + and item.target.owner.uuid in oc_copy + ), ) - ) - - centerbox.height += ( - makers.PORT_PADDING + (makers.PORT_SIZE + makers.PORT_PADDING) * i // 2 - ) - -DERIVATORS: dict[type[m.ModelElement], DerivatorFunction] = { - la.LogicalComponent: derive_from_functions, - sa.SystemComponent: derive_from_functions, -} -"""Supported objects to build derived contexts for.""" + diagram._collect = _collect_extended_context(diagram.target) + return custom.CustomCollector(diagram, params=params)() diff --git a/src/capellambse_context_diagrams/collectors/exchanges.py b/src/capellambse_context_diagrams/collectors/exchanges.py index ff83a9d2..21cecae0 100644 --- a/src/capellambse_context_diagrams/collectors/exchanges.py +++ b/src/capellambse_context_diagrams/collectors/exchanges.py @@ -290,6 +290,12 @@ def collect(self) -> None: self.incoming_edges = {} self.outgoing_edges = {} + for label in self.left.labels: + label.layoutOptions = makers.CENTRIC_LABEL_LAYOUT_OPTIONS + + for label in self.right.labels: + label.layoutOptions = makers.CENTRIC_LABEL_LAYOUT_OPTIONS + if self.diagram._include_interface or self.diagram._hide_functions: self.add_interface() diff --git a/src/capellambse_context_diagrams/collectors/generic.py b/src/capellambse_context_diagrams/collectors/generic.py index 04225b02..42a0a905 100644 --- a/src/capellambse_context_diagrams/collectors/generic.py +++ b/src/capellambse_context_diagrams/collectors/generic.py @@ -14,12 +14,18 @@ import typing as t import capellambse.model as m -from capellambse.metamodel import interaction, la, oa, pa, sa +from capellambse.metamodel import cs, fa, interaction, la, oa, pa, sa from capellambse.model import DiagramType as DT from .. import _elkjs, context, filters from . import makers +if t.TYPE_CHECKING: + Filter: t.TypeAlias = cabc.Callable[ + [cabc.Iterable[m.ModelElement]], + cabc.Iterable[m.ModelElement], + ] + logger = logging.getLogger(__name__) SourceAndTarget = tuple[m.ModelElement, m.ModelElement] @@ -285,10 +291,7 @@ def make_owner_box( break else: children.append(obj_box) - obj_box.width = max( - obj_box.width, - parent_box.width, - ) + obj_box.width = max(obj_box.width, parent_box.width) for label in parent_box.labels: label.layoutOptions = makers.DEFAULT_LABEL_LAYOUT_OPTIONS boxes_to_delete.add(obj.uuid) @@ -314,3 +317,71 @@ def make_owner_boxes( current, make_box_func, boxes, boxes_to_delete ) return current.uuid + + +def port_collector( + target: m.ModelElement | m.ElementList, diagram_type: DT +) -> tuple[dict[str, m.ModelElement], dict[str, m.ModelElement]]: + """Collect ports from `target` savely.""" + + def __collect(target): + port_types = fa.FunctionPort | fa.ComponentPort | cs.PhysicalPort + incoming_ports: dict[str, m.ModelElement] = {} + outgoing_ports: dict[str, m.ModelElement] = {} + for attr in DIAGRAM_TYPE_TO_CONNECTOR_NAMES[diagram_type]: + try: + ports = getattr(target, attr) + if not ports or not isinstance(ports[0], port_types): + continue + + if attr == "inputs": + incoming_ports.update({p.uuid: p for p in ports}) + elif attr == "ports": + for port in ports: + if port.direction == "IN": + incoming_ports[port.uuid] = port + else: + outgoing_ports[port.uuid] = port + else: + outgoing_ports.update({p.uuid: p for p in ports}) + except AttributeError: + pass + return incoming_ports, outgoing_ports + + if isinstance(target, cabc.Iterable): + assert not isinstance(target, m.ModelElement) + incoming_ports: dict[str, m.ModelElement] = {} + outgoing_ports: dict[str, m.ModelElement] = {} + for obj in target: + inc, out = __collect(obj) + incoming_ports.update(inc) + outgoing_ports.update(out) + else: + incoming_ports, outgoing_ports = __collect(target) + return incoming_ports, outgoing_ports + + +def _extract_edges( + obj: m.ModelElement, + attribute: str, + filter: Filter, +) -> cabc.Iterable[m.ModelElement]: + return filter(getattr(obj, attribute, [])) + + +def port_exchange_collector( + ports: t.Iterable[m.ModelElement], + filter: Filter = lambda i: i, +) -> dict[str, list[fa.AbstractExchange]]: + """Collect exchanges from `ports` savely.""" + edges: dict[str, list[fa.AbstractExchange]] = {} + + for port in ports: + if exs := _extract_edges(port, "exchanges", filter): + edges[port.uuid] = t.cast(list[fa.AbstractExchange], exs) + continue + + if links := _extract_edges(port, "links", filter): + edges[port.uuid] = t.cast(list[fa.AbstractExchange], links) + + return edges diff --git a/src/capellambse_context_diagrams/collectors/makers.py b/src/capellambse_context_diagrams/collectors/makers.py index b4e3766c..1970937b 100644 --- a/src/capellambse_context_diagrams/collectors/makers.py +++ b/src/capellambse_context_diagrams/collectors/makers.py @@ -72,8 +72,8 @@ STYLECLASS_PREFIX = "__Derived" -def make_diagram(diagram: context.ContextDiagram) -> _elkjs.ELKInputData: - """Return basic skeleton for ``ContextDiagram``s.""" +def make_diagram(diagram: context.CustomDiagram) -> _elkjs.ELKInputData: + """Return basic skeleton for ``CustomDiagram``s.""" return _elkjs.ELKInputData( id=diagram.uuid, layoutOptions=_elkjs.get_global_layered_layout_options(), diff --git a/src/capellambse_context_diagrams/context.py b/src/capellambse_context_diagrams/context.py index d2e31d66..514507f7 100644 --- a/src/capellambse_context_diagrams/context.py +++ b/src/capellambse_context_diagrams/context.py @@ -50,8 +50,8 @@ """The output of a collector or the input prepared for ELK.""" -class ContextAccessor(m.Accessor): - """Provides access to the context diagrams.""" +class CustomAccessor(m.Accessor): + """Provides access to the custom context diagrams.""" def __init__( self, dgcls: str, render_params: dict[str, t.Any] | None = None @@ -61,24 +61,24 @@ def __init__( self._default_render_params = render_params or {} @t.overload - def __get__(self, obj: None, objtype: type[t.Any]) -> ContextAccessor: ... + def __get__(self, obj: None, objtype: type[t.Any]) -> CustomAccessor: ... @t.overload def __get__( self, obj: m.T, objtype: type[m.T] | None = None - ) -> ContextDiagram: ... + ) -> CustomDiagram: ... def __get__( self, obj: m.T | None, objtype: type | None = None - ) -> m.Accessor | ContextDiagram: + ) -> m.Accessor | CustomDiagram: """Make a ContextDiagram for the given model object.""" del objtype if obj is None: # pragma: no cover return self assert isinstance(obj, m.ModelElement) - return self._get(obj, ContextDiagram) + return self._get(obj, CustomDiagram) def _get( - self, obj: m.ModelElement, diagram_class: type[ContextDiagram] - ) -> m.Accessor | ContextDiagram: + self, obj: m.ModelElement, diagram_class: type[CustomDiagram] + ) -> m.Accessor | CustomDiagram: new_diagram = diagram_class( self._dgcls, obj, @@ -88,6 +88,22 @@ def _get( return new_diagram +class ContextAccessor(CustomAccessor): + """Provides access to the context diagrams.""" + + def __get__( # type: ignore + self, + obj: m.T | None, + objtype: type | None = None, + ) -> m.Accessor | CustomDiagram: + """Make a ContextDiagram for the given model object.""" + del objtype + if obj is None: # pragma: no cover + return self + assert isinstance(obj, m.ModelElement) + return self._get(obj, ContextDiagram) + + class InterfaceContextAccessor(ContextAccessor): """Provides access to the interface context diagrams.""" @@ -101,7 +117,7 @@ def __init__( # pylint: disable=super-init-not-called def __get__( # type: ignore self, obj: m.T | None, objtype: type | None = None - ) -> m.Accessor | ContextDiagram: + ) -> m.Accessor | CustomDiagram: """Make a ContextDiagram for the given model object.""" del objtype if obj is None: # pragma: no cover @@ -117,7 +133,7 @@ def __get__( # type: ignore self, obj: m.T | None, objtype: type | None = None, - ) -> m.Accessor | ContextDiagram: + ) -> m.Accessor | CustomDiagram: """Make a ContextDiagram for the given model object.""" del objtype if obj is None: # pragma: no cover @@ -131,7 +147,7 @@ def __get__( # type: ignore self, obj: m.T | None, objtype: type | None = None, - ) -> m.Accessor | ContextDiagram: + ) -> m.Accessor | CustomDiagram: """Make a ContextDiagram for the given model object.""" del objtype if obj is None: # pragma: no cover @@ -154,7 +170,7 @@ def __get__( # type: ignore self, obj: m.T | None, objtype: type | None = None, - ) -> m.Accessor | ContextDiagram: + ) -> m.Accessor | CustomDiagram: """Make a ClassTreeDiagram for the given model object.""" del objtype if obj is None: # pragma: no cover @@ -177,7 +193,7 @@ def __get__( # type: ignore self, obj: m.T | None, objtype: type | None = None, - ) -> m.Accessor | ContextDiagram: + ) -> m.Accessor | CustomDiagram: """Make a RealizationViewDiagram for the given model object.""" del objtype if obj is None: # pragma: no cover @@ -198,7 +214,7 @@ def __get__( # type: ignore self, obj: m.T | None, objtype: type | None = None, - ) -> m.Accessor | ContextDiagram: + ) -> m.Accessor | CustomDiagram: """Make a DataFlowViewDiagram for the given model object.""" del objtype if obj is None: # pragma: no cover @@ -214,7 +230,7 @@ def __get__( # type: ignore self, obj: m.T | None, objtype: type | None = None, - ) -> m.Accessor | ContextDiagram: + ) -> m.Accessor | CustomDiagram: """Make a CableTreeView for the given model object.""" del objtype if obj is None: # pragma: no cover @@ -223,24 +239,8 @@ def __get__( # type: ignore return self._get(obj, CableTreeViewDiagram) -class CustomContextAccessor(ContextAccessor): - """Provides access to the custom context diagrams.""" - - def __get__( # type: ignore - self, - obj: m.T | None, - objtype: type | None = None, - ) -> m.Accessor | ContextDiagram: - """Make a CustomDiagram for the given model object.""" - del objtype - if obj is None: # pragma: no cover - return self - assert isinstance(obj, m.ModelElement) - return self._get(obj, CustomDiagram) - - -class ContextDiagram(m.AbstractDiagram): - """An automatically generated context diagram. +class CustomDiagram(m.AbstractDiagram): + """An automatically generated custom diagram. Attributes ---------- @@ -283,20 +283,28 @@ class ContextDiagram(m.AbstractDiagram): * display_port_labels — Display port labels on the diagram. * port_label_position - Position of the port labels. See [`PORT_LABEL_POSITION`][capellambse_context_diagrams.context._elkjs.PORT_LABEL_POSITION]. - * hide_direct_children - Hide direct children of the object of - interest. + * display_unused_ports - Display ports that are not connected to an edge. + * collect - A list of collected elements. + * unify_edge_direction - Unify the direction of the edges. + * balckbox - Display the object of interest as a black box. + * display_actor_relation: Show the connections between the context actors. + * include_children_context: Include all children of the object of interest. """ _display_symbols_as_boxes: bool _display_parent_relation: bool - _hide_direct_children: bool _display_derived_interfaces: bool _slim_center_box: bool _display_port_labels: bool _port_label_position: str _transparent_background: bool _display_unused_ports: bool + _collect: cabc.Iterator[m.ModelElement] + _unify_edge_direction: str + _blackbox: bool + _display_actor_relation: bool + _include_children_context: bool def __init__( self, @@ -318,13 +326,17 @@ def __init__( self._default_render_parameters = { "display_symbols_as_boxes": False, "display_parent_relation": False, - "hide_direct_children": False, "display_derived_interfaces": False, - "slim_center_box": True, + "slim_center_box": False, "display_port_labels": False, "port_label_position": _elkjs.PORT_LABEL_POSITION.OUTSIDE.name, "display_unused_ports": False, "transparent_background": False, + "collect": [], + "unify_edge_direction": "NONE", + "blackbox": False, + "display_actor_relation": False, + "include_children_context": False, } | default_render_parameters if standard_filter := STANDARD_FILTERS.get(class_): @@ -333,8 +345,8 @@ def __init__( self.render_styles = standard_styles self.collector: cabc.Callable[ - [ContextDiagram, dict[str, t.Any]], CollectorOutputData - ] = get_elkdata + [CustomDiagram, dict[str, t.Any]], CollectorOutputData + ] = custom.collector @property def uuid(self) -> str: @@ -344,7 +356,7 @@ def uuid(self) -> str: @property def name(self) -> str: """Returns the diagram name.""" - return f"Context of {self.target.name.replace('/', '- or -')}" + return f"Custom Context of {self.target.name.replace('/', '- or -')}" @property def type(self) -> m.DiagramType: @@ -441,6 +453,39 @@ def filters(self, value: cabc.Iterable[str]) -> None: self.__filters |= set(value) +class ContextDiagram(CustomDiagram): + """An automatically generated context Diagram.""" + + def __init__( + self, + class_: str, + obj: m.ModelElement, + *, + render_styles: dict[str, styling.Styler] | None = None, + default_render_parameters: dict[str, t.Any], + ) -> None: + default_render_parameters = { + "slim_center_box": True, + "unify_edge_direction": "SMART", + "include_children_context": True, + } | default_render_parameters + + super().__init__( + class_, + obj, + render_styles=render_styles, + default_render_parameters=default_render_parameters, + ) + + self.collector: cabc.Callable[ + [ContextDiagram, dict[str, t.Any]], CollectorOutputData + ] = get_elkdata + + @property + def name(self) -> str: + return f"Context of {self.target.name.replace('/', '- or -')}" + + class InterfaceContextDiagram(ContextDiagram): """A Context Diagram exclusively for ``ComponentExchange``s. @@ -885,39 +930,7 @@ def name(self) -> str: return f"Cable Tree View of {self.target.name}" -class CustomDiagram(ContextDiagram): - """An automatically generated CustomDiagram Diagram.""" - - _collect: cabc.Iterator[m.ModelElement] - _unify_edge_direction: str - - def __init__( - self, - class_: str, - obj: m.ModelElement, - *, - render_styles: dict[str, styling.Styler] | None = None, - default_render_parameters: dict[str, t.Any], - ) -> None: - default_render_parameters = { - "collect": [], - "slim_center_box": False, - "unify_edge_direction": str, - } | default_render_parameters - super().__init__( - class_, - obj, - render_styles=render_styles, - default_render_parameters=default_render_parameters, - ) - self.collector = custom.collector - - @property - def name(self) -> str: - return f"Custom Context of {self.target.name.replace('/', '- or -')}" - - -class PhysicalPortContextDiagram(CustomDiagram): +class PhysicalPortContextDiagram(ContextDiagram): """A custom Context Diagram exclusively for PhysicalPorts.""" def __init__( @@ -944,7 +957,7 @@ def _collector( default_render_parameters = { "collect": _collector(obj), "display_parent_relation": True, - "unify_edge_direction": "UNIFORM", + "unify_edge_direction": "TREE", "display_port_labels": True, "port_label_position": _elkjs.PORT_LABEL_POSITION.OUTSIDE.name, } | default_render_parameters @@ -955,10 +968,7 @@ def _collector( render_styles=render_styles, default_render_parameters=default_render_parameters, ) - - @property - def name(self) -> str: - return f"Context of {self.target.name.replace('/', '- or -')}" + self.collector = custom.collector def try_to_layout(data: _elkjs.ELKInputData) -> _elkjs.ELKOutputData: diff --git a/src/capellambse_context_diagrams/serializers.py b/src/capellambse_context_diagrams/serializers.py index ada48a39..0e8aacd9 100644 --- a/src/capellambse_context_diagrams/serializers.py +++ b/src/capellambse_context_diagrams/serializers.py @@ -61,7 +61,7 @@ class DiagramSerializer: diagram: cdiagram.Diagram - def __init__(self, elk_diagram: context.ContextDiagram) -> None: + def __init__(self, elk_diagram: context.CustomDiagram) -> None: self.model = elk_diagram.target._model self._diagram = elk_diagram self._cache: dict[str, cdiagram.DiagramElement] = {} diff --git a/tests/data/ContextDiagram.aird b/tests/data/ContextDiagram.aird index 527a0668..ed0d1a45 100644 --- a/tests/data/ContextDiagram.aird +++ b/tests/data/ContextDiagram.aird @@ -110,7 +110,7 @@ <description xmi:type="description_1:DiagramDescription" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']"/> <target xmi:type="org.polarsys.capella.core.data.la:LogicalComponentPkg" href="ContextDiagram.capella#84c0978d-9a32-4f5b-8013-5b0b6adbfd73"/> </ownedRepresentationDescriptors> - <ownedRepresentationDescriptors xmi:type="viewpoint:DRepresentationDescriptor" uid="_TmNTgB4sEe2oAusR2-iOGg" name="[LAB] Stacking" repPath="#_TmJCEB4sEe2oAusR2-iOGg" changeId="b3b22071-05e8-4cd5-92e5-27c49f0a898f"> + <ownedRepresentationDescriptors xmi:type="viewpoint:DRepresentationDescriptor" uid="_TmNTgB4sEe2oAusR2-iOGg" name="[LAB] Stacking" repPath="#_TmJCEB4sEe2oAusR2-iOGg" changeId="95e13f33-c912-4faa-8f90-6bbcb529351f"> <eAnnotations xmi:type="description:DAnnotation" uid="_TmQ94B4sEe2oAusR2-iOGg" source="https://www.polarsys.org/capella/dannotation/DesactivatedFilters"> <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_TmQ94R4sEe2oAusR2-iOGg" key="hide.computed.component.exchanges.filter" value="true"/> <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_TmQ94h4sEe2oAusR2-iOGg" key="hide.computed.physical.links.filter" value="true"/> @@ -202,6 +202,14 @@ <description xmi:type="description_1:DiagramDescription" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']"/> <target xmi:type="org.polarsys.capella.core.data.la:LogicalComponentPkg" href="ContextDiagram.capella#84c0978d-9a32-4f5b-8013-5b0b6adbfd73"/> </ownedRepresentationDescriptors> + <ownedRepresentationDescriptors xmi:type="viewpoint:DRepresentationDescriptor" uid="_37lhkNigEe-Gv-xXZhqgNA" name="[LAB] Blackbox" repPath="#_37h3MNigEe-Gv-xXZhqgNA" changeId="a78648d0-ec48-42c2-8f88-bd982d4dbe4e"> + <eAnnotations xmi:type="description:DAnnotation" uid="_37urgNigEe-Gv-xXZhqgNA" source="https://www.polarsys.org/capella/dannotation/DesactivatedFilters"> + <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_37urgdigEe-Gv-xXZhqgNA" key="hide.computed.component.exchanges.filter" value="true"/> + <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_37urgtigEe-Gv-xXZhqgNA" key="hide.computed.physical.links.filter" value="true"/> + </eAnnotations> + <description xmi:type="description_1:DiagramDescription" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']"/> + <target xmi:type="org.polarsys.capella.core.data.la:LogicalComponentPkg" href="ContextDiagram.capella#84c0978d-9a32-4f5b-8013-5b0b6adbfd73"/> + </ownedRepresentationDescriptors> </ownedViews> <ownedViews xmi:type="viewpoint:DView" uid="_4Dt18PHWEeq9N-vcO9FSUw"> <viewpoint xmi:type="description:Viewpoint" href="platform:/plugin/org.polarsys.kitalpha.vp.requirements.design/description/Requirements.odesign#//@ownedViewpoints[name='Requirements_ID']"/> @@ -4839,6 +4847,17 @@ <styles xmi:type="notation:ShapeStyle" xmi:id="_adBIYR4uEe2oAusR2-iOGg" fontName="Fira Code" fontHeight="8"/> <layoutConstraint xmi:type="notation:Bounds" xmi:id="_adBIYh4uEe2oAusR2-iOGg" x="70" y="-2" width="10" height="10"/> </children> + <children xmi:type="notation:Node" xmi:id="_mo73ANNbEe-1uL7-mHc_Jw" type="3012" element="_mn4HENNbEe-1uL7-mHc_Jw"> + <children xmi:type="notation:Node" xmi:id="_mo-TQNNbEe-1uL7-mHc_Jw" visible="false" type="5010"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_mo-TQdNbEe-1uL7-mHc_Jw" x="11"/> + </children> + <children xmi:type="notation:Node" xmi:id="_mpB9oNNbEe-1uL7-mHc_Jw" type="3005" element="_mn4HEdNbEe-1uL7-mHc_Jw"> + <styles xmi:type="notation:ShapeStyle" xmi:id="_mpB9odNbEe-1uL7-mHc_Jw" fontName="Fira Code"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_mpB9otNbEe-1uL7-mHc_Jw"/> + </children> + <styles xmi:type="notation:ShapeStyle" xmi:id="_mo73AdNbEe-1uL7-mHc_Jw" fontName="Fira Code" fontHeight="8"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_mo73AtNbEe-1uL7-mHc_Jw" x="140" y="90" width="10" height="10"/> + </children> <styles xmi:type="notation:ShapeStyle" xmi:id="_aVQlcR4sEe2oAusR2-iOGg" fontName="Fira Code" fontHeight="8"/> <layoutConstraint xmi:type="notation:Bounds" xmi:id="_aVQlch4sEe2oAusR2-iOGg" x="80" y="260" height="113"/> </children> @@ -5231,9 +5250,51 @@ <styles xmi:type="notation:ShapeStyle" xmi:id="_adBvdh4uEe2oAusR2-iOGg" fontName="Fira Code" fontHeight="8"/> <layoutConstraint xmi:type="notation:Bounds" xmi:id="_adBvdx4uEe2oAusR2-iOGg" x="-2" y="60" width="10" height="10"/> </children> + <children xmi:type="notation:Node" xmi:id="_mpCksNNbEe-1uL7-mHc_Jw" type="3012" element="_mn0csNNbEe-1uL7-mHc_Jw"> + <children xmi:type="notation:Node" xmi:id="_mpCks9NbEe-1uL7-mHc_Jw" visible="false" type="5010"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_mpCktNNbEe-1uL7-mHc_Jw" y="11"/> + </children> + <children xmi:type="notation:Node" xmi:id="_mpDLwNNbEe-1uL7-mHc_Jw" type="3005" element="_mn1DwNNbEe-1uL7-mHc_Jw"> + <styles xmi:type="notation:ShapeStyle" xmi:id="_mpDLwdNbEe-1uL7-mHc_Jw" fontName="Fira Code"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_mpDLwtNbEe-1uL7-mHc_Jw"/> + </children> + <styles xmi:type="notation:ShapeStyle" xmi:id="_mpCksdNbEe-1uL7-mHc_Jw" fontName="Fira Code" fontHeight="8"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_mpCkstNbEe-1uL7-mHc_Jw" x="20" y="-2" width="10" height="10"/> + </children> + <children xmi:type="notation:Node" xmi:id="_HJf7ANNjEe-1uL7-mHc_Jw" type="3012" element="_HItQ0NNjEe-1uL7-mHc_Jw"> + <children xmi:type="notation:Node" xmi:id="_HJf7A9NjEe-1uL7-mHc_Jw" visible="false" type="5010"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_HJf7BNNjEe-1uL7-mHc_Jw" x="11"/> + </children> + <children xmi:type="notation:Node" xmi:id="_p91KsNNlEe-1uL7-mHc_Jw" type="3005" element="_p9U0b9NlEe-1uL7-mHc_Jw"> + <styles xmi:type="notation:ShapeStyle" xmi:id="_p91KsdNlEe-1uL7-mHc_Jw" fontName="Fira Code"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_p91KstNlEe-1uL7-mHc_Jw"/> + </children> + <styles xmi:type="notation:ShapeStyle" xmi:id="_HJf7AdNjEe-1uL7-mHc_Jw" fontName="Fira Code" fontHeight="8"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_HJf7AtNjEe-1uL7-mHc_Jw" x="50" y="73" width="10" height="10"/> + </children> <styles xmi:type="notation:ShapeStyle" xmi:id="_dhlXgR4sEe2oAusR2-iOGg" fontName="Fira Code" fontHeight="8"/> <layoutConstraint xmi:type="notation:Bounds" xmi:id="_dhlXgh4sEe2oAusR2-iOGg" x="380" y="260" height="83"/> </children> + <children xmi:type="notation:Node" xmi:id="_F-_PsNNjEe-1uL7-mHc_Jw" type="2002" element="_F-OasNNjEe-1uL7-mHc_Jw"> + <children xmi:type="notation:Node" xmi:id="_F-_Ps9NjEe-1uL7-mHc_Jw" type="5006"/> + <children xmi:type="notation:Node" xmi:id="_F-_PtNNjEe-1uL7-mHc_Jw" type="7001"> + <styles xmi:type="notation:SortingStyle" xmi:id="_F-_PtdNjEe-1uL7-mHc_Jw"/> + <styles xmi:type="notation:FilteringStyle" xmi:id="_F-_PttNjEe-1uL7-mHc_Jw"/> + </children> + <children xmi:type="notation:Node" xmi:id="_HJgiENNjEe-1uL7-mHc_Jw" type="3012" element="_HIsCsNNjEe-1uL7-mHc_Jw"> + <children xmi:type="notation:Node" xmi:id="_HJgiE9NjEe-1uL7-mHc_Jw" visible="false" type="5010"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_HJgiFNNjEe-1uL7-mHc_Jw" x="11"/> + </children> + <children xmi:type="notation:Node" xmi:id="_pOA3UNNlEe-1uL7-mHc_Jw" type="3005" element="_pNhvKdNlEe-1uL7-mHc_Jw"> + <styles xmi:type="notation:ShapeStyle" xmi:id="_pOA3UdNlEe-1uL7-mHc_Jw" fontName="Fira Code"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_pOA3UtNlEe-1uL7-mHc_Jw"/> + </children> + <styles xmi:type="notation:ShapeStyle" xmi:id="_HJgiEdNjEe-1uL7-mHc_Jw" fontName="Fira Code" fontHeight="8"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_HJgiEtNjEe-1uL7-mHc_Jw" x="140" y="30" width="10" height="10"/> + </children> + <styles xmi:type="notation:ShapeStyle" xmi:id="_F-_PsdNjEe-1uL7-mHc_Jw" fontName="Fira Code" fontHeight="8"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_F-_PstNjEe-1uL7-mHc_Jw" x="180" y="440"/> + </children> <styles xmi:type="notation:DiagramStyle" xmi:id="_TmQW0h4sEe2oAusR2-iOGg"/> <edges xmi:type="notation:Edge" xmi:id="_fyjUkB4sEe2oAusR2-iOGg" type="4001" element="_fxztsB4sEe2oAusR2-iOGg" source="_fyZjkB4sEe2oAusR2-iOGg" target="_fyiGcx4sEe2oAusR2-iOGg"> <children xmi:type="notation:Node" xmi:id="_fyjUlB4sEe2oAusR2-iOGg" type="6001"> @@ -5635,6 +5696,38 @@ <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_Djedeh4xEe2oAusR2-iOGg" id="(0.5,0.5)"/> <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_Djedex4xEe2oAusR2-iOGg" id="(0.5,0.5)"/> </edges> + <edges xmi:type="notation:Edge" xmi:id="_mpFA8NNbEe-1uL7-mHc_Jw" type="4001" element="_mn7xcNNbEe-1uL7-mHc_Jw" source="_mpCksNNbEe-1uL7-mHc_Jw" target="_mo73ANNbEe-1uL7-mHc_Jw"> + <children xmi:type="notation:Node" xmi:id="_mpFoANNbEe-1uL7-mHc_Jw" type="6001"> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_mpFoAdNbEe-1uL7-mHc_Jw" y="-10"/> + </children> + <children xmi:type="notation:Node" xmi:id="_mpFoAtNbEe-1uL7-mHc_Jw" type="6002"> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_mpFoA9NbEe-1uL7-mHc_Jw" y="10"/> + </children> + <children xmi:type="notation:Node" xmi:id="_mpFoBNNbEe-1uL7-mHc_Jw" type="6003"> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_mpFoBdNbEe-1uL7-mHc_Jw" y="10"/> + </children> + <styles xmi:type="notation:ConnectorStyle" xmi:id="_mpFA8dNbEe-1uL7-mHc_Jw" jumpLinkStatus="Above" jumpLinkType="Tunnel"/> + <styles xmi:type="notation:FontStyle" xmi:id="_mpFA8tNbEe-1uL7-mHc_Jw" fontColor="9914954" fontName="Fira Code" fontHeight="8"/> + <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_mpFA89NbEe-1uL7-mHc_Jw" points="[-5, 2, 175, -90]$[-175, 89, 5, -3]"/> + <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_mpHdMNNbEe-1uL7-mHc_Jw" id="(0.5,0.5)"/> + <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_mpHdMdNbEe-1uL7-mHc_Jw" id="(0.5,0.5)"/> + </edges> + <edges xmi:type="notation:Edge" xmi:id="_HJhJINNjEe-1uL7-mHc_Jw" type="4001" element="_HIt34NNjEe-1uL7-mHc_Jw" source="_HJgiENNjEe-1uL7-mHc_Jw" target="_HJf7ANNjEe-1uL7-mHc_Jw"> + <children xmi:type="notation:Node" xmi:id="_HJhJJNNjEe-1uL7-mHc_Jw" type="6001"> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_HJhJJdNjEe-1uL7-mHc_Jw" y="-10"/> + </children> + <children xmi:type="notation:Node" xmi:id="_HJhJJtNjEe-1uL7-mHc_Jw" type="6002"> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_HJhJJ9NjEe-1uL7-mHc_Jw" y="10"/> + </children> + <children xmi:type="notation:Node" xmi:id="_HJhJKNNjEe-1uL7-mHc_Jw" type="6003"> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_HJhJKdNjEe-1uL7-mHc_Jw" y="10"/> + </children> + <styles xmi:type="notation:ConnectorStyle" xmi:id="_HJhJIdNjEe-1uL7-mHc_Jw" jumpLinkStatus="Above" jumpLinkType="Tunnel"/> + <styles xmi:type="notation:FontStyle" xmi:id="_HJhJItNjEe-1uL7-mHc_Jw" fontColor="9914954" fontName="Fira Code" fontHeight="8"/> + <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_HJhJI9NjEe-1uL7-mHc_Jw" points="[4, -5, -106, 132]$[105, -132, -5, 5]"/> + <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_HJhJKtNjEe-1uL7-mHc_Jw" id="(0.5,0.5)"/> + <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_HJhJK9NjEe-1uL7-mHc_Jw" id="(0.5,0.5)"/> + </edges> </data> </ownedAnnotationEntries> <ownedAnnotationEntries xmi:type="description:AnnotationEntry" uid="_TmgOcB4sEe2oAusR2-iOGg" source="DANNOTATION_CUSTOMIZATION_KEY"> @@ -5734,6 +5827,15 @@ </ownedStyle> <actualMapping xmi:type="description_1:NodeMapping" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@containerMappings[name='LAB%20Logical%20Component']/@borderedNodeMappings[name='LAB%20ComponentPort']"/> </ownedBorderedNodes> + <ownedBorderedNodes xmi:type="diagram:DNode" uid="_mn4HENNbEe-1uL7-mHc_Jw" name="CP 11" incomingEdges="_mn7xcNNbEe-1uL7-mHc_Jw" width="1" height="1"> + <target xmi:type="org.polarsys.capella.core.data.fa:ComponentPort" href="ContextDiagram.capella#684d4388-3615-40a7-b81d-f97647294a67"/> + <semanticElements xmi:type="org.polarsys.capella.core.data.fa:ComponentPort" href="ContextDiagram.capella#684d4388-3615-40a7-b81d-f97647294a67"/> + <graphicalFilters xmi:type="diagram:HideLabelFilter" uid="_mn4uIdNbEe-1uL7-mHc_Jw"/> + <ownedStyle xmi:type="diagram:WorkspaceImage" uid="_mn4HEdNbEe-1uL7-mHc_Jw" showIcon="false" hideLabelByDefault="true" workspacePath="/org.polarsys.capella.core.sirius.analysis/description/images/InFlowPort.png"> + <description xmi:type="style:WorkspaceImageDescription" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@containerMappings[name='LAB%20Logical%20Component']/@borderedNodeMappings[name='LAB%20ComponentPort']/@conditionnalStyles.1/@style"/> + </ownedStyle> + <actualMapping xmi:type="description_1:NodeMapping" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@containerMappings[name='LAB%20Logical%20Component']/@borderedNodeMappings[name='LAB%20ComponentPort']"/> + </ownedBorderedNodes> <arrangeConstraints>KEEP_LOCATION</arrangeConstraints> <arrangeConstraints>KEEP_SIZE</arrangeConstraints> <arrangeConstraints>KEEP_RATIO</arrangeConstraints> @@ -6072,6 +6174,24 @@ </ownedStyle> <actualMapping xmi:type="description_1:NodeMapping" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@containerMappings[name='LAB%20Logical%20Component']/@borderedNodeMappings[name='LAB%20ComponentPort']"/> </ownedBorderedNodes> + <ownedBorderedNodes xmi:type="diagram:DNode" uid="_mn0csNNbEe-1uL7-mHc_Jw" name="CP 19" outgoingEdges="_mn7xcNNbEe-1uL7-mHc_Jw" width="1" height="1"> + <target xmi:type="org.polarsys.capella.core.data.fa:ComponentPort" href="ContextDiagram.capella#5269e15c-69fb-45fd-88a0-08d4ab5f5211"/> + <semanticElements xmi:type="org.polarsys.capella.core.data.fa:ComponentPort" href="ContextDiagram.capella#5269e15c-69fb-45fd-88a0-08d4ab5f5211"/> + <graphicalFilters xmi:type="diagram:HideLabelFilter" uid="_mn2R4NNbEe-1uL7-mHc_Jw"/> + <ownedStyle xmi:type="diagram:WorkspaceImage" uid="_mn1DwNNbEe-1uL7-mHc_Jw" showIcon="false" hideLabelByDefault="true" workspacePath="/org.polarsys.capella.core.sirius.analysis/description/images/OutFlowPort.png"> + <description xmi:type="style:WorkspaceImageDescription" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@containerMappings[name='LAB%20Logical%20Component']/@borderedNodeMappings[name='LAB%20ComponentPort']/@conditionnalStyles.2/@style"/> + </ownedStyle> + <actualMapping xmi:type="description_1:NodeMapping" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@containerMappings[name='LAB%20Logical%20Component']/@borderedNodeMappings[name='LAB%20ComponentPort']"/> + </ownedBorderedNodes> + <ownedBorderedNodes xmi:type="diagram:DNode" uid="_HItQ0NNjEe-1uL7-mHc_Jw" name="CP 20" incomingEdges="_HIt34NNjEe-1uL7-mHc_Jw" width="1" height="1"> + <target xmi:type="org.polarsys.capella.core.data.fa:ComponentPort" href="ContextDiagram.capella#ec443534-9c07-44be-96d7-802bfa32e67b"/> + <semanticElements xmi:type="org.polarsys.capella.core.data.fa:ComponentPort" href="ContextDiagram.capella#ec443534-9c07-44be-96d7-802bfa32e67b"/> + <graphicalFilters xmi:type="diagram:HideLabelFilter" uid="_HItQ09NjEe-1uL7-mHc_Jw"/> + <ownedStyle xmi:type="diagram:WorkspaceImage" uid="_p9U0b9NlEe-1uL7-mHc_Jw" showIcon="false" hideLabelByDefault="true" workspacePath="/org.polarsys.capella.core.sirius.analysis/description/images/OutFlowPort.png"> + <description xmi:type="style:WorkspaceImageDescription" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@containerMappings[name='LAB%20Logical%20Component']/@borderedNodeMappings[name='LAB%20ComponentPort']/@conditionnalStyles.2/@style"/> + </ownedStyle> + <actualMapping xmi:type="description_1:NodeMapping" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@containerMappings[name='LAB%20Logical%20Component']/@borderedNodeMappings[name='LAB%20ComponentPort']"/> + </ownedBorderedNodes> <arrangeConstraints>KEEP_LOCATION</arrangeConstraints> <arrangeConstraints>KEEP_SIZE</arrangeConstraints> <arrangeConstraints>KEEP_RATIO</arrangeConstraints> @@ -6393,6 +6513,42 @@ </ownedStyle> <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@edgeMappings[name='LAB%20DataFlow%20between%20Function']"/> </ownedDiagramElements> + <ownedDiagramElements xmi:type="diagram:DEdge" uid="_mn7xcNNbEe-1uL7-mHc_Jw" name="C 28" sourceNode="_mn0csNNbEe-1uL7-mHc_Jw" targetNode="_mn4HENNbEe-1uL7-mHc_Jw"> + <target xmi:type="org.polarsys.capella.core.data.fa:ComponentExchange" href="ContextDiagram.capella#f350dfd4-5997-4fab-b3d2-9a5214ae263c"/> + <semanticElements xmi:type="org.polarsys.capella.core.data.fa:ComponentExchange" href="ContextDiagram.capella#f350dfd4-5997-4fab-b3d2-9a5214ae263c"/> + <ownedStyle xmi:type="diagram:EdgeStyle" uid="_mn8YgNNbEe-1uL7-mHc_Jw" targetArrow="NoDecoration" centered="Both" strokeColor="74,74,151"> + <description xmi:type="style:EdgeStyleDescription" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@edgeMappings[name='LAB%20DataFlow%20between%20Logical%20Components']/@conditionnalStyles.3/@style"/> + <centerLabelStyle xmi:type="diagram:CenterLabelStyle" uid="_mn8YgdNbEe-1uL7-mHc_Jw" labelColor="74,74,151"/> + </ownedStyle> + <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@edgeMappings[name='LAB%20DataFlow%20between%20Logical%20Components']"/> + </ownedDiagramElements> + <ownedDiagramElements xmi:type="diagram:DNodeContainer" uid="_F-OasNNjEe-1uL7-mHc_Jw" name="Real leftie"> + <target xmi:type="org.polarsys.capella.core.data.cs:Part" href="ContextDiagram.capella#22bf0991-c6cd-43dd-9129-9edff619c1bb"/> + <semanticElements xmi:type="org.polarsys.capella.core.data.cs:Part" href="ContextDiagram.capella#22bf0991-c6cd-43dd-9129-9edff619c1bb"/> + <semanticElements xmi:type="org.polarsys.capella.core.data.la:LogicalComponent" href="ContextDiagram.capella#3253a54d-6df2-4638-bd13-65e51c577758"/> + <ownedBorderedNodes xmi:type="diagram:DNode" uid="_HIsCsNNjEe-1uL7-mHc_Jw" name="CP 1" outgoingEdges="_HIt34NNjEe-1uL7-mHc_Jw" width="1" height="1"> + <target xmi:type="org.polarsys.capella.core.data.fa:ComponentPort" href="ContextDiagram.capella#ac7447ba-b89c-47f9-8390-d7db74c6e02c"/> + <semanticElements xmi:type="org.polarsys.capella.core.data.fa:ComponentPort" href="ContextDiagram.capella#ac7447ba-b89c-47f9-8390-d7db74c6e02c"/> + <graphicalFilters xmi:type="diagram:HideLabelFilter" uid="_HIspwtNjEe-1uL7-mHc_Jw"/> + <ownedStyle xmi:type="diagram:WorkspaceImage" uid="_pNhvKdNlEe-1uL7-mHc_Jw" showIcon="false" hideLabelByDefault="true" workspacePath="/org.polarsys.capella.core.sirius.analysis/description/images/InFlowPort.png"> + <description xmi:type="style:WorkspaceImageDescription" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@containerMappings[name='LAB%20Logical%20Component']/@borderedNodeMappings[name='LAB%20ComponentPort']/@conditionnalStyles.1/@style"/> + </ownedStyle> + <actualMapping xmi:type="description_1:NodeMapping" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@containerMappings[name='LAB%20Logical%20Component']/@borderedNodeMappings[name='LAB%20ComponentPort']"/> + </ownedBorderedNodes> + <ownedStyle xmi:type="diagram:FlatContainerStyle" uid="_F-PBwNNjEe-1uL7-mHc_Jw" borderSize="1" borderSizeComputationExpression="1" borderColor="74,74,151" backgroundStyle="GradientTopToBottom" backgroundColor="195,230,255" foregroundColor="150,177,218"> + <description xmi:type="style:FlatContainerStyleDescription" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@containerMappings[name='LAB%20Logical%20Component']/@style"/> + </ownedStyle> + <actualMapping xmi:type="description_1:ContainerMapping" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@containerMappings[name='LAB%20Logical%20Component']"/> + </ownedDiagramElements> + <ownedDiagramElements xmi:type="diagram:DEdge" uid="_HIt34NNjEe-1uL7-mHc_Jw" name="C 29" sourceNode="_HIsCsNNjEe-1uL7-mHc_Jw" targetNode="_HItQ0NNjEe-1uL7-mHc_Jw"> + <target xmi:type="org.polarsys.capella.core.data.fa:ComponentExchange" href="ContextDiagram.capella#fe3756df-2a89-45f3-91a3-0fc2e614afd0"/> + <semanticElements xmi:type="org.polarsys.capella.core.data.fa:ComponentExchange" href="ContextDiagram.capella#fe3756df-2a89-45f3-91a3-0fc2e614afd0"/> + <ownedStyle xmi:type="diagram:EdgeStyle" uid="_HIue8NNjEe-1uL7-mHc_Jw" targetArrow="NoDecoration" centered="Both" strokeColor="74,74,151"> + <description xmi:type="style:EdgeStyleDescription" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@edgeMappings[name='LAB%20DataFlow%20between%20Logical%20Components']/@conditionnalStyles.3/@style"/> + <centerLabelStyle xmi:type="diagram:CenterLabelStyle" uid="_HIue8dNjEe-1uL7-mHc_Jw" labelColor="74,74,151"/> + </ownedStyle> + <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@edgeMappings[name='LAB%20DataFlow%20between%20Logical%20Components']"/> + </ownedDiagramElements> <description xmi:type="description_1:DiagramDescription" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']"/> <currentConcern xmi:type="concern:ConcernDescription" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@concerns/@ownedConcernDescriptions.0"/> <activatedFilters xmi:type="filter:CompositeFilterDescription" href="platform:/plugin/org.polarsys.kitalpha.ad.integration.sirius/description/ad.odesign#//@ownedViewpoints[name='ad']/@ownedRepresentations[name='AD%20diagram']/@filters[name='ModelExtensionFilter']"/> @@ -18067,4 +18223,411 @@ <activatedLayers xmi:type="description_1:AdditionalLayer" href="platform:/plugin/org.polarsys.capella.vp.requirements.design/description/CapellaRequirements.odesign#//@ownedViewpoints[name='CapellaRequirements_ID']/@ownedRepresentationExtensions[name='CapellaViewpoints']/@layers[name='ReqVP_Requirements_Layer']"/> <target xmi:type="org.polarsys.capella.core.data.la:LogicalComponentPkg" href="ContextDiagram.capella#84c0978d-9a32-4f5b-8013-5b0b6adbfd73"/> </diagram:DSemanticDiagram> + <diagram:DSemanticDiagram uid="_37h3MNigEe-Gv-xXZhqgNA"> + <ownedAnnotationEntries xmi:type="description:AnnotationEntry" uid="_37tdYNigEe-Gv-xXZhqgNA" source="GMF_DIAGRAMS"> + <data xmi:type="notation:Diagram" xmi:id="_37tdYdigEe-Gv-xXZhqgNA" type="Sirius" element="_37h3MNigEe-Gv-xXZhqgNA" measurementUnit="Pixel"> + <children xmi:type="notation:Node" xmi:id="_4qkugNigEe-Gv-xXZhqgNA" type="2002" element="_4pqIgNigEe-Gv-xXZhqgNA"> + <children xmi:type="notation:Node" xmi:id="_4qmjsNigEe-Gv-xXZhqgNA" type="5006"/> + <children xmi:type="notation:Node" xmi:id="_4qnKwNigEe-Gv-xXZhqgNA" type="7001"> + <children xmi:type="notation:Node" xmi:id="__5BSMNigEe-Gv-xXZhqgNA" type="3008" element="__3xVANigEe-Gv-xXZhqgNA"> + <children xmi:type="notation:Node" xmi:id="__5BSM9igEe-Gv-xXZhqgNA" type="5005"/> + <children xmi:type="notation:Node" xmi:id="__5B5QNigEe-Gv-xXZhqgNA" type="7002"> + <styles xmi:type="notation:SortingStyle" xmi:id="__5B5QdigEe-Gv-xXZhqgNA"/> + <styles xmi:type="notation:FilteringStyle" xmi:id="__5B5QtigEe-Gv-xXZhqgNA"/> + </children> + <children xmi:type="notation:Node" xmi:id="_tpzTQNihEe-Gv-xXZhqgNA" type="3012" element="_tpApENihEe-Gv-xXZhqgNA"> + <children xmi:type="notation:Node" xmi:id="_tpz6UNihEe-Gv-xXZhqgNA" visible="false" type="5010"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_tpz6UdihEe-Gv-xXZhqgNA" x="11"/> + </children> + <children xmi:type="notation:Node" xmi:id="_tp0hYNihEe-Gv-xXZhqgNA" type="3005" element="_tpApEdihEe-Gv-xXZhqgNA"> + <styles xmi:type="notation:ShapeStyle" xmi:id="_tp0hYdihEe-Gv-xXZhqgNA" fontName="Sans"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_tp0hYtihEe-Gv-xXZhqgNA"/> + </children> + <styles xmi:type="notation:ShapeStyle" xmi:id="_tpzTQdihEe-Gv-xXZhqgNA" fontName="Sans" fontHeight="8"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_tpzTQtihEe-Gv-xXZhqgNA" x="140" y="30" width="10" height="10"/> + </children> + <children xmi:type="notation:Node" xmi:id="_3wJ4MNihEe-Gv-xXZhqgNA" type="3012" element="_3vWm8NihEe-Gv-xXZhqgNA"> + <children xmi:type="notation:Node" xmi:id="_3wKfQNihEe-Gv-xXZhqgNA" visible="false" type="5010"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_3wKfQdihEe-Gv-xXZhqgNA" y="11"/> + </children> + <children xmi:type="notation:Node" xmi:id="_3wLGUNihEe-Gv-xXZhqgNA" type="3005" element="_3vWm8dihEe-Gv-xXZhqgNA"> + <styles xmi:type="notation:ShapeStyle" xmi:id="_3wLGUdihEe-Gv-xXZhqgNA" fontName="Sans"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_3wLGUtihEe-Gv-xXZhqgNA"/> + </children> + <styles xmi:type="notation:ShapeStyle" xmi:id="_3wJ4MdihEe-Gv-xXZhqgNA" fontName="Sans" fontHeight="8"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_3wJ4MtihEe-Gv-xXZhqgNA" x="-2" y="30" width="10" height="10"/> + </children> + <styles xmi:type="notation:ShapeStyle" xmi:id="__5BSMdigEe-Gv-xXZhqgNA" fontName="Sans" fontHeight="8"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="__5BSMtigEe-Gv-xXZhqgNA" x="125" y="54"/> + </children> + <children xmi:type="notation:Node" xmi:id="_BN0h8NihEe-Gv-xXZhqgNA" type="3008" element="_BNGwQNihEe-Gv-xXZhqgNA"> + <children xmi:type="notation:Node" xmi:id="_BN1JANihEe-Gv-xXZhqgNA" type="5005"/> + <children xmi:type="notation:Node" xmi:id="_BN1JAdihEe-Gv-xXZhqgNA" type="7002"> + <styles xmi:type="notation:SortingStyle" xmi:id="_BN1JAtihEe-Gv-xXZhqgNA"/> + <styles xmi:type="notation:FilteringStyle" xmi:id="_BN1JA9ihEe-Gv-xXZhqgNA"/> + </children> + <children xmi:type="notation:Node" xmi:id="_xj3VENihEe-Gv-xXZhqgNA" type="3012" element="_xjHHINihEe-Gv-xXZhqgNA"> + <children xmi:type="notation:Node" xmi:id="_xj38INihEe-Gv-xXZhqgNA" visible="false" type="5010"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_xj38IdihEe-Gv-xXZhqgNA" x="11"/> + </children> + <children xmi:type="notation:Node" xmi:id="_xj4jMNihEe-Gv-xXZhqgNA" type="3005" element="_xjHHIdihEe-Gv-xXZhqgNA"> + <styles xmi:type="notation:ShapeStyle" xmi:id="_xj4jMdihEe-Gv-xXZhqgNA" fontName="Sans"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_xj4jMtihEe-Gv-xXZhqgNA"/> + </children> + <styles xmi:type="notation:ShapeStyle" xmi:id="_xj3VEdihEe-Gv-xXZhqgNA" fontName="Sans" fontHeight="8"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_xj3VEtihEe-Gv-xXZhqgNA" x="140" y="40" width="10" height="10"/> + </children> + <styles xmi:type="notation:ShapeStyle" xmi:id="_BN0h8dihEe-Gv-xXZhqgNA" fontName="Sans" fontHeight="8"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_BN0h8tihEe-Gv-xXZhqgNA" x="125" y="234"/> + </children> + <styles xmi:type="notation:SortingStyle" xmi:id="_4qnKwdigEe-Gv-xXZhqgNA"/> + <styles xmi:type="notation:FilteringStyle" xmi:id="_4qnKwtigEe-Gv-xXZhqgNA"/> + </children> + <children xmi:type="notation:Node" xmi:id="_pwQO0NihEe-Gv-xXZhqgNA" type="3012" element="_pvTMktihEe-Gv-xXZhqgNA"> + <children xmi:type="notation:Node" xmi:id="_pwQO09ihEe-Gv-xXZhqgNA" visible="false" type="5010"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_pwQO1NihEe-Gv-xXZhqgNA" y="11"/> + </children> + <children xmi:type="notation:Node" xmi:id="_pwQ14NihEe-Gv-xXZhqgNA" type="3005" element="_pvTzoNihEe-Gv-xXZhqgNA"> + <styles xmi:type="notation:ShapeStyle" xmi:id="_pwQ14dihEe-Gv-xXZhqgNA" fontName="Sans"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_pwQ14tihEe-Gv-xXZhqgNA"/> + </children> + <styles xmi:type="notation:ShapeStyle" xmi:id="_pwQO0dihEe-Gv-xXZhqgNA" fontName="Sans" fontHeight="8"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_pwQO0tihEe-Gv-xXZhqgNA" x="-2" y="80" width="10" height="10"/> + </children> + <styles xmi:type="notation:ShapeStyle" xmi:id="_4qkugdigEe-Gv-xXZhqgNA" fontName="Sans" fontHeight="8"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_4qkugtigEe-Gv-xXZhqgNA" x="370" y="140" width="303" height="363"/> + </children> + <children xmi:type="notation:Node" xmi:id="_FuURoNihEe-Gv-xXZhqgNA" type="2002" element="_FtlR0NihEe-Gv-xXZhqgNA"> + <children xmi:type="notation:Node" xmi:id="_FuURo9ihEe-Gv-xXZhqgNA" type="5006"/> + <children xmi:type="notation:Node" xmi:id="_FuU4sNihEe-Gv-xXZhqgNA" type="7001"> + <children xmi:type="notation:Node" xmi:id="_KXdnANihEe-Gv-xXZhqgNA" type="3008" element="_KWv1UNihEe-Gv-xXZhqgNA"> + <children xmi:type="notation:Node" xmi:id="_KXdnA9ihEe-Gv-xXZhqgNA" type="5005"/> + <children xmi:type="notation:Node" xmi:id="_KXdnBNihEe-Gv-xXZhqgNA" type="7002"> + <styles xmi:type="notation:SortingStyle" xmi:id="_KXdnBdihEe-Gv-xXZhqgNA"/> + <styles xmi:type="notation:FilteringStyle" xmi:id="_KXdnBtihEe-Gv-xXZhqgNA"/> + </children> + <children xmi:type="notation:Node" xmi:id="_tp0hY9ihEe-Gv-xXZhqgNA" type="3012" element="_tpBQIdihEe-Gv-xXZhqgNA"> + <children xmi:type="notation:Node" xmi:id="_tp0hZtihEe-Gv-xXZhqgNA" visible="false" type="5010"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_tp0hZ9ihEe-Gv-xXZhqgNA" y="11"/> + </children> + <children xmi:type="notation:Node" xmi:id="_tp1IcNihEe-Gv-xXZhqgNA" type="3005" element="_tpBQItihEe-Gv-xXZhqgNA"> + <styles xmi:type="notation:ShapeStyle" xmi:id="_tp1IcdihEe-Gv-xXZhqgNA" fontName="Sans"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_tp1IctihEe-Gv-xXZhqgNA"/> + </children> + <styles xmi:type="notation:ShapeStyle" xmi:id="_tp0hZNihEe-Gv-xXZhqgNA" fontName="Sans" fontHeight="8"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_tp0hZdihEe-Gv-xXZhqgNA" x="-2" y="20" width="10" height="10"/> + </children> + <styles xmi:type="notation:ShapeStyle" xmi:id="_KXdnAdihEe-Gv-xXZhqgNA" fontName="Sans" fontHeight="8"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_KXdnAtihEe-Gv-xXZhqgNA" x="15" y="44"/> + </children> + <children xmi:type="notation:Node" xmi:id="_NYNbMNihEe-Gv-xXZhqgNA" type="3008" element="_NXjT4NihEe-Gv-xXZhqgNA"> + <children xmi:type="notation:Node" xmi:id="_NYNbM9ihEe-Gv-xXZhqgNA" type="5005"/> + <children xmi:type="notation:Node" xmi:id="_NYOCQNihEe-Gv-xXZhqgNA" type="7002"> + <styles xmi:type="notation:SortingStyle" xmi:id="_NYOCQdihEe-Gv-xXZhqgNA"/> + <styles xmi:type="notation:FilteringStyle" xmi:id="_NYOCQtihEe-Gv-xXZhqgNA"/> + </children> + <children xmi:type="notation:Node" xmi:id="_xj4jM9ihEe-Gv-xXZhqgNA" type="3012" element="_xjHuMtihEe-Gv-xXZhqgNA"> + <children xmi:type="notation:Node" xmi:id="_xj5KQNihEe-Gv-xXZhqgNA" visible="false" type="5010"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_xj5KQdihEe-Gv-xXZhqgNA" y="11"/> + </children> + <children xmi:type="notation:Node" xmi:id="_xj5KQtihEe-Gv-xXZhqgNA" type="3005" element="_xjIVQNihEe-Gv-xXZhqgNA"> + <styles xmi:type="notation:ShapeStyle" xmi:id="_xj5KQ9ihEe-Gv-xXZhqgNA" fontName="Sans"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_xj5KRNihEe-Gv-xXZhqgNA"/> + </children> + <styles xmi:type="notation:ShapeStyle" xmi:id="_xj4jNNihEe-Gv-xXZhqgNA" fontName="Sans" fontHeight="8"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_xj4jNdihEe-Gv-xXZhqgNA" x="-2" y="40" width="10" height="10"/> + </children> + <styles xmi:type="notation:ShapeStyle" xmi:id="_NYNbMdihEe-Gv-xXZhqgNA" fontName="Sans" fontHeight="8"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_NYNbMtihEe-Gv-xXZhqgNA" x="35" y="204"/> + </children> + <styles xmi:type="notation:SortingStyle" xmi:id="_FuU4sdihEe-Gv-xXZhqgNA"/> + <styles xmi:type="notation:FilteringStyle" xmi:id="_FuU4stihEe-Gv-xXZhqgNA"/> + </children> + <styles xmi:type="notation:ShapeStyle" xmi:id="_FuURodihEe-Gv-xXZhqgNA" fontName="Sans" fontHeight="8"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_FuURotihEe-Gv-xXZhqgNA" x="820" y="190" width="221" height="311"/> + </children> + <children xmi:type="notation:Node" xmi:id="_O0ZFUNihEe-Gv-xXZhqgNA" type="2002" element="_Ozo3YNihEe-Gv-xXZhqgNA"> + <children xmi:type="notation:Node" xmi:id="_O0ZFU9ihEe-Gv-xXZhqgNA" type="5006"/> + <children xmi:type="notation:Node" xmi:id="_O0ZFVNihEe-Gv-xXZhqgNA" type="7001"> + <styles xmi:type="notation:SortingStyle" xmi:id="_O0ZFVdihEe-Gv-xXZhqgNA"/> + <styles xmi:type="notation:FilteringStyle" xmi:id="_O0ZFVtihEe-Gv-xXZhqgNA"/> + </children> + <children xmi:type="notation:Node" xmi:id="_pwQ149ihEe-Gv-xXZhqgNA" type="3012" element="_pvSlgNihEe-Gv-xXZhqgNA"> + <children xmi:type="notation:Node" xmi:id="_pwQ15tihEe-Gv-xXZhqgNA" visible="false" type="5010"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_pwQ159ihEe-Gv-xXZhqgNA" x="11"/> + </children> + <children xmi:type="notation:Node" xmi:id="_pwRc8NihEe-Gv-xXZhqgNA" type="3005" element="_pvSlgdihEe-Gv-xXZhqgNA"> + <styles xmi:type="notation:ShapeStyle" xmi:id="_pwRc8dihEe-Gv-xXZhqgNA" fontName="Sans"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_pwRc8tihEe-Gv-xXZhqgNA"/> + </children> + <styles xmi:type="notation:ShapeStyle" xmi:id="_pwQ15NihEe-Gv-xXZhqgNA" fontName="Sans" fontHeight="8"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_pwQ15dihEe-Gv-xXZhqgNA" x="140" y="30" width="10" height="10"/> + </children> + <styles xmi:type="notation:ShapeStyle" xmi:id="_O0ZFUdihEe-Gv-xXZhqgNA" fontName="Sans" fontHeight="8"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_O0ZFUtihEe-Gv-xXZhqgNA" x="100" y="190"/> + </children> + <styles xmi:type="notation:DiagramStyle" xmi:id="_37tdYtigEe-Gv-xXZhqgNA"/> + <edges xmi:type="notation:Edge" xmi:id="_pwSEANihEe-Gv-xXZhqgNA" type="4001" element="_pvUasNihEe-Gv-xXZhqgNA" source="_pwQ149ihEe-Gv-xXZhqgNA" target="_pwQO0NihEe-Gv-xXZhqgNA"> + <children xmi:type="notation:Node" xmi:id="_pwSEBNihEe-Gv-xXZhqgNA" type="6001"> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_pwSEBdihEe-Gv-xXZhqgNA" x="-2" y="-3"/> + </children> + <children xmi:type="notation:Node" xmi:id="_pwSEBtihEe-Gv-xXZhqgNA" type="6002"> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_pwSEB9ihEe-Gv-xXZhqgNA" x="9" y="2"/> + </children> + <children xmi:type="notation:Node" xmi:id="_pwSECNihEe-Gv-xXZhqgNA" type="6003"> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_pwSECdihEe-Gv-xXZhqgNA" x="-14" y="2"/> + </children> + <styles xmi:type="notation:ConnectorStyle" xmi:id="_pwSEAdihEe-Gv-xXZhqgNA" jumpLinkStatus="Above" jumpLinkType="Tunnel"/> + <styles xmi:type="notation:FontStyle" xmi:id="_pwSEAtihEe-Gv-xXZhqgNA" fontColor="9914954" fontName="Sans" fontHeight="8"/> + <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_pwSEA9ihEe-Gv-xXZhqgNA" points="[5, 0, -123, 0]$[123, 0, -5, 0]"/> + <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_pwSrENihEe-Gv-xXZhqgNA" id="(0.5,0.5)"/> + <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_pwSrEdihEe-Gv-xXZhqgNA" id="(0.5,0.5)"/> + </edges> + <edges xmi:type="notation:Edge" xmi:id="_tp1vgNihEe-Gv-xXZhqgNA" type="4001" element="_tpB3MdihEe-Gv-xXZhqgNA" source="_tpzTQNihEe-Gv-xXZhqgNA" target="_tp0hY9ihEe-Gv-xXZhqgNA"> + <children xmi:type="notation:Node" xmi:id="_tp1vhNihEe-Gv-xXZhqgNA" type="6001"> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_tp1vhdihEe-Gv-xXZhqgNA" x="-2" y="-10"/> + </children> + <children xmi:type="notation:Node" xmi:id="_tp1vhtihEe-Gv-xXZhqgNA" type="6002"> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_tp1vh9ihEe-Gv-xXZhqgNA" x="-1" y="9"/> + </children> + <children xmi:type="notation:Node" xmi:id="_tp1viNihEe-Gv-xXZhqgNA" type="6003"> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_tp1vidihEe-Gv-xXZhqgNA" x="-1" y="7"/> + </children> + <styles xmi:type="notation:ConnectorStyle" xmi:id="_tp1vgdihEe-Gv-xXZhqgNA" jumpLinkStatus="Above" jumpLinkType="Tunnel"/> + <styles xmi:type="notation:FontStyle" xmi:id="_tp1vgtihEe-Gv-xXZhqgNA" fontColor="9914954" fontName="Sans" fontHeight="8"/> + <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_tp1vg9ihEe-Gv-xXZhqgNA" points="[5, 0, -193, -30]$[193, 29, -5, -1]"/> + <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_tp1vitihEe-Gv-xXZhqgNA" id="(0.5,0.5)"/> + <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_tp1vi9ihEe-Gv-xXZhqgNA" id="(0.5,0.5)"/> + </edges> + <edges xmi:type="notation:Edge" xmi:id="_xj5xUNihEe-Gv-xXZhqgNA" type="4001" element="_xjI8UNihEe-Gv-xXZhqgNA" source="_xj3VENihEe-Gv-xXZhqgNA" target="_xj4jM9ihEe-Gv-xXZhqgNA"> + <children xmi:type="notation:Node" xmi:id="_xj5xVNihEe-Gv-xXZhqgNA" type="6001"> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_xj5xVdihEe-Gv-xXZhqgNA" x="-2" y="-10"/> + </children> + <children xmi:type="notation:Node" xmi:id="_xj5xVtihEe-Gv-xXZhqgNA" type="6002"> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_xj5xV9ihEe-Gv-xXZhqgNA" x="-1" y="8"/> + </children> + <children xmi:type="notation:Node" xmi:id="_xj5xWNihEe-Gv-xXZhqgNA" type="6003"> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_xj5xWdihEe-Gv-xXZhqgNA" x="1" y="10"/> + </children> + <styles xmi:type="notation:ConnectorStyle" xmi:id="_xj5xUdihEe-Gv-xXZhqgNA" jumpLinkStatus="Above" jumpLinkType="Tunnel"/> + <styles xmi:type="notation:FontStyle" xmi:id="_xj5xUtihEe-Gv-xXZhqgNA" fontColor="9914954" fontName="Sans" fontHeight="8"/> + <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_xj5xU9ihEe-Gv-xXZhqgNA" points="[5, 0, -213, -20]$[213, 19, -5, -1]"/> + <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_xj6YYNihEe-Gv-xXZhqgNA" id="(0.5,0.5)"/> + <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_xj6YYdihEe-Gv-xXZhqgNA" id="(0.5,0.5)"/> + </edges> + <edges xmi:type="notation:Edge" xmi:id="_3wLtYNihEe-Gv-xXZhqgNA" type="4001" element="_3vX1ENihEe-Gv-xXZhqgNA" source="_3wJ4MNihEe-Gv-xXZhqgNA" target="_pwQO0NihEe-Gv-xXZhqgNA"> + <children xmi:type="notation:Node" xmi:id="_3wLtZNihEe-Gv-xXZhqgNA" type="6001"> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_3wLtZdihEe-Gv-xXZhqgNA" y="-10"/> + </children> + <children xmi:type="notation:Node" xmi:id="_3wLtZtihEe-Gv-xXZhqgNA" type="6002"> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_3wLtZ9ihEe-Gv-xXZhqgNA" x="-1" y="11"/> + </children> + <children xmi:type="notation:Node" xmi:id="_3wLtaNihEe-Gv-xXZhqgNA" type="6003"> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_3wLtadihEe-Gv-xXZhqgNA" y="10"/> + </children> + <styles xmi:type="notation:ConnectorStyle" xmi:id="_3wLtYdihEe-Gv-xXZhqgNA" jumpLinkStatus="Above" jumpLinkType="Tunnel"/> + <styles xmi:type="notation:FontStyle" xmi:id="_3wLtYtihEe-Gv-xXZhqgNA" fontColor="9914954" fontName="Sans" fontHeight="8"/> + <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_3wLtY9ihEe-Gv-xXZhqgNA" points="[0, 0, 140, 8]$[-140, -8, 0, 0]"/> + <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_3wMUcNihEe-Gv-xXZhqgNA" id="(0.0,0.36764705882352944)"/> + <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_3wMUcdihEe-Gv-xXZhqgNA" id="(1.0,0.5)"/> + </edges> + </data> + </ownedAnnotationEntries> + <ownedAnnotationEntries xmi:type="description:AnnotationEntry" uid="_38PB0NigEe-Gv-xXZhqgNA" source="DANNOTATION_CUSTOMIZATION_KEY"> + <data xmi:type="diagram:ComputedStyleDescriptionRegistry" uid="_38PB0digEe-Gv-xXZhqgNA"/> + </ownedAnnotationEntries> + <ownedDiagramElements xmi:type="diagram:DNodeContainer" uid="_4pqIgNigEe-Gv-xXZhqgNA" name="Parent LC"> + <target xmi:type="org.polarsys.capella.core.data.cs:Part" href="ContextDiagram.capella#48210457-d83d-45d7-b663-28c44a79e0fa"/> + <semanticElements xmi:type="org.polarsys.capella.core.data.cs:Part" href="ContextDiagram.capella#48210457-d83d-45d7-b663-28c44a79e0fa"/> + <semanticElements xmi:type="org.polarsys.capella.core.data.la:LogicalComponent" href="ContextDiagram.capella#fd69347c-fca9-4cdd-ae44-9182e13c8d9d"/> + <ownedBorderedNodes xmi:type="diagram:DNode" uid="_pvTMktihEe-Gv-xXZhqgNA" name="CP 3" incomingEdges="_pvUasNihEe-Gv-xXZhqgNA _3vX1ENihEe-Gv-xXZhqgNA" width="1" height="1"> + <target xmi:type="org.polarsys.capella.core.data.fa:ComponentPort" href="ContextDiagram.capella#bcfc68d6-bce0-4281-9da5-eecd3ebc3025"/> + <semanticElements xmi:type="org.polarsys.capella.core.data.fa:ComponentPort" href="ContextDiagram.capella#bcfc68d6-bce0-4281-9da5-eecd3ebc3025"/> + <graphicalFilters xmi:type="diagram:HideLabelFilter" uid="_pvTzotihEe-Gv-xXZhqgNA"/> + <ownedStyle xmi:type="diagram:WorkspaceImage" uid="_pvTzoNihEe-Gv-xXZhqgNA" showIcon="false" hideLabelByDefault="true" workspacePath="/org.polarsys.capella.core.sirius.analysis/description/images/InFlowPort.png"> + <description xmi:type="style:WorkspaceImageDescription" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@containerMappings[name='LAB%20Logical%20Component']/@borderedNodeMappings[name='LAB%20ComponentPort']/@conditionnalStyles.1/@style"/> + </ownedStyle> + <actualMapping xmi:type="description_1:NodeMapping" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@containerMappings[name='LAB%20Logical%20Component']/@borderedNodeMappings[name='LAB%20ComponentPort']"/> + </ownedBorderedNodes> + <ownedStyle xmi:type="diagram:FlatContainerStyle" uid="_4prWoNigEe-Gv-xXZhqgNA" borderSize="1" borderSizeComputationExpression="1" borderColor="74,74,151" backgroundStyle="GradientTopToBottom" backgroundColor="195,230,255" foregroundColor="150,177,218"> + <description xmi:type="style:FlatContainerStyleDescription" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@containerMappings[name='LAB%20Logical%20Component']/@style"/> + </ownedStyle> + <actualMapping xmi:type="description_1:ContainerMapping" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@containerMappings[name='LAB%20Logical%20Component']"/> + <ownedDiagramElements xmi:type="diagram:DNodeContainer" uid="__3xVANigEe-Gv-xXZhqgNA" name="Child LC 1"> + <target xmi:type="org.polarsys.capella.core.data.cs:Part" href="ContextDiagram.capella#78b12b60-f134-48e4-8440-53e1b2b115c5"/> + <semanticElements xmi:type="org.polarsys.capella.core.data.cs:Part" href="ContextDiagram.capella#78b12b60-f134-48e4-8440-53e1b2b115c5"/> + <semanticElements xmi:type="org.polarsys.capella.core.data.la:LogicalComponent" href="ContextDiagram.capella#9f92e453-0692-4842-9e0c-4d36ab541acd"/> + <ownedBorderedNodes xmi:type="diagram:DNode" uid="_tpApENihEe-Gv-xXZhqgNA" name="CP 1" outgoingEdges="_tpB3MdihEe-Gv-xXZhqgNA" width="1" height="1"> + <target xmi:type="org.polarsys.capella.core.data.fa:ComponentPort" href="ContextDiagram.capella#3f2c5aeb-6351-458f-a581-a5eaa0e2b07f"/> + <semanticElements xmi:type="org.polarsys.capella.core.data.fa:ComponentPort" href="ContextDiagram.capella#3f2c5aeb-6351-458f-a581-a5eaa0e2b07f"/> + <graphicalFilters xmi:type="diagram:HideLabelFilter" uid="_tpBQINihEe-Gv-xXZhqgNA"/> + <arrangeConstraints>KEEP_LOCATION</arrangeConstraints> + <arrangeConstraints>KEEP_SIZE</arrangeConstraints> + <arrangeConstraints>KEEP_RATIO</arrangeConstraints> + <ownedStyle xmi:type="diagram:WorkspaceImage" uid="_tpApEdihEe-Gv-xXZhqgNA" showIcon="false" hideLabelByDefault="true" workspacePath="/org.polarsys.capella.core.sirius.analysis/description/images/OutFlowPort.png"> + <description xmi:type="style:WorkspaceImageDescription" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@containerMappings[name='LAB%20Logical%20Component']/@borderedNodeMappings[name='LAB%20ComponentPort']/@conditionnalStyles.2/@style"/> + </ownedStyle> + <actualMapping xmi:type="description_1:NodeMapping" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@containerMappings[name='LAB%20Logical%20Component']/@borderedNodeMappings[name='LAB%20ComponentPort']"/> + </ownedBorderedNodes> + <ownedBorderedNodes xmi:type="diagram:DNode" uid="_3vWm8NihEe-Gv-xXZhqgNA" name="CP 2" outgoingEdges="_3vX1ENihEe-Gv-xXZhqgNA" width="1" height="1"> + <target xmi:type="org.polarsys.capella.core.data.fa:ComponentPort" href="ContextDiagram.capella#ce221886-adfd-45f5-99cf-07baac99458d"/> + <semanticElements xmi:type="org.polarsys.capella.core.data.fa:ComponentPort" href="ContextDiagram.capella#ce221886-adfd-45f5-99cf-07baac99458d"/> + <graphicalFilters xmi:type="diagram:HideLabelFilter" uid="_3vXOAdihEe-Gv-xXZhqgNA"/> + <ownedStyle xmi:type="diagram:WorkspaceImage" uid="_3vWm8dihEe-Gv-xXZhqgNA" showIcon="false" hideLabelByDefault="true" workspacePath="/org.polarsys.capella.core.sirius.analysis/description/images/OutFlowPort.png"> + <description xmi:type="style:WorkspaceImageDescription" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@containerMappings[name='LAB%20Logical%20Component']/@borderedNodeMappings[name='LAB%20ComponentPort']/@conditionnalStyles.2/@style"/> + </ownedStyle> + <actualMapping xmi:type="description_1:NodeMapping" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@containerMappings[name='LAB%20Logical%20Component']/@borderedNodeMappings[name='LAB%20ComponentPort']"/> + </ownedBorderedNodes> + <arrangeConstraints>KEEP_LOCATION</arrangeConstraints> + <arrangeConstraints>KEEP_SIZE</arrangeConstraints> + <arrangeConstraints>KEEP_RATIO</arrangeConstraints> + <ownedStyle xmi:type="diagram:FlatContainerStyle" uid="__3xVAdigEe-Gv-xXZhqgNA" borderSize="1" borderSizeComputationExpression="1" borderColor="74,74,151" backgroundStyle="GradientTopToBottom" backgroundColor="195,230,255" foregroundColor="150,177,218"> + <description xmi:type="style:FlatContainerStyleDescription" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@containerMappings[name='LAB%20Logical%20Component']/@style"/> + </ownedStyle> + <actualMapping xmi:type="description_1:ContainerMapping" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@containerMappings[name='LAB%20Logical%20Component']"/> + </ownedDiagramElements> + <ownedDiagramElements xmi:type="diagram:DNodeContainer" uid="_BNGwQNihEe-Gv-xXZhqgNA" name="Child LC 2"> + <target xmi:type="org.polarsys.capella.core.data.cs:Part" href="ContextDiagram.capella#05f8fd0d-8fae-4d6d-b0d3-77428963d5c7"/> + <semanticElements xmi:type="org.polarsys.capella.core.data.cs:Part" href="ContextDiagram.capella#05f8fd0d-8fae-4d6d-b0d3-77428963d5c7"/> + <semanticElements xmi:type="org.polarsys.capella.core.data.la:LogicalComponent" href="ContextDiagram.capella#847991cf-546d-4817-b52f-a58b5a42d0e5"/> + <ownedBorderedNodes xmi:type="diagram:DNode" uid="_xjHHINihEe-Gv-xXZhqgNA" name="CP 1" outgoingEdges="_xjI8UNihEe-Gv-xXZhqgNA" width="1" height="1"> + <target xmi:type="org.polarsys.capella.core.data.fa:ComponentPort" href="ContextDiagram.capella#5fcfacff-479d-4ac0-a832-56396a07c1fe"/> + <semanticElements xmi:type="org.polarsys.capella.core.data.fa:ComponentPort" href="ContextDiagram.capella#5fcfacff-479d-4ac0-a832-56396a07c1fe"/> + <graphicalFilters xmi:type="diagram:HideLabelFilter" uid="_xjHuMdihEe-Gv-xXZhqgNA"/> + <arrangeConstraints>KEEP_LOCATION</arrangeConstraints> + <arrangeConstraints>KEEP_SIZE</arrangeConstraints> + <arrangeConstraints>KEEP_RATIO</arrangeConstraints> + <ownedStyle xmi:type="diagram:WorkspaceImage" uid="_xjHHIdihEe-Gv-xXZhqgNA" showIcon="false" hideLabelByDefault="true" workspacePath="/org.polarsys.capella.core.sirius.analysis/description/images/OutFlowPort.png"> + <description xmi:type="style:WorkspaceImageDescription" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@containerMappings[name='LAB%20Logical%20Component']/@borderedNodeMappings[name='LAB%20ComponentPort']/@conditionnalStyles.2/@style"/> + </ownedStyle> + <actualMapping xmi:type="description_1:NodeMapping" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@containerMappings[name='LAB%20Logical%20Component']/@borderedNodeMappings[name='LAB%20ComponentPort']"/> + </ownedBorderedNodes> + <arrangeConstraints>KEEP_LOCATION</arrangeConstraints> + <arrangeConstraints>KEEP_SIZE</arrangeConstraints> + <arrangeConstraints>KEEP_RATIO</arrangeConstraints> + <ownedStyle xmi:type="diagram:FlatContainerStyle" uid="_BNGwQdihEe-Gv-xXZhqgNA" borderSize="1" borderSizeComputationExpression="1" borderColor="74,74,151" backgroundStyle="GradientTopToBottom" backgroundColor="195,230,255" foregroundColor="150,177,218"> + <description xmi:type="style:FlatContainerStyleDescription" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@containerMappings[name='LAB%20Logical%20Component']/@style"/> + </ownedStyle> + <actualMapping xmi:type="description_1:ContainerMapping" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@containerMappings[name='LAB%20Logical%20Component']"/> + </ownedDiagramElements> + </ownedDiagramElements> + <ownedDiagramElements xmi:type="diagram:DNodeContainer" uid="_FtlR0NihEe-Gv-xXZhqgNA" name="Right LC"> + <target xmi:type="org.polarsys.capella.core.data.cs:Part" href="ContextDiagram.capella#debfa8e3-da1a-445f-b6c8-7d2ac5b5aeaf"/> + <semanticElements xmi:type="org.polarsys.capella.core.data.cs:Part" href="ContextDiagram.capella#debfa8e3-da1a-445f-b6c8-7d2ac5b5aeaf"/> + <semanticElements xmi:type="org.polarsys.capella.core.data.la:LogicalComponent" href="ContextDiagram.capella#b0a3a955-698f-4e66-8e71-599aa686290d"/> + <ownedStyle xmi:type="diagram:FlatContainerStyle" uid="_Ftl44NihEe-Gv-xXZhqgNA" borderSize="1" borderSizeComputationExpression="1" borderColor="74,74,151" backgroundStyle="GradientTopToBottom" backgroundColor="195,230,255" foregroundColor="150,177,218"> + <description xmi:type="style:FlatContainerStyleDescription" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@containerMappings[name='LAB%20Logical%20Component']/@style"/> + </ownedStyle> + <actualMapping xmi:type="description_1:ContainerMapping" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@containerMappings[name='LAB%20Logical%20Component']"/> + <ownedDiagramElements xmi:type="diagram:DNodeContainer" uid="_KWv1UNihEe-Gv-xXZhqgNA" name="Right LC 1"> + <target xmi:type="org.polarsys.capella.core.data.cs:Part" href="ContextDiagram.capella#a059ee90-c181-4d9c-9705-a7cc40704242"/> + <semanticElements xmi:type="org.polarsys.capella.core.data.cs:Part" href="ContextDiagram.capella#a059ee90-c181-4d9c-9705-a7cc40704242"/> + <semanticElements xmi:type="org.polarsys.capella.core.data.la:LogicalComponent" href="ContextDiagram.capella#fdbed138-965e-4abd-82f6-1dc794970fde"/> + <ownedBorderedNodes xmi:type="diagram:DNode" uid="_tpBQIdihEe-Gv-xXZhqgNA" name="CP 1" incomingEdges="_tpB3MdihEe-Gv-xXZhqgNA" width="1" height="1"> + <target xmi:type="org.polarsys.capella.core.data.fa:ComponentPort" href="ContextDiagram.capella#6afd0810-6274-4bac-8092-d59a9ef9bd99"/> + <semanticElements xmi:type="org.polarsys.capella.core.data.fa:ComponentPort" href="ContextDiagram.capella#6afd0810-6274-4bac-8092-d59a9ef9bd99"/> + <graphicalFilters xmi:type="diagram:HideLabelFilter" uid="_tpB3MNihEe-Gv-xXZhqgNA"/> + <arrangeConstraints>KEEP_LOCATION</arrangeConstraints> + <arrangeConstraints>KEEP_SIZE</arrangeConstraints> + <arrangeConstraints>KEEP_RATIO</arrangeConstraints> + <ownedStyle xmi:type="diagram:WorkspaceImage" uid="_tpBQItihEe-Gv-xXZhqgNA" showIcon="false" hideLabelByDefault="true" workspacePath="/org.polarsys.capella.core.sirius.analysis/description/images/InFlowPort.png"> + <description xmi:type="style:WorkspaceImageDescription" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@containerMappings[name='LAB%20Logical%20Component']/@borderedNodeMappings[name='LAB%20ComponentPort']/@conditionnalStyles.1/@style"/> + </ownedStyle> + <actualMapping xmi:type="description_1:NodeMapping" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@containerMappings[name='LAB%20Logical%20Component']/@borderedNodeMappings[name='LAB%20ComponentPort']"/> + </ownedBorderedNodes> + <ownedStyle xmi:type="diagram:FlatContainerStyle" uid="_KWv1UdihEe-Gv-xXZhqgNA" borderSize="1" borderSizeComputationExpression="1" borderColor="74,74,151" backgroundStyle="GradientTopToBottom" backgroundColor="195,230,255" foregroundColor="150,177,218"> + <description xmi:type="style:FlatContainerStyleDescription" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@containerMappings[name='LAB%20Logical%20Component']/@style"/> + </ownedStyle> + <actualMapping xmi:type="description_1:ContainerMapping" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@containerMappings[name='LAB%20Logical%20Component']"/> + </ownedDiagramElements> + <ownedDiagramElements xmi:type="diagram:DNodeContainer" uid="_NXjT4NihEe-Gv-xXZhqgNA" name="Right LC 2"> + <target xmi:type="org.polarsys.capella.core.data.cs:Part" href="ContextDiagram.capella#e2f83407-575c-42a1-8d82-7924ac0fb1f5"/> + <semanticElements xmi:type="org.polarsys.capella.core.data.cs:Part" href="ContextDiagram.capella#e2f83407-575c-42a1-8d82-7924ac0fb1f5"/> + <semanticElements xmi:type="org.polarsys.capella.core.data.la:LogicalComponent" href="ContextDiagram.capella#7fa21226-c6d0-418c-a061-cb38b207b852"/> + <ownedBorderedNodes xmi:type="diagram:DNode" uid="_xjHuMtihEe-Gv-xXZhqgNA" name="CP 1" incomingEdges="_xjI8UNihEe-Gv-xXZhqgNA" width="1" height="1"> + <target xmi:type="org.polarsys.capella.core.data.fa:ComponentPort" href="ContextDiagram.capella#93f2fe63-cb60-4640-a1ab-d078b560a241"/> + <semanticElements xmi:type="org.polarsys.capella.core.data.fa:ComponentPort" href="ContextDiagram.capella#93f2fe63-cb60-4640-a1ab-d078b560a241"/> + <graphicalFilters xmi:type="diagram:HideLabelFilter" uid="_xjIVQtihEe-Gv-xXZhqgNA"/> + <ownedStyle xmi:type="diagram:WorkspaceImage" uid="_xjIVQNihEe-Gv-xXZhqgNA" showIcon="false" hideLabelByDefault="true" workspacePath="/org.polarsys.capella.core.sirius.analysis/description/images/InFlowPort.png"> + <description xmi:type="style:WorkspaceImageDescription" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@containerMappings[name='LAB%20Logical%20Component']/@borderedNodeMappings[name='LAB%20ComponentPort']/@conditionnalStyles.1/@style"/> + </ownedStyle> + <actualMapping xmi:type="description_1:NodeMapping" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@containerMappings[name='LAB%20Logical%20Component']/@borderedNodeMappings[name='LAB%20ComponentPort']"/> + </ownedBorderedNodes> + <ownedStyle xmi:type="diagram:FlatContainerStyle" uid="_NXj68NihEe-Gv-xXZhqgNA" borderSize="1" borderSizeComputationExpression="1" borderColor="74,74,151" backgroundStyle="GradientTopToBottom" backgroundColor="195,230,255" foregroundColor="150,177,218"> + <description xmi:type="style:FlatContainerStyleDescription" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@containerMappings[name='LAB%20Logical%20Component']/@style"/> + </ownedStyle> + <actualMapping xmi:type="description_1:ContainerMapping" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@containerMappings[name='LAB%20Logical%20Component']"/> + </ownedDiagramElements> + </ownedDiagramElements> + <ownedDiagramElements xmi:type="diagram:DNodeContainer" uid="_Ozo3YNihEe-Gv-xXZhqgNA" name="Left LC"> + <target xmi:type="org.polarsys.capella.core.data.cs:Part" href="ContextDiagram.capella#04dcd5d0-2521-4d19-978a-443f63969a9c"/> + <semanticElements xmi:type="org.polarsys.capella.core.data.cs:Part" href="ContextDiagram.capella#04dcd5d0-2521-4d19-978a-443f63969a9c"/> + <semanticElements xmi:type="org.polarsys.capella.core.data.la:LogicalComponent" href="ContextDiagram.capella#9f7682b0-e830-4dd6-912b-0feb19ae0968"/> + <ownedBorderedNodes xmi:type="diagram:DNode" uid="_pvSlgNihEe-Gv-xXZhqgNA" name="CP 1" outgoingEdges="_pvUasNihEe-Gv-xXZhqgNA" width="1" height="1"> + <target xmi:type="org.polarsys.capella.core.data.fa:ComponentPort" href="ContextDiagram.capella#79780935-a7b3-4c2c-b664-67a9b2ce0d82"/> + <semanticElements xmi:type="org.polarsys.capella.core.data.fa:ComponentPort" href="ContextDiagram.capella#79780935-a7b3-4c2c-b664-67a9b2ce0d82"/> + <graphicalFilters xmi:type="diagram:HideLabelFilter" uid="_pvTMkdihEe-Gv-xXZhqgNA"/> + <ownedStyle xmi:type="diagram:WorkspaceImage" uid="_pvSlgdihEe-Gv-xXZhqgNA" showIcon="false" hideLabelByDefault="true" workspacePath="/org.polarsys.capella.core.sirius.analysis/description/images/OutFlowPort.png"> + <description xmi:type="style:WorkspaceImageDescription" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@containerMappings[name='LAB%20Logical%20Component']/@borderedNodeMappings[name='LAB%20ComponentPort']/@conditionnalStyles.2/@style"/> + </ownedStyle> + <actualMapping xmi:type="description_1:NodeMapping" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@containerMappings[name='LAB%20Logical%20Component']/@borderedNodeMappings[name='LAB%20ComponentPort']"/> + </ownedBorderedNodes> + <arrangeConstraints>KEEP_LOCATION</arrangeConstraints> + <arrangeConstraints>KEEP_SIZE</arrangeConstraints> + <arrangeConstraints>KEEP_RATIO</arrangeConstraints> + <ownedStyle xmi:type="diagram:FlatContainerStyle" uid="_Ozo3YdihEe-Gv-xXZhqgNA" borderSize="1" borderSizeComputationExpression="1" borderColor="74,74,151" backgroundStyle="GradientTopToBottom" backgroundColor="195,230,255" foregroundColor="150,177,218"> + <description xmi:type="style:FlatContainerStyleDescription" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@containerMappings[name='LAB%20Logical%20Component']/@style"/> + </ownedStyle> + <actualMapping xmi:type="description_1:ContainerMapping" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@containerMappings[name='LAB%20Logical%20Component']"/> + </ownedDiagramElements> + <ownedDiagramElements xmi:type="diagram:DEdge" uid="_pvUasNihEe-Gv-xXZhqgNA" name="Left to Parent" sourceNode="_pvSlgNihEe-Gv-xXZhqgNA" targetNode="_pvTMktihEe-Gv-xXZhqgNA"> + <target xmi:type="org.polarsys.capella.core.data.fa:ComponentExchange" href="ContextDiagram.capella#453903da-1cbd-4bb8-bab2-d83a825ee7d1"/> + <semanticElements xmi:type="org.polarsys.capella.core.data.fa:ComponentExchange" href="ContextDiagram.capella#453903da-1cbd-4bb8-bab2-d83a825ee7d1"/> + <ownedStyle xmi:type="diagram:EdgeStyle" uid="_pvUasdihEe-Gv-xXZhqgNA" targetArrow="NoDecoration" centered="Both" strokeColor="74,74,151"> + <description xmi:type="style:EdgeStyleDescription" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@edgeMappings[name='LAB%20DataFlow%20between%20Logical%20Components']/@conditionnalStyles.3/@style"/> + <centerLabelStyle xmi:type="diagram:CenterLabelStyle" uid="_pvUastihEe-Gv-xXZhqgNA" labelColor="74,74,151"/> + </ownedStyle> + <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@edgeMappings[name='LAB%20DataFlow%20between%20Logical%20Components']"/> + </ownedDiagramElements> + <ownedDiagramElements xmi:type="diagram:DEdge" uid="_tpB3MdihEe-Gv-xXZhqgNA" name="Child 1 to Right 1" sourceNode="_tpApENihEe-Gv-xXZhqgNA" targetNode="_tpBQIdihEe-Gv-xXZhqgNA"> + <target xmi:type="org.polarsys.capella.core.data.fa:ComponentExchange" href="ContextDiagram.capella#d89b2b08-0061-4b43-9bd6-af829f80aa2f"/> + <semanticElements xmi:type="org.polarsys.capella.core.data.fa:ComponentExchange" href="ContextDiagram.capella#d89b2b08-0061-4b43-9bd6-af829f80aa2f"/> + <ownedStyle xmi:type="diagram:EdgeStyle" uid="_tpCeQNihEe-Gv-xXZhqgNA" targetArrow="NoDecoration" centered="Both" strokeColor="74,74,151"> + <description xmi:type="style:EdgeStyleDescription" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@edgeMappings[name='LAB%20DataFlow%20between%20Logical%20Components']/@conditionnalStyles.3/@style"/> + <centerLabelStyle xmi:type="diagram:CenterLabelStyle" uid="_tpCeQdihEe-Gv-xXZhqgNA" labelColor="74,74,151"/> + </ownedStyle> + <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@edgeMappings[name='LAB%20DataFlow%20between%20Logical%20Components']"/> + </ownedDiagramElements> + <ownedDiagramElements xmi:type="diagram:DEdge" uid="_xjI8UNihEe-Gv-xXZhqgNA" name="Child 2 to Right 2" sourceNode="_xjHHINihEe-Gv-xXZhqgNA" targetNode="_xjHuMtihEe-Gv-xXZhqgNA"> + <target xmi:type="org.polarsys.capella.core.data.fa:ComponentExchange" href="ContextDiagram.capella#6ba4f3d9-6adb-4632-817e-23d86b9b0637"/> + <semanticElements xmi:type="org.polarsys.capella.core.data.fa:ComponentExchange" href="ContextDiagram.capella#6ba4f3d9-6adb-4632-817e-23d86b9b0637"/> + <ownedStyle xmi:type="diagram:EdgeStyle" uid="_xjI8UdihEe-Gv-xXZhqgNA" targetArrow="NoDecoration" centered="Both" strokeColor="74,74,151"> + <description xmi:type="style:EdgeStyleDescription" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@edgeMappings[name='LAB%20DataFlow%20between%20Logical%20Components']/@conditionnalStyles.3/@style"/> + <centerLabelStyle xmi:type="diagram:CenterLabelStyle" uid="_xjI8UtihEe-Gv-xXZhqgNA" labelColor="74,74,151"/> + </ownedStyle> + <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@edgeMappings[name='LAB%20DataFlow%20between%20Logical%20Components']"/> + </ownedDiagramElements> + <ownedDiagramElements xmi:type="diagram:DEdge" uid="_3vX1ENihEe-Gv-xXZhqgNA" name="Parent to Child 1" sourceNode="_3vWm8NihEe-Gv-xXZhqgNA" targetNode="_pvTMktihEe-Gv-xXZhqgNA"> + <target xmi:type="org.polarsys.capella.core.data.fa:ComponentExchange" href="ContextDiagram.capella#955b6e5d-df64-4805-8973-93756a4be879"/> + <semanticElements xmi:type="org.polarsys.capella.core.data.fa:ComponentExchange" href="ContextDiagram.capella#955b6e5d-df64-4805-8973-93756a4be879"/> + <ownedStyle xmi:type="diagram:EdgeStyle" uid="_3vX1EdihEe-Gv-xXZhqgNA" targetArrow="NoDecoration" centered="Both" strokeColor="74,74,151"> + <description xmi:type="style:EdgeStyleDescription" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@edgeMappings[name='LAB%20DataFlow%20between%20Logical%20Components']/@conditionnalStyles.3/@style"/> + <centerLabelStyle xmi:type="diagram:CenterLabelStyle" uid="_3vX1EtihEe-Gv-xXZhqgNA" labelColor="74,74,151"/> + </ownedStyle> + <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer/@edgeMappings[name='LAB%20DataFlow%20between%20Logical%20Components']"/> + </ownedDiagramElements> + <description xmi:type="description_1:DiagramDescription" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']"/> + <currentConcern xmi:type="concern:ConcernDescription" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@concerns/@ownedConcernDescriptions.0"/> + <activatedFilters xmi:type="filter:CompositeFilterDescription" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@filters[name='hide.simplified.diagram.based.component.exchanges.filter']"/> + <activatedFilters xmi:type="filter:CompositeFilterDescription" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@filters[name='hide.simplified.oriented.grouped.component.exchanges.filter']"/> + <activatedFilters xmi:type="filter:CompositeFilterDescription" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@filters[name='hide.sequencing.information.filter']"/> + <activatedFilters xmi:type="filter:CompositeFilterDescription" href="platform:/plugin/org.polarsys.kitalpha.ad.integration.sirius/description/ad.odesign#//@ownedViewpoints[name='ad']/@ownedRepresentations[name='AD%20diagram']/@filters[name='ModelExtensionFilter']"/> + <activatedFilters xmi:type="filter:CompositeFilterDescription" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@filters[name='hide.overlappedphysical.paths.label.filter']"/> + <activatedFilters xmi:type="filter:CompositeFilterDescription" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@filters[name='hide.simplified.group.of.component.exchanges.filter']"/> + <activatedFilters xmi:type="filter:CompositeFilterDescription" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@filters[name='hide.overlappedfunctional.chains.label.filter']"/> + <filterVariableHistory xmi:type="diagram:FilterVariableHistory" uid="_37ieQNigEe-Gv-xXZhqgNA"/> + <activatedLayers xmi:type="description_1:Layer" href="platform:/plugin/org.polarsys.capella.core.sirius.analysis/description/logical.odesign#//@ownedViewpoints[name='Logical%20Architecture']/@ownedRepresentations[name='Logical%20Architecture%20Blank']/@defaultLayer"/> + <activatedLayers xmi:type="description_1:AdditionalLayer" href="platform:/plugin/org.polarsys.capella.vp.requirements.design/description/CapellaRequirements.odesign#//@ownedViewpoints[name='CapellaRequirements_ID']/@ownedRepresentationExtensions[name='CapellaViewpoints']/@layers[name='ReqVP_Requirements_Layer']"/> + <target xmi:type="org.polarsys.capella.core.data.la:LogicalComponentPkg" href="ContextDiagram.capella#84c0978d-9a32-4f5b-8013-5b0b6adbfd73"/> + </diagram:DSemanticDiagram> </xmi:XMI> diff --git a/tests/data/ContextDiagram.capella b/tests/data/ContextDiagram.capella index 0900687b..9e3a267b 100644 --- a/tests/data/ContextDiagram.capella +++ b/tests/data/ContextDiagram.capella @@ -62,7 +62,7 @@ definition="#682bd51d-5451-4930-a97e-8bfca6c3a127" value="true"/> <ownedAttributes xsi:type="Requirements:DateValueAttribute" id="b97c09b5-948a-46e8-a656-69d764ddce7d" definition="#682bd51d-5451-4930-a97e-8bfca6c3a127" definitionProxy="" - value="2021-07-23T15:00:00.000+0200"/> + value="2021-07-23T13:00:00.000+0000"/> <ownedAttributes xsi:type="Requirements:IntegerValueAttribute" id="85dfd42c-7f6e-4236-a181-bdd784040431" definition="#682bd51d-5451-4930-a97e-8bfca6c3a127" value="10"/> <ownedAttributes xsi:type="Requirements:RealValueAttribute" id="d2231d14-854d-4625-b48b-6cf1c2554367" @@ -3729,6 +3729,17 @@ The predator is far away</bodies> <ownedComponentExchanges xsi:type="org.polarsys.capella.core.data.fa:ComponentExchange" id="43158e15-f8d1-49e3-bc01-7222edcbf839" name="C 28" source="#f413a1aa-61d7-41d1-aa0b-60744965204f" target="#36fb9559-675b-4efd-87fd-b20aa893cd44" kind="FLOW"/> + <ownedComponentExchanges xsi:type="org.polarsys.capella.core.data.fa:ComponentExchange" + id="453903da-1cbd-4bb8-bab2-d83a825ee7d1" name="Left to Parent" source="#79780935-a7b3-4c2c-b664-67a9b2ce0d82" + target="#bcfc68d6-bce0-4281-9da5-eecd3ebc3025" kind="FLOW"/> + <ownedComponentExchanges xsi:type="org.polarsys.capella.core.data.fa:ComponentExchange" + id="d89b2b08-0061-4b43-9bd6-af829f80aa2f" name="Child 1 to Right 1" + source="#3f2c5aeb-6351-458f-a581-a5eaa0e2b07f" target="#6afd0810-6274-4bac-8092-d59a9ef9bd99" + kind="FLOW"/> + <ownedComponentExchanges xsi:type="org.polarsys.capella.core.data.fa:ComponentExchange" + id="6ba4f3d9-6adb-4632-817e-23d86b9b0637" name="Child 2 to Right 2" + source="#5fcfacff-479d-4ac0-a832-56396a07c1fe" target="#93f2fe63-cb60-4640-a1ab-d078b560a241" + kind="FLOW"/> <ownedFeatures xsi:type="org.polarsys.capella.core.data.cs:Part" id="a3194240-cd17-4998-8f8b-785233487ec3" name="Campus" abstractType="#6583b560-6d2f-4190-baa2-94eef179c8ea"/> <ownedFeatures xsi:type="org.polarsys.capella.core.data.fa:ComponentPort" @@ -3802,6 +3813,12 @@ The predator is far away</bodies> name="Parent" abstractType="#eb966300-e6a2-40b4-ab9c-98fa1d6d04ad"/> <ownedFeatures xsi:type="org.polarsys.capella.core.data.cs:Part" id="11f75091-5849-48b3-b8bc-a660814944e9" name="LC 27" abstractType="#c6fd5f4e-f184-4a54-8320-f3bfd5ca7fdc"/> + <ownedFeatures xsi:type="org.polarsys.capella.core.data.cs:Part" id="48210457-d83d-45d7-b663-28c44a79e0fa" + name="Parent LC" abstractType="#fd69347c-fca9-4cdd-ae44-9182e13c8d9d"/> + <ownedFeatures xsi:type="org.polarsys.capella.core.data.cs:Part" id="debfa8e3-da1a-445f-b6c8-7d2ac5b5aeaf" + name="Right LC" abstractType="#b0a3a955-698f-4e66-8e71-599aa686290d"/> + <ownedFeatures xsi:type="org.polarsys.capella.core.data.cs:Part" id="04dcd5d0-2521-4d19-978a-443f63969a9c" + name="Left LC" abstractType="#9f7682b0-e830-4dd6-912b-0feb19ae0968"/> <ownedComponentRealizations xsi:type="org.polarsys.capella.core.data.cs:ComponentRealization" id="0f8b10b5-d460-4055-bd34-7e4a33e94b5e" targetElement="#230c4621-7e0a-4d0a-9db2-d4ba5e97b3df" sourceElement="#0d2edb8f-fa34-4e73-89ec-fb9a63001440"/> @@ -4083,6 +4100,9 @@ The predator is far away</bodies> <ownedFeatures xsi:type="org.polarsys.capella.core.data.fa:ComponentPort" id="60a1fd22-3ef8-46dd-8e0c-b4dbcca86ec0" name="CP 10" orientation="OUT" kind="FLOW"/> + <ownedFeatures xsi:type="org.polarsys.capella.core.data.fa:ComponentPort" + id="684d4388-3615-40a7-b81d-f97647294a67" name="CP 11" orientation="IN" + kind="FLOW"/> </ownedLogicalComponents> </ownedLogicalComponents> <ownedLogicalComponents xsi:type="org.polarsys.capella.core.data.la:LogicalComponent" @@ -4157,6 +4177,12 @@ The predator is far away</bodies> <ownedFeatures xsi:type="org.polarsys.capella.core.data.fa:ComponentPort" id="c06968be-09ae-4e9a-acc9-733c833a3c87" name="CP 18" orientation="IN" kind="FLOW"/> + <ownedFeatures xsi:type="org.polarsys.capella.core.data.fa:ComponentPort" + id="5269e15c-69fb-45fd-88a0-08d4ab5f5211" name="CP 19" orientation="OUT" + kind="FLOW"/> + <ownedFeatures xsi:type="org.polarsys.capella.core.data.fa:ComponentPort" + id="ec443534-9c07-44be-96d7-802bfa32e67b" name="CP 20" orientation="OUT" + kind="FLOW"/> </ownedLogicalComponents> <ownedLogicalComponents xsi:type="org.polarsys.capella.core.data.la:LogicalComponent" id="16b4fcc5-548d-4721-b62a-d3d5b1c1d2eb" name="Hierarchy"> @@ -4504,6 +4530,60 @@ The predator is far away</bodies> id="36fb9559-675b-4efd-87fd-b20aa893cd44" name="CP 1" orientation="IN" kind="FLOW"/> </ownedLogicalComponents> + <ownedLogicalComponents xsi:type="org.polarsys.capella.core.data.la:LogicalComponent" + id="fd69347c-fca9-4cdd-ae44-9182e13c8d9d" name="Parent LC"> + <ownedComponentExchanges xsi:type="org.polarsys.capella.core.data.fa:ComponentExchange" + id="955b6e5d-df64-4805-8973-93756a4be879" name="Parent to Child 1" + source="#ce221886-adfd-45f5-99cf-07baac99458d" target="#bcfc68d6-bce0-4281-9da5-eecd3ebc3025" + kind="FLOW"/> + <ownedFeatures xsi:type="org.polarsys.capella.core.data.cs:Part" id="78b12b60-f134-48e4-8440-53e1b2b115c5" + name="Child LC 1" abstractType="#9f92e453-0692-4842-9e0c-4d36ab541acd"/> + <ownedFeatures xsi:type="org.polarsys.capella.core.data.cs:Part" id="05f8fd0d-8fae-4d6d-b0d3-77428963d5c7" + name="Child LC 2" abstractType="#847991cf-546d-4817-b52f-a58b5a42d0e5"/> + <ownedFeatures xsi:type="org.polarsys.capella.core.data.fa:ComponentPort" + id="bcfc68d6-bce0-4281-9da5-eecd3ebc3025" name="CP 3" orientation="IN" + kind="FLOW"/> + <ownedLogicalComponents xsi:type="org.polarsys.capella.core.data.la:LogicalComponent" + id="9f92e453-0692-4842-9e0c-4d36ab541acd" name="Child LC 1"> + <ownedFeatures xsi:type="org.polarsys.capella.core.data.fa:ComponentPort" + id="3f2c5aeb-6351-458f-a581-a5eaa0e2b07f" name="CP 1" orientation="OUT" + kind="FLOW"/> + <ownedFeatures xsi:type="org.polarsys.capella.core.data.fa:ComponentPort" + id="ce221886-adfd-45f5-99cf-07baac99458d" name="CP 2" orientation="OUT" + kind="FLOW"/> + </ownedLogicalComponents> + <ownedLogicalComponents xsi:type="org.polarsys.capella.core.data.la:LogicalComponent" + id="847991cf-546d-4817-b52f-a58b5a42d0e5" name="Child LC 2"> + <ownedFeatures xsi:type="org.polarsys.capella.core.data.fa:ComponentPort" + id="5fcfacff-479d-4ac0-a832-56396a07c1fe" name="CP 1" orientation="OUT" + kind="FLOW"/> + </ownedLogicalComponents> + </ownedLogicalComponents> + <ownedLogicalComponents xsi:type="org.polarsys.capella.core.data.la:LogicalComponent" + id="b0a3a955-698f-4e66-8e71-599aa686290d" name="Right LC"> + <ownedFeatures xsi:type="org.polarsys.capella.core.data.cs:Part" id="a059ee90-c181-4d9c-9705-a7cc40704242" + name="Right LC 1" abstractType="#fdbed138-965e-4abd-82f6-1dc794970fde"/> + <ownedFeatures xsi:type="org.polarsys.capella.core.data.cs:Part" id="e2f83407-575c-42a1-8d82-7924ac0fb1f5" + name="Right LC 2" abstractType="#7fa21226-c6d0-418c-a061-cb38b207b852"/> + <ownedLogicalComponents xsi:type="org.polarsys.capella.core.data.la:LogicalComponent" + id="fdbed138-965e-4abd-82f6-1dc794970fde" name="Right LC 1"> + <ownedFeatures xsi:type="org.polarsys.capella.core.data.fa:ComponentPort" + id="6afd0810-6274-4bac-8092-d59a9ef9bd99" name="CP 1" orientation="IN" + kind="FLOW"/> + </ownedLogicalComponents> + <ownedLogicalComponents xsi:type="org.polarsys.capella.core.data.la:LogicalComponent" + id="7fa21226-c6d0-418c-a061-cb38b207b852" name="Right LC 2"> + <ownedFeatures xsi:type="org.polarsys.capella.core.data.fa:ComponentPort" + id="93f2fe63-cb60-4640-a1ab-d078b560a241" name="CP 1" orientation="IN" + kind="FLOW"/> + </ownedLogicalComponents> + </ownedLogicalComponents> + <ownedLogicalComponents xsi:type="org.polarsys.capella.core.data.la:LogicalComponent" + id="9f7682b0-e830-4dd6-912b-0feb19ae0968" name="Left LC"> + <ownedFeatures xsi:type="org.polarsys.capella.core.data.fa:ComponentPort" + id="79780935-a7b3-4c2c-b664-67a9b2ce0d82" name="CP 1" orientation="OUT" + kind="FLOW"/> + </ownedLogicalComponents> <ownedLogicalComponentPkgs xsi:type="org.polarsys.capella.core.data.la:LogicalComponentPkg" id="83d80c8a-e845-4fd9-bb6f-91fc32145785" name="LogicalComponents"> <ownedComponentExchanges xsi:type="org.polarsys.capella.core.data.fa:ComponentExchange" diff --git a/tests/test_context_diagrams.py b/tests/test_context_diagrams.py index 19be83e5..a5a1ec01 100644 --- a/tests/test_context_diagrams.py +++ b/tests/test_context_diagrams.py @@ -12,7 +12,6 @@ TEST_HIERARCHY_UUID = "16b4fcc5-548d-4721-b62a-d3d5b1c1d2eb" TEST_HIERARCHY_PARENTS_UUIDS = { "0d2edb8f-fa34-4e73-89ec-fb9a63001440", - "99a1d711-74af-4db7-af08-4dbd91c281ce", "53558f58-270e-4206-8fc7-3cf9e788fac9", } TEST_ACTIVITY_UUIDS = { @@ -125,16 +124,16 @@ def test_context_diagrams_rerender_on_parameter_change( ), pytest.param( [ - ("e1e48763-7479-4f3a-8134-c82bb6705d58", 126, 190), - ("8df45b70-15cc-4d3a-99e4-593516392c5a", 154, 234), - ("74af6883-25a0-446a-80f3-656f8a490b11", 266, 412), + ("e1e48763-7479-4f3a-8134-c82bb6705d58", 112, 187), + ("8df45b70-15cc-4d3a-99e4-593516392c5a", 140, 234), + ("74af6883-25a0-446a-80f3-656f8a490b11", 252, 412), ], id="LogicalComponent", ), pytest.param( [ - ("0c06cc88-8c77-46f2-8542-c08b1e8edd18", 112, 168), - ("9f1e1875-9ead-4af2-b428-c390786a436a", 112, 168), + ("0c06cc88-8c77-46f2-8542-c08b1e8edd18", 98, 164), + ("9f1e1875-9ead-4af2-b428-c390786a436a", 98, 164), ], id="LogicalFunction", ), @@ -142,7 +141,7 @@ def test_context_diagrams_rerender_on_parameter_change( [ ("6241d0c5-65d2-4c0b-b79c-a2a8ed7273f6", 36, 36), ("344a405e-c7e5-4367-8a9a-41d3d9a27f81", 40, 40), - ("230c4621-7e0a-4d0a-9db2-d4ba5e97b3df", 42, 60), + ("230c4621-7e0a-4d0a-9db2-d4ba5e97b3df", 42, 49), ], id="SystemComponent Root", ), @@ -227,14 +226,14 @@ def test_context_diagram_of_allocated_functions( def test_context_diagram_with_derived_interfaces( model: capellambse.MelodyModel, ) -> None: - obj = model.by_uuid(TEST_DERIVED_UUID) + obj = model.by_uuid("47c3130b-ec39-4365-a77a-5ab6365d1e2e") context_diagram = obj.context_diagram derived_diagram = context_diagram.render( None, display_derived_interfaces=True ) - assert len(derived_diagram) > 5 + assert len(derived_diagram) >= 15 @pytest.mark.parametrize( @@ -275,9 +274,9 @@ def test_context_diagram_hide_direct_children( } diag = obj.context_diagram - grey = diag.render(None, hide_direct_children=True) + grey = diag.render(None, blackbox=True) diag.invalidate_cache() - white = diag.render(None, hide_direct_children=False) + white = diag.render(None, blackbox=False) assert not {element.uuid for element in grey} & expected_hidden_uuids assert {element.uuid for element in white} & expected_hidden_uuids @@ -306,6 +305,24 @@ def test_context_diagram_display_unused_ports( assert unused_port_uuid in {element.uuid for element in bdiag} +def test_context_diagram_blackbox( + model: capellambse.MelodyModel, +) -> None: + obj = model.by_uuid("fd69347c-fca9-4cdd-ae44-9182e13c8d9d") + hidden_element_uuids = { + "9f92e453-0692-4842-9e0c-4d36ab541acd", + "847991cf-546d-4817-b52f-a58b5a42d0e5", + "955b6e5d-df64-4805-8973-93756a4be879", + "ce221886-adfd-45f5-99cf-07baac99458d", + } + + white = obj.context_diagram.render(None, blackbox=False) + black = obj.context_diagram.render(None, blackbox=True) + + assert {element.uuid for element in white} & hidden_element_uuids + assert not {element.uuid for element in black} & hidden_element_uuids + + @pytest.mark.skipif( sys.platform == "win32", reason="Wrong coordinates on Windows for some reason",