document.addEventListener('DOMContentLoaded', function() { const toggleHeatmapButton = document.getElementById('toggleHeatmap'); if (toggleHeatmapButton) { toggleHeatmapButton.onclick = toggleHeatmap; } else { console.error("Botão com id 'toggleHeatmap' não encontrado!"); } }); let heatmapVisible = false; function toggleHeatmap() { heatmapVisible = !heatmapVisible; if (heatmapVisible) { showLoading(); setTimeout(() => { drawBlurryHeatmap(); hideLoading(); }, 100); // Pequeno delay para mostrar o loading antes do render } else { clearHeatmap(); } } function setupCanvas() { let heatmapCanvas = document.getElementById('heatmapCanvas'); if (!heatmapCanvas) { heatmapCanvas = document.createElement('canvas'); heatmapCanvas.id = 'heatmapCanvas'; heatmapCanvas.width = document.getElementById('matrix').offsetWidth; heatmapCanvas.height = document.getElementById('matrix').offsetHeight; heatmapCanvas.style.position = 'absolute'; heatmapCanvas.style.top = '-31px'; heatmapCanvas.style.left = '0'; heatmapCanvas.style.pointerEvents = 'none'; document.getElementById('matrix').appendChild(heatmapCanvas); } const ctx = heatmapCanvas.getContext('2d'); ctx.filter = 'blur(6.5px)'; return ctx; } function drawBlurryHeatmap() { const ctx = setupCanvas(); ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); // Filtrar pontos sem labels const pontosSemLabel = data.filter(p => !p.label); if (pontosSemLabel.length === 0) { console.error("Nenhum ponto sem label encontrado para o mapa de calor."); return; } // Definir gatilhos de densidade const totalPontos = pontosSemLabel.length; let step = 1; // Define a frequência de desenho dos pontos if (totalPontos > 800) { step = 8; // Desenha 1 em cada 10 pontos } else if (totalPontos > 600) { step = 5; // Desenha 1 em cada 7 pontos } else if (totalPontos > 400) { step = 3; // Desenha 1 em cada 5 pontos } else if (totalPontos > 200) { step = 2; // Desenha 1 em cada 3 pontos } // Parâmetros de cada camada const raios = [90, 70, 50, 30, 20, 10, 7, 5]; const cores = ["#00ffff", "#8efc6e", "#fcf75e", "#fc8e75", "#ec3577", "#d22b6a", "#b12059", "#8e1947"]; const opacidades = [0.05, 0.05, 0.1, 0.1, 0.1, 0.1, 0.2, 0.2]; // Para cada camada, com step adaptado raios.forEach((raio, i) => { const densidadeLocal = calcularDensidadeCluster(pontosSemLabel, raio, step); densidadeLocal.forEach(({ x, y }) => { ctx.beginPath(); ctx.arc(x, y, raio, 0, Math.PI * 2); ctx.fillStyle = cores[i]; ctx.globalAlpha = opacidades[i]; ctx.fill(); ctx.closePath(); }); }); // Redefinir opacidade global ao final ctx.globalAlpha = 1.0; } function calcularDensidadeCluster(pontos, raio, step) { const clusters = []; pontos.forEach((ponto1, index) => { // Aplica o step para reduzir a densidade de pontos desenhados if (index % step !== 0) return; const cluster = pontos.filter(ponto2 => distanciaEntrePontos(ponto1, ponto2) <= raio); if (cluster.length >= 3) { // Define que pelo menos 3 pontos devem estar no cluster clusters.push({ x: ponto1.x, y: ponto1.y }); } }); return clusters; } function distanciaEntrePontos(p1, p2) { return Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2)); } function clearHeatmap() { const heatmapCanvas = document.getElementById('heatmapCanvas'); if (heatmapCanvas) { const ctx = heatmapCanvas.getContext('2d'); ctx.clearRect(0, 0, heatmapCanvas.width, heatmapCanvas.height); } } // Funções de loading function showLoading() { let loadingDiv = document.getElementById('loading'); if (!loadingDiv) { loadingDiv = document.createElement('div'); loadingDiv.id = 'loading'; loadingDiv.textContent = 'Carregando mapa de calor...'; loadingDiv.style.position = 'absolute'; loadingDiv.style.top = '47%'; loadingDiv.style.left = '50%'; loadingDiv.style.transform = 'translate(-50%, -50%)'; loadingDiv.style.backgroundColor = 'rgba(0, 0, 0, 0.3)'; loadingDiv.style.color = 'white'; loadingDiv.style.padding = '10px 20px'; loadingDiv.style.borderRadius = '5px'; loadingDiv.style.zIndex = '10'; loadingDiv.style.fontFamily = 'Arial, sans-serif'; // Define a fonte como Arial document.body.appendChild(loadingDiv); } loadingDiv.style.display = 'block'; } function hideLoading() { const loadingDiv = document.getElementById('loading'); if (loadingDiv) { loadingDiv.style.display = 'none'; } }