Feat: vis.js Layout-Switcher im XSL-Abhängigkeitsgraph (v1.2.0)

Layout-Umschaltung zwischen barnesHut, ForceAtlas2, Repulsion und hierarchischem
Layout mit konfigurierbaren Parametern pro Layout. Einstellungen werden persistent
in AppSettings gespeichert und beim Öffnen des Dialogs wiederhergestellt.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-21 19:32:29 +01:00
parent f7ef90079a
commit 4e65a6ad4c
7 changed files with 446 additions and 29 deletions
+60
View File
@@ -80,6 +80,65 @@ class XsltVersion(str, Enum):
XSLT_2_0_3_0 = "2.0/3.0" # s9api (XSLT 2.0 und 3.0)
class GraphLayout(str, Enum):
"""vis.js Physics-Solver / Layout-Modus."""
BARNES_HUT = "barnesHut"
FORCE_ATLAS2 = "forceAtlas2Based"
REPULSION = "repulsion"
HIERARCHICAL = "hierarchical"
class HierarchicalDirection(str, Enum):
"""Richtung für hierarchisches Layout."""
UD = "UD"
DU = "DU"
LR = "LR"
RL = "RL"
class HierarchicalSortMethod(str, Enum):
"""Sortiermethode für hierarchisches Layout."""
HUBSIZE = "hubsize"
DIRECTED = "directed"
class GraphLayoutSettings(BaseModel):
"""Persistierte vis.js Layout-Einstellungen für den XSL-Abhängigkeitsgraph."""
layout: GraphLayout = GraphLayout.BARNES_HUT
# barnesHut
bh_gravitational_constant: int = -3000
bh_central_gravity: float = 0.3
bh_spring_length: int = 150
bh_spring_constant: float = 0.04
bh_damping: float = 0.09
# forceAtlas2Based
fa_gravitational_constant: int = -50
fa_central_gravity: float = 0.01
fa_spring_length: int = 100
fa_spring_constant: float = 0.08
fa_damping: float = 0.4
# repulsion
re_node_distance: int = 120
re_central_gravity: float = 0.0
re_spring_length: int = 200
re_spring_constant: float = 0.05
re_damping: float = 0.09
# hierarchical
hi_direction: HierarchicalDirection = HierarchicalDirection.UD
hi_sort_method: HierarchicalSortMethod = HierarchicalSortMethod.HUBSIZE
hi_level_separation: int = 150
hi_node_spacing: int = 100
hi_tree_spacing: int = 200
class PostgreSqlDb(BaseModel):
id: int
name: str
@@ -147,6 +206,7 @@ class AppSettings(BaseSettings):
window_geometry: tuple[int, int, int, int] | None = None # (x, y, width, height)
splitter_sizes: list[int] | None = None # Splitter-Positionen
tree_column_widths: list[int] | None = None # TreeWidget-Spaltenbreiten
graph_layout_settings: GraphLayoutSettings = Field(default_factory=GraphLayoutSettings)
model_config = SettingsConfigDict(json_file=config_path)