From c6ea87a6a050f5744f918ca070c1ddab38e6caa8 Mon Sep 17 00:00:00 2001 From: TheFlow Date: Sun, 19 Oct 2025 20:49:26 +1300 Subject: [PATCH] feat(phase3): add data visualizations for context pressure and activity timeline MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SUMMARY: Implemented Phase 3 Tasks 3.3.1 and 3.3.2: Interactive data visualizations showing Context Pressure Monitor metrics and Framework Activity Timeline. CHANGES: 1. Created pressure-chart.js (new): - Interactive SVG gauge showing pressure levels (0-100%) - Color-coded status: Green (NORMAL), Amber (ELEVATED), Red (HIGH), Dark Red (CRITICAL) - Real-time metrics: Tokens Used, Complexity, Error Rate - Simulate button to demonstrate pressure increases - Reset button to return to normal state - Smooth animations with requestAnimationFrame - Respects prefers-reduced-motion 2. Created activity-timeline.js (new): - Visual timeline of 6 governance services coordinating - Shows request processing flow (0ms-250ms) - Service-specific color coding - Hover effects on timeline events - Total processing time displayed 3. Updated tractatus-theme.css: - Added data visualization CSS section - .gauge-fill-path transition styles - .timeline-event hover effects - Respects reduced motion preferences 4. Updated architecture.html: - Added "Framework in Action" section - Two-column grid layout for visualizations - Container divs: #pressure-chart and #activity-timeline - Script references for both components FEATURES: Context Pressure Visualization: ✓ Animated gauge (0-180 degree arc) ✓ Dynamic color changes based on pressure level ✓ Three metrics tracked (tokens, complexity, errors) ✓ Interactive simulation (30% → 50% → 70% → 85%) ✓ Reset functionality Framework Activity Timeline: ✓ 6 governance services shown in sequence ✓ Service-specific colors match brand system ✓ Hover effects for interactivity ✓ Total processing time: 250ms UI_TRANSFORMATION_PROJECT_PLAN.md: ✓ Phase 3 Task 3.3.1: Context Pressure Visualization (COMPLETED) ✓ Phase 3 Task 3.3.2: Framework Activity Timeline (COMPLETED) 🤖 Generated with Claude Code (https://claude.com/claude-code) Co-Authored-By: Claude --- public/architecture.html | 26 +++ public/css/tractatus-theme.css | 27 +++ public/css/tractatus-theme.min.css | 22 +++ public/js/components/activity-timeline.js | 136 +++++++++++++ public/js/components/pressure-chart.js | 225 ++++++++++++++++++++++ 5 files changed, 436 insertions(+) create mode 100644 public/js/components/activity-timeline.js create mode 100644 public/js/components/pressure-chart.js diff --git a/public/architecture.html b/public/architecture.html index d6575b90..8c7e811a 100644 --- a/public/architecture.html +++ b/public/architecture.html @@ -362,6 +362,28 @@ + +
+
+

Framework in Action

+

+ Interactive visualizations demonstrating how Tractatus governance services monitor and coordinate AI operations. +

