Files
ETPlot/gallery/assets/js/comparison-manager.js
2026-05-08 13:05:39 +02:00

181 lines
5.2 KiB
JavaScript

/**
* Plot comparison functionality
*/
export class ComparisonManager {
constructor() {
this.comparisonMode = false;
this.comparisonSlot = null; // 'left' or 'right'
this.plots = { left: null, right: null };
}
/**
* Toggle comparison mode
*/
toggleCompareMode() {
this.comparisonMode = !this.comparisonMode;
const compareBtn = document.getElementById('compareToggle');
if (!compareBtn) return;
if (this.comparisonMode) {
compareBtn.style.background = 'var(--success-color)';
compareBtn.title = 'Exit Compare Mode (Ctrl+C)';
this.showComparisonOverlay();
} else {
compareBtn.style.background = 'var(--button-bg)';
compareBtn.title = 'Compare Plots (Ctrl+C)';
this.hideComparisonOverlay();
}
}
/**
* Show comparison overlay
*/
showComparisonOverlay() {
const overlay = document.getElementById('comparisonOverlay');
if (overlay) overlay.classList.add('open');
}
/**
* Hide comparison overlay
*/
hideComparisonOverlay() {
const overlay = document.getElementById('comparisonOverlay');
if (overlay) overlay.classList.remove('open');
this.comparisonMode = false;
const compareBtn = document.getElementById('compareToggle');
if (compareBtn) {
compareBtn.style.background = 'var(--button-bg)';
compareBtn.title = 'Compare Plots (Ctrl+C)';
}
}
/**
* Close comparison overlay (alias for hideComparisonOverlay)
*/
closeComparison() {
this.hideComparisonOverlay();
}
/**
* Select plot for comparison - simple approach
*/
selectPlotForComparison(slot) {
this.comparisonSlot = slot;
// Hide overlay temporarily by removing the 'open' class
const overlay = document.getElementById('comparisonOverlay');
if (overlay) overlay.classList.remove('open');
// Show simple alert with instructions
const instruction = document.createElement('div');
instruction.id = 'comparisonInstruction';
instruction.style.cssText = `
position: fixed;
top: 20px;
left: 50%;
transform: translateX(-50%);
background: var(--button-bg);
color: white;
padding: 1rem 2rem;
border-radius: 8px;
z-index: 3000;
font-size: 1.1rem;
font-weight: 600;
box-shadow: 0 4px 20px rgba(0,0,0,0.3);
`;
instruction.innerHTML = `📊 Click any plot to select for ${slot === 'left' ? 'Plot A' : 'Plot B'} (ESC to cancel)`;
document.body.appendChild(instruction);
// Add one-time click listener to all grid items
const gridItems = document.querySelectorAll('.grid-item');
const handleClick = (event) => {
event.preventDefault();
event.stopPropagation();
const gridItem = event.currentTarget;
const img = gridItem.querySelector('img');
const nameEl = gridItem.querySelector('.plot-name');
if (img && nameEl) {
const plotInfo = {
name: nameEl.textContent.trim(),
imgSrc: img.src,
pdfSrc: img.src.replace('.png', '.pdf'),
path: window.location.pathname
};
this.addPlotToComparison(plotInfo, slot);
}
// Clean up
instruction.remove();
gridItems.forEach(item => item.removeEventListener('click', handleClick));
this.comparisonSlot = null;
if (overlay) overlay.classList.add('open');
};
gridItems.forEach(item => {
item.style.cursor = 'pointer';
item.style.border = '2px dashed var(--button-bg)';
item.addEventListener('click', handleClick);
});
// ESC to cancel
const handleEscape = (event) => {
if (event.key === 'Escape') {
instruction.remove();
gridItems.forEach(item => {
item.removeEventListener('click', handleClick);
item.style.cursor = '';
item.style.border = '';
});
this.comparisonSlot = null;
if (overlay) overlay.classList.add('open');
document.removeEventListener('keydown', handleEscape);
}
};
document.addEventListener('keydown', handleEscape);
}
/**
* Add plot to comparison panel
*/
addPlotToComparison(plotInfo, slot) {
this.plots[slot] = plotInfo;
const container = document.getElementById(`${slot}PlotContainer`);
const title = document.getElementById(`${slot}PlotTitle`);
const replaceBtn = document.getElementById(`${slot}ReplaceBtn`);
if (container) {
container.innerHTML = `
<img src="${plotInfo.imgSrc}" class="comparison-plot" alt="${plotInfo.name}"
onclick="window.open('${plotInfo.pdfSrc}', '_blank')" />
<div class="comparison-plot-info">
<strong>${plotInfo.name}</strong><br>
<small>${plotInfo.path}</small>
</div>
`;
}
if (title) title.textContent = plotInfo.name;
if (replaceBtn) replaceBtn.style.display = 'block';
// Reset grid item styles
const gridItems = document.querySelectorAll('.grid-item');
gridItems.forEach(item => {
item.style.cursor = '';
item.style.border = '';
});
}
/**
* Replace plot in comparison
*/
replacePlot(slot) {
this.selectPlotForComparison(slot);
}
}