Skip to content

Commit

Permalink
merge: Merge pull request #27 from DSD-DBS/capellambse-internal-restr…
Browse files Browse the repository at this point in the history
…ucturing

fix: Anticipate internal restructuring of capellambse's aird module
  • Loading branch information
ewuerger authored Jan 17, 2023
2 parents 5c835a6 + f60ecde commit 43552a8
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 95 deletions.
2 changes: 1 addition & 1 deletion capellambse_context_diagrams/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
import typing as t
from importlib import metadata

from capellambse.aird import COLORS, CSSdef, capstyle
from capellambse.diagram import COLORS, CSSdef, capstyle
from capellambse.model import common
from capellambse.model.crosslayer import fa
from capellambse.model.layers import ctx, la, oa, pa
Expand Down
14 changes: 7 additions & 7 deletions capellambse_context_diagrams/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import logging
import typing as t

from capellambse import aird
from capellambse import diagram as cdiagram
from capellambse.model import common, diagram, modeltypes

from . import _elkjs, filters, serializers, styling
Expand Down Expand Up @@ -140,11 +140,11 @@ class ContextDiagram(diagram.AbstractDiagram):
symbol in the middle of the diagram, and instead keeps the
symbol small and only enlarges the surrounding box.
serializer
The serializer builds an `aird.Diagram` via
The serializer builds a `diagram.Diagram` via
[`serializers.DiagramSerializer.make_diagram`][capellambse_context_diagrams.serializers.DiagramSerializer.make_diagram]
by converting every
[`_elkjs.ELKOutputChild`][capellambse_context_diagrams._elkjs.ELKOutputChild]
into an `aird.Box`, `aird.Edge` or `aird.Circle`.
into a `diagram.Box`, `diagram.Edge` or `diagram.Circle`.
filters
A list of filter names that are applied during collection of
context. Currently this is only done in
Expand Down Expand Up @@ -191,7 +191,7 @@ def type(self) -> modeltypes.DiagramType:
def nodes(self) -> common.MixedElementList:
"""Return a list of all nodes visible in this diagram."""
adiagram = self.render(None)
assert isinstance(adiagram, aird.Diagram)
assert isinstance(adiagram, cdiagram.Diagram)
allids = {e.uuid for e in iter(adiagram)}
assert None not in allids
elems = []
Expand Down Expand Up @@ -248,7 +248,7 @@ def _create_diagram(
self,
params: dict[str, t.Any],
elkdata: _elkjs.ELKInputData | None = None,
) -> aird.Diagram:
) -> cdiagram.Diagram:
try:
data = elkdata or get_elkdata(self, params)
layout = _elkjs.call_elkjs(data)
Expand Down Expand Up @@ -283,7 +283,7 @@ def _create_diagram(
self,
params: dict[str, t.Any],
elkdata: _elkjs.ELKInputData | None = None,
) -> aird.Diagram:
) -> cdiagram.Diagram:
return super()._create_diagram(
params,
elkdata
Expand All @@ -306,7 +306,7 @@ def _create_diagram(
self,
params: dict[str, t.Any],
elkdata: _elkjs.ELKInputData | None = None,
) -> aird.Diagram:
) -> cdiagram.Diagram:
return super()._create_diagram(
params,
elkdata
Expand Down
4 changes: 2 additions & 2 deletions capellambse_context_diagrams/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def exchange_items(obj: common.GenericElement) -> str:
by ','.
"""
stringifier = importlib.import_module(
"capellambse.aird.parser._filters.global"
"capellambse.aird._filters.global"
)._stringify_exchange_items
return stringifier(obj, obj._model._loader)

Expand Down Expand Up @@ -84,7 +84,7 @@ def sort_exchange_items_label(
) -> None:
"""Sort the exchange items in the exchange label if value is true."""
global_filters = importlib.import_module(
"capellambse.aird.parser._filters.global"
"capellambse.aird._filters.global"
)
adjustments["labels_text"] = global_filters._stringify_exchange_items(
exchange, exchange._model._loader, value
Expand Down
107 changes: 40 additions & 67 deletions capellambse_context_diagrams/serializers.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# SPDX-FileCopyrightText: 2022 Copyright DB Netz AG and the capellambse-context-diagrams contributors
# SPDX-License-Identifier: Apache-2.0

"""This submodule provides a serializer that transform data from an ELK-
"""This submodule provides a serializer that transforms data from an ELK-
layouted diagram [_elkjs.ELKOutputData][capellambse_context_diagrams._elkjs.ELKOutputData]
according to [_elkjs.ELKInputData][capellambse_context_diagrams._elkjs.ELKInputData].
The pre-layouted data was collected with the functions from
Expand All @@ -11,8 +11,7 @@

import logging

from capellambse import aird
from capellambse.model import common
from capellambse import diagram

from . import _elkjs, collectors, context

Expand All @@ -32,26 +31,26 @@

class DiagramSerializer:
"""Serialize an ``elk_diagram`` into an
[`aird.Diagram`][capellambse.aird.diagram.Diagram].
[`diagram.Diagram`][capellambse.diagram.Diagram].
Attributes
----------
model
The [`MelodyModel`][capellambse.model.MelodyModel] instance.
aird_diagram
The created [`aird.Diagram`][capellambse.aird.diagram.Diagram]
diagram
The created [`diagram.Diagram`][capellambse.diagram.Diagram]
instance.
"""

aird_diagram: aird.Diagram
diagram: diagram.Diagram

def __init__(self, elk_diagram: context.ContextDiagram) -> None:
self.model = elk_diagram.target._model
self._diagram = elk_diagram
self._cache: dict[str, aird.Box] = {}
self._cache: dict[str, diagram.Box] = {}

def make_diagram(self, data: _elkjs.ELKOutputData) -> aird.Diagram:
"""Transform a layouted diagram into an `aird.Diagram`.
def make_diagram(self, data: _elkjs.ELKOutputData) -> diagram.Diagram:
"""Transform a layouted diagram into an `diagram.Diagram`.
Parameters
----------
Expand All @@ -61,49 +60,49 @@ def make_diagram(self, data: _elkjs.ELKOutputData) -> aird.Diagram:
Returns
-------
diagram
A [`aird.Diagram`][capellambse.aird.diagram.Diagram] constructed
A [`diagram.Diagram`][capellambse.diagram.Diagram] constructed
from the input data.
"""
self.aird_diagram = aird.Diagram(
self.diagram = diagram.Diagram(
self._diagram.name, styleclass=self._diagram.styleclass
)
for child in data["children"]:
self.deserialize_child(child, aird.Vector2D(), None)
self.deserialize_child(child, diagram.Vector2D(), None)

self.aird_diagram.calculate_viewport()
return self.aird_diagram
self.diagram.calculate_viewport()
return self.diagram

def deserialize_child(
self,
child: _elkjs.ELKOutputChild,
ref: aird.Vector2D,
parent: aird.Box | aird.Edge | None,
ref: diagram.Vector2D,
parent: diagram.Box | diagram.Edge | None,
) -> None:
"""Converts a `child` into aird elements and adds it to the
diagram.
Parameters
----------
child : _elkjs.ELKOutputChild
child
The child to deserialize.
ref : aird.Vector2D
ref
The reference point of the child.
parent : aird.Box | aird.Edge | None
parent
The parent of the child. This is either a box or an edge.
See Also
--------
[`aird.Box`][capellambse.aird.diagram.Box] : Box class type.
[`aird.Edge`][capellambse.aird.diagram.Edge] : Edge class type.
[`aird.Circle`][capellambse.aird.diagram.Circle] : Circle class
[`diagram.Box`][capellambse.diagram.Box] : Box class type.
[`diagram.Edge`][capellambse.diagram.Edge] : Edge class type.
[`diagram.Circle`][capellambse.diagram.Circle] : Circle class
type.
[`aird.Diagram`][capellambse.aird.diagram.Diagram] : Diagram
[`diagram.Diagram`][capellambse.diagram.Diagram] : Diagram
class type that stores all previously named classes.
"""
styleclass: str | None = self.get_styleclass(child["id"])
element: aird.Box | aird.Edge
element: diagram.Box | diagram.Edge
if child["type"] in {"node", "port"}:
assert parent is None or isinstance(parent, aird.Box)
assert parent is None or isinstance(parent, diagram.Box)
has_symbol_cls = False
try:
obj = self.model.by_uuid(child["id"])
Expand All @@ -123,7 +122,7 @@ class type that stores all previously named classes.

ref += (child["position"]["x"], child["position"]["y"]) # type: ignore
size = (child["size"]["width"], child["size"]["height"]) # type: ignore
element = aird.Box(
element = diagram.Box(
ref,
size,
uuid=child["id"],
Expand All @@ -133,38 +132,38 @@ class type that stores all previously named classes.
styleoverrides=self.get_styleoverrides(child),
)
element.JSON_TYPE = box_type
self.aird_diagram.add_element(element)
self.diagram.add_element(element)
self._cache[child["id"]] = element
elif child["type"] == "edge":
element = aird.Edge(
element = diagram.Edge(
[
ref + (point["x"], point["y"])
for point in child["routingPoints"]
],
uuid=child["id"],
source=self.aird_diagram[child["sourceId"]],
target=self.aird_diagram[child["targetId"]],
source=self.diagram[child["sourceId"]],
target=self.diagram[child["targetId"]],
styleclass=styleclass,
styleoverrides=self.get_styleoverrides(child),
)
self.aird_diagram.add_element(element)
self.diagram.add_element(element)
self._cache[child["id"]] = element
elif child["type"] == "label":
assert parent is not None
if isinstance(parent, aird.Box) and not parent.port:
if isinstance(parent, diagram.Box) and not parent.port:
if parent.JSON_TYPE != "symbol":
parent.label = child["text"]
else:
parent.label = aird.Box(
parent.label = diagram.Box(
ref + (child["position"]["x"], child["position"]["y"]),
(child["size"]["width"], child["size"]["height"]),
label=child["text"],
# parent=parent,
)
else:
assert isinstance(parent, aird.Edge)
assert isinstance(parent, diagram.Edge)
parent.labels = [
aird.Box(
diagram.Box(
ref + (child["position"]["x"], child["position"]["y"]),
(child["size"]["width"], child["size"]["height"]),
label=child["text"],
Expand All @@ -175,14 +174,14 @@ class type that stores all previously named classes.
element = parent
elif child["type"] == "junction":
uuid = child["id"].split("_", maxsplit=1)[0]
element = aird.Circle(
aird.Vector2D(**child["position"]),
element = diagram.Circle(
diagram.Vector2D(**child["position"]),
5,
uuid=child["id"],
styleclass=self.get_styleclass(uuid),
styleoverrides=self.get_styleoverrides(child),
)
self.aird_diagram.add_element(element)
self.diagram.add_element(element)
else:
logger.warning("Received unknown type %s", child["type"])
return
Expand All @@ -197,14 +196,14 @@ def get_styleclass(self, uuid: str) -> str | None:
styleclass: str | None
try:
melodyobj = self._diagram._model.by_uuid(uuid)
styleclass = get_styleclass(melodyobj)
styleclass = diagram.get_styleclass(melodyobj)
except KeyError:
styleclass = None
return styleclass

def get_styleoverrides(
self, child: _elkjs.ELKOutputChild
) -> aird.diagram._StyleOverrides | None:
) -> diagram.StyleOverrides | None:
"""Return
[`styling.CSSStyles`][capellambse_context_diagrams.styling.CSSStyles]
from a given
Expand All @@ -220,29 +219,3 @@ def get_styleoverrides(

styleoverrides = style_condition(obj)
return styleoverrides


def get_styleclass(obj: common.GenericElement) -> str:
"""Return the styleclass for a given `obj`."""
styleclass = obj.__class__.__name__
styleclass = (
aird.parser._semantic.STYLECLASS_LOOKUP.get(
styleclass, (styleclass, None)
)[0]
or styleclass
)
if styleclass.endswith("Component"):
styleclass = "".join(
(
styleclass[: -len("Component")],
"Human" * obj.is_human,
obj.nature.name.capitalize() if hasattr(obj, "nature") else "",
("Component", "Actor")[obj.is_actor],
)
)
elif styleclass == "CP":
try:
styleclass += f'_{obj._element.attrib["orientation"]}'
except KeyError:
styleclass = "CP_UNSET"
return styleclass
13 changes: 7 additions & 6 deletions capellambse_context_diagrams/styling.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@

import typing as t

from capellambse import aird
from capellambse import diagram
from capellambse.diagram import capstyle
from capellambse.model import common

CSSStyles = t.Union[aird.diagram._StyleOverrides, None]
CSSStyles = t.Union[diagram.StyleOverrides, None]
"""
A dictionary with CSS styles. The keys are the attribute names and the
values can be of the types `str`, `aird.RGB` and even
Expand All @@ -21,7 +22,7 @@
[parent_is_actor_fills_blue][capellambse_context_diagrams.styling.parent_is_actor_fills_blue]
"""
Styler = t.Callable[
[common.GenericElement], t.Union[aird.diagram._StyleOverrides, None]
[common.GenericElement], t.Union[diagram.StyleOverrides, None]
]
"""Function that produces `CSSStyles` for given obj."""

Expand All @@ -34,10 +35,10 @@ def parent_is_actor_fills_blue(obj: common.GenericElement) -> CSSStyles:
if obj.owner.is_actor:
return {
"fill": [
aird.capstyle.COLORS["_CAP_Actor_Blue_min"],
aird.capstyle.COLORS["_CAP_Actor_Blue"],
capstyle.COLORS["_CAP_Actor_Blue_min"],
capstyle.COLORS["_CAP_Actor_Blue"],
],
"stroke": aird.capstyle.COLORS["_CAP_Actor_Border_Blue"],
"stroke": capstyle.COLORS["_CAP_Actor_Border_Blue"],
}
except AttributeError:
pass
Expand Down
4 changes: 2 additions & 2 deletions docs/gen_images.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import pathlib

import mkdocs_gen_files
from capellambse import MelodyModel, aird
from capellambse import MelodyModel, diagram

from capellambse_context_diagrams import context, filters, styling

Expand Down Expand Up @@ -98,7 +98,7 @@ def generate_styling_image(
lost,
dict(
styling.BLUE_ACTOR_FNCS,
**{"junction": lambda _: {"fill": aird.RGB(220, 20, 60)}}, # type: ignore
**{"junction": lambda _: {"fill": diagram.RGB(220, 20, 60)}}, # type: ignore
),
"red junction",
)
Expand Down
Loading

0 comments on commit 43552a8

Please sign in to comment.