Skip to content

Latest commit

 

History

History
368 lines (288 loc) · 10.1 KB

File metadata and controls

368 lines (288 loc) · 10.1 KB

ELK Activation Guide for ArcViz

Objective

Activate ELK as the default layout engine, with Dagre as fallback.

Changes Made

✅ 1. HTML Template (arcviz_explorer_template.html)

Lines 8-13: Added ELK + initialization

<script src="https://d3js.org/d3.v7.min.js"></script>
<script src="https://unpkg.com/elkjs@0.9.3/lib/elk.bundled.js"></script>
<script src="https://unpkg.com/dagre-d3@0.6.4/dist/dagre-d3.min.js"></script>
<script>
    // Initialize ELK layout engine
    const elk = new ELK();
</script>

Lines 17-45: Updated configuration

const ARCVIZ_CONFIG = {
    // Layout Engine Selection
    engine: 'elk',                  // 'elk' (default) | 'dagre' (fallback)
    
    // ELK Layout Configuration (Primary)
    elk: {
        algorithm: 'layered',
        'elk.direction': 'DOWN',
        'elk.hierarchyHandling': 'INCLUDE_CHILDREN',
        'elk.layered.spacing.nodeNodeBetweenLayers': 200,
        'elk.spacing.nodeNode': 80,
        'elk.spacing.edgeNode': 40,
        // ... config complète
    },
    
    // Dagre Layout Configuration (Fallback)
    dagre: {
        rankdir: 'TB',
        nodesep: 350,
        // ... config existante
    },
    // ... reste de la config
};

Lines 897-912: Modified renderDiagram function

async function renderDiagram() {
    const diagramData = archData.diagram;
    
    if (!diagramData || !diagramData.nodes || !diagramData.layers) {
        console.error('Invalid diagram data:', diagramData);
        return;
    }
    
    console.log(`🎨 ArcViz Engine: ${ARCVIZ_CONFIG.engine.toUpperCase()}`);
    
    if (ARCVIZ_CONFIG.engine === 'elk') {
        await renderWithELK(diagramData);
    } else {
        renderWithDagre(diagramData);
    }
}

Line 914: Renamed Dagre function

function renderWithDagre(diagramData) {
    console.log('📊 Using Dagre-D3 layout engine...');
    // ... code Dagre existant inchangé
}

✅ 2. ELK Renderer (arcviz_elk_renderer.js)

Complete file created with:

  • renderWithELK() - Main entry point
  • convertToELKGraph() - ArcLang → ELK conversion
  • convertNodeToELK() - Node conversion with ports
  • renderELKGraph() - D3 rendering of ELK result
  • renderLayer() - Capella layer rendering
  • renderComponent() - Component rendering with Capella style
  • renderPort() - Native ELK port rendering (IN/OUT)
  • renderEdge() - Edge rendering with orthogonal routing
  • setupZoomAndPan() - Zoom/pan identical to Dagre

Integration Steps

Step 1: Inject ELK renderer into template

Open src/compiler/arcviz_explorer_template.html and add BEFORE the final </script> line (around line 1600):

        // ============================================================================
        // ELK LAYOUT RENDERER
        // ============================================================================
        
        <<INSERT CONTENT OF arcviz_elk_renderer.js HERE>>
        
    </script>
</body>
</html>

Step 2: Test with remote_start

cd /Users/malek/Arclang
cargo run --bin arclang -- explorer examples/automotive/remote_start/remote_start_architecture.arc
open examples/automotive/remote_start/remote_start_architecture_explorer.html

Expected console output:

🎨 ArcViz Engine: ELK
🚀 Using ELK layout engine...
ELK Layout: 80ms
D3 Render: 45ms
ELK Total: 125ms
✓ ELK diagram rendered: 25 nodes, 16 edges

Step 3: Verify the result

Visual checks:

  • ✅ Native ports visible (green squares on left, orange on right)
  • ✅ Port labels well positioned
  • ✅ Layers with colored backgrounds and borders
  • ✅ Clean orthogonal edge routing
  • ✅ ASIL badges displayed
  • ✅ Functions listed in components
  • ✅ Zoom/pan functional

Step 4: Fallback to Dagre (optional)

If ELK fails or is disabled, change in ARCVIZ_CONFIG:

engine: 'dagre',  // Back to Dagre

Before/After Comparison

Before (Dagre only)

✓ Diagram rendered: 25 nodes, 16 edges (Dagre layout: 65ms)
Ports: ❌ Manually positioned after layout
Routing: ⭐⭐⭐ Good for <50 components

After (ELK by default)

✓ ELK diagram rendered: 25 nodes, 16 edges (ELK layout: 125ms)
Ports: ✅ Native with FIXED_SIDE constraints
Routing: ⭐⭐⭐⭐⭐ Excellent orthogonal routing

Advanced Configuration

For complex architectures (>100 components)

elk: {
    algorithm: 'layered',
    'elk.direction': 'DOWN',
    'elk.layered.spacing.nodeNodeBetweenLayers': 150,
    'elk.spacing.nodeNode': 60,
    'elk.layered.thoroughness': 200,  // Higher quality
    'elk.layered.compaction.postCompaction.strategy': 'EDGE_LENGTH',
    'elk.separateConnectedComponents': true  // Separate disconnected components
}

Dynamic Dagre/ELK Toggle

Add to the UI (toolbar):

<button onclick="toggleLayoutEngine()">
    Switch to <span id="alt-engine">Dagre</span>
</button>

