/**
* 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
`;
// 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;
}