document.addEventListener('DOMContentLoaded', () => { console.log('Tooltip script loaded'); // Function to fix problematic tooltips window.fixProblemTooltips = () => { console.log('Fixing problem tooltips'); // Find all tooltip elements with tooltip-trigger class const allTooltips = document.querySelectorAll('.tooltip-trigger'); console.log(`Found ${allTooltips.length} tooltip triggers`); // Process each tooltip - fix all tooltips with tooltip-trigger class allTooltips.forEach(tooltip => { const tooltipContent = tooltip.getAttribute('data-tooltip') || ''; if (tooltipContent) { console.log(`Processing tooltip: ${tooltip.innerText}`); // Get tooltip title const tooltipTitle = tooltip.getAttribute('data-title') || tooltip.innerText; const tooltipId = 'custom-' + tooltipTitle.replace(/[^a-zA-Z0-9]/g, ''); // Fix this tooltip fixSingleTooltip(tooltip, tooltipTitle, tooltipId); } }); }; // Function to fix a single tooltip const fixSingleTooltip = (tooltip, title, id) => { console.log(`Fixing tooltip for ${title} with ID ${id}`); // Remove any existing event listeners const clone = tooltip.cloneNode(true); tooltip.parentNode.replaceChild(clone, tooltip); tooltip = clone; // Add tooltip-right class and inline styles tooltip.classList.add('tooltip-right'); tooltip.style.position = 'relative'; // Add data-title if missing if (!tooltip.getAttribute('data-title')) { tooltip.setAttribute('data-title', title); } // Get tooltip content const tooltipContent = tooltip.getAttribute('data-tooltip') || ''; // Show the tooltip on the left side tooltip.addEventListener('mouseenter', (event) => { console.log(`Mouse entered ${title}`); // Remove any existing custom tooltip with this ID const existingTooltip = document.getElementById(id); if (existingTooltip) { existingTooltip.remove(); } // Create custom tooltip element const customTooltip = document.createElement('div'); customTooltip.id = id; customTooltip.className = 'custom-tooltip'; customTooltip.innerHTML = `${title}${tooltipContent}`; document.body.appendChild(customTooltip); // Position tooltip near the element const rect = tooltip.getBoundingClientRect(); console.log(`Element position: top=${rect.top}, left=${rect.left}, width=${rect.width}, height=${rect.height}`); const tooltipWidth = 300; // Width of our tooltip in pixels const horizontalOffset = 5; // Small gap between element and tooltip // Check if this is a model tooltip in the cost analysis tab (in first column of any table) const isModelTooltip = (tooltip.closest('td:first-child') !== null || tooltip.closest('th:first-child') !== null); // Position tooltip either to the right or below based on location if (isModelTooltip) { console.log('Positioning model tooltip to the right'); // Position to the right for model tooltips in cost analysis // Calculate vertical centering (tooltip height is variable) const tooltipHeight = 300; // Estimate for most model tooltips // Position exactly at vertical center of the model name const modelMiddle = rect.top + (rect.height / 2); // Set position as fixed to work properly with scrolling customTooltip.style.position = 'fixed'; customTooltip.style.top = `${modelMiddle}px`; customTooltip.style.transform = 'translateY(-50%)'; customTooltip.style.left = `${rect.right + horizontalOffset}px`; // Create arrow element for the model tooltip - using orange color from FLaME const arrow = document.createElement('div'); arrow.style.position = 'absolute'; arrow.style.left = '-10px'; // Move it a bit further out for visibility arrow.style.top = '50%'; arrow.style.transform = 'translateY(-50%)'; arrow.style.width = '0'; arrow.style.height = '0'; arrow.style.borderTop = '11px solid transparent'; // Make it larger arrow.style.borderBottom = '11px solid transparent'; // Make it larger arrow.style.borderRight = '11px solid rgba(0, 0, 0, 0.9)'; // Orange accent color for visibility arrow.style.display = 'block'; arrow.style.zIndex = '9999'; customTooltip.appendChild(arrow); // Make sure tooltip doesn't go too close to the top edge if (modelMiddle < 50) { customTooltip.style.top = '50px'; } // Check if tooltip would go off the right edge of the screen const viewportWidth = window.innerWidth; const tooltipRight = rect.right + horizontalOffset + tooltipWidth; if (tooltipRight > viewportWidth - 20) { // Position to the left of the element instead customTooltip.style.left = `${rect.left - tooltipWidth - horizontalOffset}px`; // Move the arrow to the right side and flip it if (arrow) { arrow.style.left = 'auto'; arrow.style.right = '-8px'; arrow.style.borderRight = 'none'; arrow.style.borderLeft = '8px solid rgba(0, 0, 0, 0.9)'; // Orange color for visibility } } } else { // Default behavior - position below and centered const verticalOffset = 5; // Set tooltip position below the element customTooltip.style.top = `${window.scrollY + rect.bottom + verticalOffset}px`; // Center the tooltip horizontally on the element const tooltipLeft = rect.left + (rect.width / 2) - (tooltipWidth / 2); // But make sure it stays within the viewport bounds const viewportWidth = window.innerWidth; let adjustedLeft = tooltipLeft; // Check right edge if (tooltipLeft + tooltipWidth > viewportWidth - 20) { adjustedLeft = viewportWidth - tooltipWidth - 20; } // Check left edge if (adjustedLeft < 20) { adjustedLeft = 20; } customTooltip.style.left = `${adjustedLeft}px`; // Add a small arrow at the top pointing to the element const arrow = document.createElement('div'); arrow.style.position = 'absolute'; arrow.style.top = '-8px'; arrow.style.left = `${Math.max(0, Math.min(tooltipWidth - 20, rect.left + (rect.width / 2) - adjustedLeft - 8))}px`; arrow.style.width = '0'; arrow.style.height = '0'; arrow.style.borderLeft = '8px solid transparent'; arrow.style.borderRight = '8px solid transparent'; arrow.style.borderBottom = '8px solid rgba(0, 0, 0, 0.9)'; customTooltip.appendChild(arrow); } console.log(`Tooltip position: top=${customTooltip.style.top}, left=${customTooltip.style.left}`); }); // Hide tooltip on mouseout tooltip.addEventListener('mouseleave', (event) => { console.log(`Mouse left ${title}`); const customTooltip = document.getElementById(id); if (customTooltip) { customTooltip.remove(); } }); }; // Run when DOM is ready console.log('Setting up initial tooltip fix'); setTimeout(fixProblemTooltips, 500); // Run again when tabs are clicked const tabs = document.querySelectorAll('.tabs li'); console.log(`Found ${tabs.length} tabs`); tabs.forEach(tab => { tab.addEventListener('click', (event) => { console.log(`Tab clicked: ${tab.textContent}`); // Give time for the content to be displayed setTimeout(fixProblemTooltips, 500); }); }); // Handle window resize window.addEventListener('resize', () => { console.log('Window resized, removing tooltips'); // Remove all custom tooltips on resize document.querySelectorAll('.custom-tooltip').forEach(t => t.remove()); }); });