<script>
function toggleLayoutEngine() {
    ARCVIZ_CONFIG.engine = ARCVIZ_CONFIG.engine === 'elk' ? 'dagre' : 'elk';
    document.getElementById('alt-engine').textContent = 
        ARCVIZ_CONFIG.engine === 'elk' ? 'Dagre' : 'ELK';
    renderDiagram();
}
</script>

Expected Performance

Remote Start (25 components, 16 edges)

  • Dagre: 65ms total
  • ELK: 125ms total (+60ms, acceptable)
  • Quality: ELK superior (native ports, orthogonal routing)

Data Platform Migration (24 components, 8 layers)

  • Dagre: ~70ms total
  • ELK: ~135ms total
  • Quality: ELK much better for multi-layer hierarchy

Large System (150 components)

  • Dagre: ~1200ms (becomes crowded)
  • ELK: ~1300ms (stays clean)
  • Winner: ELK

Troubleshooting

Error: "elk is not defined"

Solution: Verify that elkjs is loaded before initialization:

<script src="https://unpkg.com/elkjs@0.9.3/lib/elk.bundled.js"></script>
<script>
    const elk = new ELK();
</script>

Ports not displayed

Solution: Verify that interfaces are in diagramData:

console.log('Node interfaces:', node.interfaces_in, node.interfaces_out);

Layout appears "squashed"

Solution: Increase spacing:

'elk.spacing.nodeNode': 100,  // instead of 80
'elk.layered.spacing.nodeNodeBetweenLayers': 250  // instead of 200

Edges overlap

Solution: Change routing:

'elk.edgeRouting': 'SPLINES',  // instead of ORTHOGONAL

✅ INTEGRATION COMPLETED

Final Status

  1. ✅ ELK integrated into template (lines 1520-2130)
  2. ✅ Tested with remote_start (25 components, 16 interfaces)
  3. ✅ Configuration optimized for Capella MBSE
  4. ✅ Dagre available as fallback
  5. ✅ Stereotypes disabled (stability)
  6. ✅ Dynamic widths with SVG measurement

Active Configuration

Default engine: engine: 'elk'
Layout: Hierarchical with INCLUDE_CHILDREN
Port positioning: FIXED_SIDE (WEST/EAST)
Edge routing: ORTHOGONAL
Node spacing: 100px between components, 250px between layers
Component width: Min 300px, Max 700px (dynamic)

Features

✅ Native ELK ports (green/orange squares)
✅ Clean orthogonal routing
✅ Hierarchical layers with drop shadows
✅ ASIL badges (colored circles)
✅ Auto-adapted width to text
✅ Intelligent truncation of long labels
✅ Automatic fallback to Dagre if ELK error

Rollback (if necessary)

# In arcviz_explorer_template.html, line 18:
engine: 'dagre'  # Instead of 'elk'

Status:ELK IS NOW THE ARCLANG STANDARD
Date: 2025-10-23
Tested: Remote Start System (25 components), Data Platform Migration (24 components)
Production Ready: Yes

✅ COMPLETE UNIFICATION - ALL GENERATORS

Global Integration

  1. arclang explorer - Interactive ELK (HTML template)
  2. arc-viz-ultimate - Static ELK with fallback
  3. arc-viz-smart - Static ELK with fallback
  4. arc-viz-channel - Static ELK with fallback
  5. arc-viz-perfect - Static ELK with fallback
  6. HTML export - Static ELK by default

New Available Formats

ELK Formats (default):

  • arc-viz-ultimate → Static ELK (requires Node.js/elkjs)
  • arc-viz-smart → Static ELK
  • arc-viz-channel → Static ELK
  • arc-viz-perfect → Static ELK
  • arc-viz-elk → Explicit static ELK

Legacy Formats (automatic fallback):

  • arc-viz-ultimate-legacy → Original custom algorithm
  • arc-viz-smart-legacy → Original custom algorithm
  • arc-viz-channel-legacy → Original custom algorithm
  • arc-viz-perfect-legacy → Original custom algorithm

Fallback Mechanism

If Node.js or elkjs is not available:

⚠ ELK unavailable (MODULE_NOT_FOUND), falling back to custom layout
✓ Export successful

The system automatically switches to arcviz_elk.rs (custom hierarchical algorithm).

CLI Commands

# ELK with automatic fallback (RECOMMENDED)
arclang export model.arc -o diagram.html -f arc-viz-ultimate

# Force ELK usage (fails if unavailable)
arclang export model.arc -o diagram.html -f arc-viz-elk

# Use legacy explicitly
arclang export model.arc -o diagram.html -f arc-viz-ultimate-legacy

ELK Installation (Optional but Recommended)

# Install Node.js (if not available)
brew install node  # macOS
sudo apt install nodejs  # Ubuntu

# Install elkjs globally
npm install -g elkjs

# Verify
node -e "require('elkjs')" && echo "✓ ELK ready"

Code Architecture

Modified files:

  • src/compiler/arcviz_elk_static.rs - New static ELK generator
  • src/compiler/mod.rs - Module export + CompilerError::Other
  • src/cli/mod.rs - ELK/Legacy formats in ExportFormat enum
  • src/cli/mod.rs - Routing to ELK by default for all formats

Principle:

  1. Try generation with ELK via Node.js subprocess
  2. If failure: automatic fallback to arcviz_elk.rs custom algorithm
  3. Guarantee compatibility even without Node.js/elkjs

Unification Benefits

Consistent visual style - Capella design everywhere
Better layout - ELK hierarchical > custom algorithms
Native ports - Correct WEST/EAST constraints
Simplified maintenance - One renderer instead of 5+
Guaranteed compatibility - Automatic fallback if ELK unavailable