View Auto-Layoutο
Overviewο
The View Auto-Layout feature provides automatic graph layout algorithms for ArchiMate views, enabling diagram generation with minimal manual positioning. Two complementary algorithms are available:
Force-Directed Layout: Physics-based simulation using spring-embedder algorithm for organic, aesthetically pleasing layouts
Hierarchical Layout: Layer-based Sugiyama algorithm for structured, dependency-aware layouts
Quickstartο
Basic usage:
from pyArchimate.view.layout import apply_layout
from pyArchimate.view.layout.core import LayoutConfig
# Apply force-directed layout
config = LayoutConfig(algorithm="force_directed", spacing=50)
result = apply_layout(my_view, config)
# Apply hierarchical layout
config = LayoutConfig(algorithm="hierarchical", spacing=100)
result = apply_layout(my_view, config)
if result.success:
print(f"Laid out {result.elements_processed} elements in {result.layout_time_ms}ms")
Algorithmsο
Force-Directed Layoutο
The force-directed layout uses a Spring-Embedder physics simulation:
Repulsive forces: Nodes push each other away
Attractive forces: Connected nodes pull toward each other
Damping: Reduces oscillation and accelerates convergence
Early exit: Stops iterations when all nodes move less than 0.01px
Configuration parameters:
spacing: Minimum space between elements (pixels)margin: Margin around canvas edgeslayer_priority: βmandatoryβ or βsoftβ for ArchiMate layer constraints
Performance: <5 seconds for 500 elements on modern hardware
Hierarchical Layoutο
The hierarchical layout uses the Sugiyama layer-based algorithm:
Layer assignment: Elements grouped by dependency depth
Crossing minimization: Edge routing optimized to reduce crossing count
Node ordering: Elements arranged within layers for visual clarity
Configuration parameters:
spacing: Vertical/horizontal gap between layers and elementsmargin: Canvas marginlayer_priority: βmandatoryβ (enforce ArchiMate layers) or βsoftβ (use dependency levels)
Performance: <1 second for 500 elements
Auto-Formatο
Elements can be automatically standardized:
from pyArchimate.view.layout import apply_format
from pyArchimate.view.layout.core import LayoutConfig
config = LayoutConfig(alignment="grid", grid_size=10)
result = apply_format(my_view, config)
Features:
Standardized sizing: All elements use ArchiMate standard dimensions (120Γ55 pixels)
Font normalization: Segoe UI 9pt for all text
Grid alignment: Optional snap-to-grid positioning
Element exclusion: Specify elements to exclude from formatting
SVG Exportο
Views can be exported to SVG with automatic symbol rendering:
svg_string = my_view.to_svg()
my_view.to_svg(filepath="diagram.svg")
Features:
ArchiMate symbols: Official symbol definitions for all element types
Standard colors: ArchiMate-compliant color palette
Orthogonal routing: Connections use horizontal/vertical segments
Relationship styling: Official ArchiMate relationship rendering
Configuration Optionsο
LayoutConfig parameters:
config = LayoutConfig(
algorithm="force_directed", # or "hierarchical"
spacing=50, # Element spacing in pixels
margin=20, # Canvas margin in pixels
alignment="free", # or "grid" for grid snapping
grid_size=10, # Grid cell size when alignment="grid"
excluded_element_ids=[], # Element IDs to exclude from repositioning
routing_style="orthogonal", # or "mixed_45" for diagonal segments
layer_priority="mandatory", # or "soft" for layer constraints
node_size_constraints={} # Optional min/max size constraints
)
Edge Casesο
The layout algorithms handle several edge cases gracefully:
Single element: No layout needed, element remains at original position
No connections: Elements distributed across canvas using repulsion
Circular dependencies: Detected and resolved using topological analysis
Disconnected components: Each component laid out independently
Identical element sizes: Variance tracking ensures consistent spacing
Error Handlingο
Layout operations return a LayoutResult object:
result = apply_layout(view, config)
if result.success:
print(f"Success: {result.elements_processed} elements laid out")
else:
print(f"Error: {result.error_message}")
print(f"Quality metrics: {result.quality_metrics}")
Common error scenarios:
Invalid algorithm name β ValueError raised
Invalid spacing/margin values β ValueError raised
Invalid configuration β ValueError raised
Layout timeout β operation completes with partial results
Undo/Rollbackο
Layout operations can be undone:
from pyArchimate.view.layout import undo_layout
# Apply layout
result = apply_layout(view, config)
# Undo to restore previous positions
undo_result = undo_layout(view)
if undo_result.success:
print("Layout undone, original positions restored")
Performance Targetsο
Benchmark results on modern hardware (Intel i7, 16GB RAM):
Force-directed 100 elements: <500ms
Force-directed 300 elements: <2 seconds
Force-directed 500 elements: <5 seconds
Hierarchical 300 elements: <1 second
Hierarchical 500 elements: <1 second
SVG export overhead: <5% additional time
Advanced Topicsο
Custom Element Sizingο
Override standard sizing for specific elements:
# Per-element override
element.width = 150
element.height = 80
# Or use size constraints in config
config = LayoutConfig(
node_size_constraints={
"min_width": 100,
"max_width": 200,
"min_height": 50,
"max_height": 150
}
)
Element Exclusionο
Exclude specific elements from repositioning:
config = LayoutConfig(excluded_element_ids=[elem1.id, elem2.id])
result = apply_layout(view, config)
# elem1 and elem2 remain at original positions
Routing Stylesο
Two routing styles for connections:
orthogonal: Horizontal/vertical segments only (default, clean appearance)mixed_45: Horizontal/vertical with optional Β±45Β° angles (more direct paths)
config = LayoutConfig(routing_style="mixed_45")
result = apply_layout(view, config)
Layer Constraintsο
Two modes for enforcing ArchiMate layer hierarchy:
mandatory: Strictly enforce Business > Application > Technology > Motivationsoft: Prefer layer order but allow violations if needed for layout
config = LayoutConfig(layer_priority="soft") # More flexible layout
result = apply_layout(view, config)
Troubleshootingο
Layout appears too denseο
Increase
spacingparameter (default 50, try 75-100)Try hierarchical algorithm instead of force-directed
Elements are scattered too farο
Increase
marginparameter (adds inward force near edges)Try smaller
spacingvalue
Layout takes too longο
Force-directed with 500+ elements may take 5-10 seconds
Use hierarchical algorithm for faster results
Reduce spacing to decrease force calculation iterations
Connections overlap too muchο
Increase
spacingto create more roomTry different routing style (
mixed_45)Check if element exclusion is inadvertently skipping elements
See Alsoο
Architecture Overview - Detailed technical architecture
pyArchimate - API reference documentation