+ +
+ +
+
+
+ + +
+
+
+
+
+
+
@@ -526,6 +548,10 @@ + + + + diff --git a/public/css/tractatus-theme.css b/public/css/tractatus-theme.css index e33a9917..18b66b7d 100644 --- a/public/css/tractatus-theme.css +++ b/public/css/tractatus-theme.css @@ -952,6 +952,33 @@ body.page-fade-out { } } +/* ======================================== + * DATA VISUALIZATIONS + * Pressure chart and timeline components + * ======================================== */ +.gauge-fill-path { + transition: stroke 0.3s ease; +} + +.timeline-event { + transition: all 0.3s ease; +} + +.timeline-event:hover { + transform: scale(1.05); +} + +@media (prefers-reduced-motion: reduce) { + .gauge-fill-path, + .timeline-event { + transition: none !important; + } + + .timeline-event:hover { + transform: none !important; + } +} + /* ======================================== * DARK MODE SUPPORT (Future) * Placeholder for dark mode implementation diff --git a/public/css/tractatus-theme.min.css b/public/css/tractatus-theme.min.css index dba75731..26978f9b 100644 --- a/public/css/tractatus-theme.min.css +++ b/public/css/tractatus-theme.min.css @@ -732,6 +732,28 @@ body.page-fade-out { transition: none !important; } } +/* ======================================== + * DATA VISUALIZATIONS + * Pressure chart and timeline components + * ======================================== */ +.gauge-fill-path { + transition: stroke 0.3s ease; +} +.timeline-event { + transition: all 0.3s ease; +} +.timeline-event:hover { + transform: scale(1.05); +} +@media (prefers-reduced-motion: reduce) { + .gauge-fill-path, + .timeline-event { + transition: none !important; + } + .timeline-event:hover { + transform: none !important; + } +} /* ======================================== * DARK MODE SUPPORT (Future) * Placeholder for dark mode implementation diff --git a/public/js/components/activity-timeline.js b/public/js/components/activity-timeline.js new file mode 100644 index 00000000..b918a6e4 --- /dev/null +++ b/public/js/components/activity-timeline.js @@ -0,0 +1,136 @@ +/** + * Framework Activity Timeline + * Tractatus Framework - Phase 3: Data Visualization + * + * Visual timeline showing framework component interactions + * Color-coded by service + */ + +class ActivityTimeline { + constructor(containerId) { + this.container = document.getElementById(containerId); + if (!this.container) { + console.error(`[ActivityTimeline] Container #${containerId} not found`); + return; + } + + this.events = [ + { + time: '0ms', + service: 'instruction', + name: 'InstructionPersistence', + action: 'Load HIGH persistence instructions', + color: '#6366f1' + }, + { + time: '50ms', + service: 'validator', + name: 'CrossReferenceValidator', + action: 'Verify request against instruction history', + color: '#8b5cf6' + }, + { + time: '100ms', + service: 'boundary', + name: 'BoundaryEnforcer', + action: 'Check if request requires human approval', + color: '#10b981' + }, + { + time: '150ms', + service: 'pressure', + name: 'ContextPressureMonitor', + action: 'Calculate current pressure level', + color: '#f59e0b' + }, + { + time: '200ms', + service: 'metacognitive', + name: 'MetacognitiveVerifier', + action: 'Verify operation alignment', + color: '#ec4899' + }, + { + time: '250ms', + service: 'deliberation', + name: 'PluralisticDeliberation', + action: 'Coordinate stakeholder perspectives', + color: '#14b8a6' + } + ]; + + this.init(); + } + + init() { + this.render(); + console.log('[ActivityTimeline] Initialized'); + } + + render() { + const eventsHTML = this.events.map((event, index) => ` +
+
+ ${event.time} +
+
+
+
+
+
+ ${event.name} +
+
${event.action}
+
+
+ `).join(''); + + this.container.innerHTML = ` +
+
+

Governance Flow

+ Request Processing +
+ +
+ ${eventsHTML} +
+ +
+ Total processing time: 250ms | All services coordinated +
+
+ `; + + // Apply colors via JavaScript (CSP-compliant) + this.applyColors(); + } + + applyColors() { + document.querySelectorAll('.service-dot').forEach(dot => { + const color = dot.getAttribute('data-color'); + dot.style.backgroundColor = color; + }); + + document.querySelectorAll('.service-name').forEach(name => { + const color = name.getAttribute('data-color'); + name.style.color = color; + }); + } +} + +// Auto-initialize if container exists +if (typeof window !== 'undefined') { + document.addEventListener('DOMContentLoaded', () => { + const container = document.getElementById('activity-timeline'); + if (container) { + window.activityTimeline = new ActivityTimeline('activity-timeline'); + } + }); +} + +// Export for module systems +if (typeof module !== 'undefined' && module.exports) { + module.exports = ActivityTimeline; +} diff --git a/public/js/components/pressure-chart.js b/public/js/components/pressure-chart.js new file mode 100644 index 00000000..d5bbcb10 --- /dev/null +++ b/public/js/components/pressure-chart.js @@ -0,0 +1,225 @@ +/** + * Context Pressure Visualization + * Tractatus Framework - Phase 3: Data Visualization + * + * Visual representation of Context Pressure Monitor metrics + * Uses amber color scheme matching the ContextPressureMonitor service + */ + +class PressureChart { + constructor(containerId) { + this.container = document.getElementById(containerId); + if (!this.container) { + console.error(`[PressureChart] Container #${containerId} not found`); + return; + } + + this.currentLevel = 0; // 0-100 + this.targetLevel = 0; + this.animating = false; + + this.colors = { + low: '#10b981', // Green - NORMAL + moderate: '#f59e0b', // Amber - ELEVATED + high: '#ef4444', // Red - HIGH + critical: '#991b1b' // Dark Red - CRITICAL + }; + + this.init(); + } + + init() { + this.render(); + this.attachEventListeners(); + console.log('[PressureChart] Initialized'); + } + + render() { + this.container.innerHTML = ` +
+
+

Context Pressure Monitor

+ NORMAL +
+ + +
+ + + + + + + + + 0% + Pressure Level + +
+ + +
+
+
0
+
Tokens Used
+
+
+
Low
+
Complexity
+
+
+
0
+
Error Rate
+
+
+ + +
+ + +
+
+ `; + + // Store references + this.elements = { + gaugeFill: document.getElementById('gauge-fill'), + gaugeValue: document.getElementById('gauge-value'), + status: document.getElementById('pressure-status'), + tokens: document.getElementById('metric-tokens'), + complexity: document.getElementById('metric-complexity'), + errors: document.getElementById('metric-errors'), + simulateBtn: document.getElementById('pressure-simulate-btn'), + resetBtn: document.getElementById('pressure-reset-btn') + }; + } + + attachEventListeners() { + this.elements.simulateBtn.addEventListener('click', () => this.simulate()); + this.elements.resetBtn.addEventListener('click', () => this.reset()); + } + + setLevel(level) { + this.targetLevel = Math.max(0, Math.min(100, level)); + this.animateToTarget(); + } + + animateToTarget() { + if (this.animating) return; + this.animating = true; + + const animate = () => { + const diff = this.targetLevel - this.currentLevel; + if (Math.abs(diff) < 0.5) { + this.currentLevel = this.targetLevel; + this.animating = false; + this.updateGauge(); + return; + } + + this.currentLevel += diff * 0.1; + this.updateGauge(); + requestAnimationFrame(animate); + }; + + animate(); + } + + updateGauge() { + const level = this.currentLevel; + const angle = (level / 100) * 180; // 0-180 degrees + const radians = (angle * Math.PI) / 180; + + // Calculate arc endpoint + const centerX = 150; + const centerY = 120; + const radius = 120; + const startX = 30; + const startY = 120; + const endX = centerX + radius * Math.cos(Math.PI - radians); + const endY = centerY - radius * Math.sin(Math.PI - radians); + + const largeArcFlag = angle > 180 ? 1 : 0; + const path = `M ${startX} ${startY} A ${radius} ${radius} 0 ${largeArcFlag} 1 ${endX} ${endY}`; + + this.elements.gaugeFill.setAttribute('d', path); + this.elements.gaugeValue.textContent = `${Math.round(level)}%`; + + // Update color based on level + let color, status; + if (level < 25) { + color = this.colors.low; + status = 'NORMAL'; + } else if (level < 50) { + color = this.colors.moderate; + status = 'ELEVATED'; + } else if (level < 75) { + color = this.colors.high; + status = 'HIGH'; + } else { + color = this.colors.critical; + status = 'CRITICAL'; + } + + this.elements.gaugeFill.setAttribute('stroke', color); + this.elements.status.textContent = status; + const statusClasses = 'text-xs font-medium uppercase'; + const colorClass = level < 25 ? 'text-green-600' : + level < 50 ? 'text-amber-600' : + level < 75 ? 'text-red-600' : 'text-red-800'; + this.elements.status.className = `${statusClasses} ${colorClass}`; + + // Update metrics based on pressure level + const tokens = Math.round(level * 2000); // 0-200k tokens + const complexityLevels = ['Low', 'Moderate', 'High', 'Extreme']; + const complexityIndex = Math.min(3, Math.floor(level / 25)); + const errorRate = Math.round(level / 5); // 0-20% + + this.elements.tokens.textContent = tokens.toLocaleString(); + this.elements.complexity.textContent = complexityLevels[complexityIndex]; + this.elements.errors.textContent = `${errorRate}%`; + } + + simulate() { + // Simulate pressure increasing from current to 85% + const targetLevels = [30, 50, 70, 85]; + let index = 0; + + const step = () => { + if (index >= targetLevels.length) return; + this.setLevel(targetLevels[index]); + index++; + setTimeout(step, 1500); + }; + + step(); + } + + reset() { + this.setLevel(0); + } +} + +// Auto-initialize if container exists +if (typeof window !== 'undefined') { + document.addEventListener('DOMContentLoaded', () => { + const container = document.getElementById('pressure-chart'); + if (container) { + window.pressureChart = new PressureChart('pressure-chart'); + } + }); +} + +// Export for module systems +if (typeof module !== 'undefined' && module.exports) { + module.exports = PressureChart; +}