Enter data in the "Data Input" tab to generate a heatmap.
';
return;
}
const { headers, rows } = parsedData;
const allValues = rows.flatMap(r => r.data);
const min = Math.min(...allValues);
const max = Math.max(...allValues);
let tableHTML = '
| ';
headers.forEach(h => { tableHTML += `${h} | `; });
tableHTML += '
';
rows.forEach(row => {
tableHTML += `| ${row.label} | `;
row.data.forEach(val => {
const {bgColor, textColor} = getColorForValue(val, min, max);
tableHTML += `${val} | `;
});
tableHTML += '
';
});
tableHTML += '
';
heatmapContainer.innerHTML = tableHTML;
};
const getColorForValue = (value, min, max) => {
const percent = (value - min) / (max - min);
const scheme = colorSchemeSelect.value;
let r, g, b;
// Simple linear interpolation for color
const lerp = (c1, c2, t) => c1 * (1 - t) + c2 * t;
if (scheme === 'blue-red') { // Blue -> White -> Red
if (percent < 0.5) {
r = lerp(70, 255, percent * 2); g = lerp(147, 255, percent * 2); b = lerp(195, 255, percent * 2);
} else {
r = lerp(255, 214, (percent - 0.5) * 2); g = lerp(255, 96, (percent - 0.5) * 2); b = lerp(255, 77, (percent - 0.5) * 2);
}
} else if (scheme === 'green-purple') { // Green -> White -> Purple
if (percent < 0.5) {
r = lerp(46, 255, percent * 2); g = lerp(204, 255, percent * 2); b = lerp(113, 255, percent * 2);
} else {
r = lerp(255, 142, (percent - 0.5) * 2); g = lerp(255, 68, (percent - 0.5) * 2); b = lerp(255, 173, (percent - 0.5) * 2);
}
} else { // grayscale
const val = lerp(240, 30, percent);
r = g = b = val;
}
const textColor = (r * 0.299 + g * 0.587 + b * 0.114) > 186 ? '#000000' : '#ffffff';
return { bgColor: `rgb(${Math.round(r)},${Math.round(g)},${Math.round(b)})`, textColor };
};
const downloadPDF = () => {
const heatmapElement = mainContainer.querySelector("#hm-heatmap-container");
if(!heatmapElement || !heatmapElement.querySelector('table')) {
alert('Please generate a heatmap first.');
return;
}
html2canvas(heatmapElement, { scale: 2 }).then(canvas => {
const { jsPDF } = window.jspdf;
const doc = new jsPDF({ orientation: 'l', unit: 'mm', format: 'a4' });
doc.setFontSize(18);
doc.text("Heatmap Visualization Report", 14, 22);
const imgData = canvas.toDataURL('image/png');
const pdfWidth = doc.internal.pageSize.getWidth();
const pdfHeight = doc.internal.pageSize.getHeight();
const imgProps = doc.getImageProperties(imgData);
const imgHeight = (imgProps.height * pdfWidth) / imgProps.width;
doc.addImage(imgData, 'PNG', 10, 30, pdfWidth - 20, Math.min(imgHeight, pdfHeight - 40));
doc.save('Heatmap-Report.pdf');
});
};
// --- Event Listeners and Init ---
generateBtn.addEventListener('click', parseCSV);
colorSchemeSelect.addEventListener('change', renderHeatmap);
downloadBtn.addEventListener('click', downloadPDF);
let currentTabIndex = 0;
const tabs = mainContainer.querySelectorAll('.hm-tab-link');
window.hm_changeTab = (event, tabName) => {
currentTabIndex = Array.from(tabs).findIndex(t => t === event.currentTarget);
Array.from(mainContainer.querySelectorAll('.hm-tab-content')).forEach(c => c.classList.remove('active'));
tabs.forEach(t => t.classList.remove('active'));
mainContainer.querySelector('#' + tabName).classList.add('active');
};
parseCSV();
});