Skip to content

Commit

Permalink
refactor(class-tree): Resolve suggestions from code review
Browse files Browse the repository at this point in the history
- Rename attribute to just `tree_diagram`
- Remove the `LAYOUT_OPTIONS` global dict
- Add controlability of `edgeLabels.sideSelection`
  • Loading branch information
ewuerger committed Oct 18, 2023
1 parent 8f85612 commit 2dfb59a
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 25 deletions.
4 changes: 2 additions & 2 deletions capellambse_context_diagrams/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,9 @@ def register_functional_context() -> None:


def register_class_tree() -> None:
"""Add the `class_tree_diagram` attribute to `ModelObject`s."""
"""Add the `tree_diagram` attribute to ``Class``es."""
common.set_accessor(
information.Class,
"class_tree_diagram",
"tree_diagram",
context.ClassTreeAccessor(DiagramType.CDB.value),
)
25 changes: 11 additions & 14 deletions capellambse_context_diagrams/collectors/class_tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,29 +12,26 @@
from .. import _elkjs, context
from . import generic, makers

LAYOUT_OPTIONS: _elkjs.LayoutOptions = {
"algorithm": "layered",
"edgeRouting": "ORTHOGONAL",
"elk.direction": "DOWN",
"partitioning.activate": True,
"edgeLabels.sideSelection": "ALWAYS_DOWN",
}


def collector(
diagram: context.ContextDiagram, params: dict[str, t.Any] | None = None
diagram: context.ContextDiagram, params: dict[str, t.Any]
) -> _elkjs.ELKInputData:
"""Return the class tree data for ELK."""
params = params or {}
assert isinstance(diagram.target, information.Class)
data = generic.collector(diagram, no_symbol=True)
if params.get("partitioning", False):
data["layoutOptions"]["partitioning.activate"] = True
data["children"][0]["layoutOptions"] = {}
data["children"][0]["layoutOptions"]["elk.partitioning.partition"] = 0
data["layoutOptions"] = LAYOUT_OPTIONS
data["layoutOptions"]["algorithm"] = (params or {})["algorithm"]
data["layoutOptions"]["elk.direction"] = (params or {})["direction"]
data["layoutOptions"]["edgeRouting"] = (params or {})["edgeRouting"]

data["layoutOptions"]["edgeLabels.sideSelection"] = params.get(
"edgeLabelsSide", "ALWAYS_DOWN"
)
data["layoutOptions"]["algorithm"] = params.get("algorithm", "layered")
data["layoutOptions"]["elk.direction"] = params.get("direction", "DOWN")
data["layoutOptions"]["edgeRouting"] = params.get(
"edgeRouting", "ORTHOGONAL"
)

made_boxes: set[str] = set()
for _, (source, prop, target, partition) in get_all_classes(
Expand Down
1 change: 1 addition & 0 deletions capellambse_context_diagrams/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -351,5 +351,6 @@ def _create_diagram(self, params: dict[str, t.Any]) -> cdiagram.Diagram:
params.setdefault("direction", "DOWN")
params.setdefault("edgeRouting", "POLYLINE")
params.setdefault("partitioning", True)
params.setdefault("edgeLabelsSide", "SMART_DOWN")
params["elkdata"] = class_tree.collector(self, params)
return super()._create_diagram(params)
17 changes: 13 additions & 4 deletions docs/class-tree.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,17 @@
# Class Tree Diagram

With release [`v0.5.35`](https://github.com/DSD-DBS/py-capellambse/releases/tag/v0.5.35) of [py-capellambse](https://github.com/DSD-DBS/py-capellambse) you can access the
`.class_tree_diagram` on `Class` objects. A class tree diagram shows a tree
made from all properties of the parent class.
`.tree_diagram` on [`Class`][capellambse.model.crosslayer.information.Class]
objects. A class tree diagram shows a tree made from all properties of the
parent class.

??? example "Class Tree of Root"

``` py
import capellambse

model = capellambse.MelodyModel("tests/data/ContextDiagram.aird")
diag = model.by_uuid("b7c7f442-377f-492c-90bf-331e66988bda").class_tree_diagram
diag = model.by_uuid("b7c7f442-377f-492c-90bf-331e66988bda").tree_diagram
diag.render("svgdiagram").save_drawing(pretty=True)
```
<figure markdown>
Expand Down Expand Up @@ -43,6 +44,13 @@ ELK. The available options are:
classes is its own partition.
- True (default)
- False
5. edgeLabelSide - Controls edge label placement.
- SMART_DOWN (default)
- SMART_UP
- ALWAYS_UP
- ALWAYS_DOWN
- DIRECTION_UP
- DIRECTION_DOWN

Here is an example that shows how convenient these parameters can be passed
before rendering:
Expand All @@ -53,12 +61,13 @@ before rendering:
import capellambse

model = capellambse.MelodyModel("tests/data/ContextDiagram.aird")
diag = model.by_uuid("b7c7f442-377f-492c-90bf-331e66988bda").class_tree_diagram
diag = model.by_uuid("b7c7f442-377f-492c-90bf-331e66988bda").tree_diagram
diag.render(
"svgdiagram",
edgeRouting="ORTHOGONAL",
direction="Right",
partitioning=False,
edgeLabelsSide="ALWAYS_DOWN",
).save_drawing(pretty=True)
```
<figure markdown>
Expand Down
3 changes: 2 additions & 1 deletion docs/gen_images.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ def generate_hierarchy_image() -> None:

def generate_class_tree_images() -> None:
obj = model.by_uuid(class_tree_uuid)
diag = obj.class_tree_diagram
diag = obj.tree_diagram
with mkdocs_gen_files.open(f"{str(dest / diag.name)}.svg", "w") as fd:
print(diag.render("svg"), file=fd)
with mkdocs_gen_files.open(
Expand All @@ -106,6 +106,7 @@ def generate_class_tree_images() -> None:
edgeRouting="ORTHOGONAL",
direction="Right",
partitioning=False,
edgeLabelsSide="ALWAYS_DOWN",
),
file=fd,
)
Expand Down
13 changes: 9 additions & 4 deletions tests/test_class_tree_diagrams.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,37 @@


@pytest.mark.parametrize("fmt", ["svgdiagram", "svg", None])
def test_class_tree_diagram_gets_rendered_successfully(
def test_tree_diagram_gets_rendered_successfully(
model: capellambse.MelodyModel, fmt: str
) -> None:
obj = model.by_uuid(CLASS_UUID)

diag = obj.class_tree_diagram
diag = obj.tree_diagram

assert diag.render(fmt)


@pytest.mark.parametrize("edgeRouting", ["SPLINE", "ORTHOGONAL", "POLYLINE"])
@pytest.mark.parametrize("direction", ["DOWN", "RIGHT"])
@pytest.mark.parametrize("partitioning", [True, False])
def test_class_tree_diagram_renders_with_additional_params(
@pytest.mark.parametrize(
"edgeLabelsSide", ["ALWAYS_DOWN", "DIRECTION_DOWN", "SMART_DOWN"]
)
def test_tree_diagram_renders_with_additional_params(
model: capellambse.MelodyModel,
edgeRouting: str,
direction: str,
partitioning: bool,
edgeLabelsSide: str,
) -> None:
obj = model.by_uuid(CLASS_UUID)

diag = obj.class_tree_diagram
diag = obj.tree_diagram

assert diag.render(
"svgdiagram",
edgeRouting=edgeRouting,
direction=direction,
partitioning=partitioning,
edgeLabelsSide=edgeLabelsSide,
)

0 comments on commit 2dfb59a

Please sign in to comment.