Most Backlinks
${results.mostBacklinks.url} (${results.mostBacklinks.backlinks.toLocaleString()})
Most Keywords
${results.mostKeywords.url} (${results.mostKeywords.keywords.toLocaleString()})
`;
let tableHtml = `
| Website |
Domain Authority |
Backlinks |
Keywords |
`;
results.allData.forEach(site => {
const isYou = site.isYou;
tableHtml += `
| ${site.url} ${isYou ? 'YOU' : ''} |
${site.da} |
${site.backlinks.toLocaleString()} |
${site.keywords.toLocaleString()} |
`;
});
tableHtml += `
`;
resultsContainer.innerHTML = tableHtml;
renderChart(results.allData);
};
const renderChart = (data) => {
const ctx = document.getElementById('comparison-chart').getContext('2d');
if(comparisonChart) comparisonChart.destroy();
const labels = data.map(d => d.url);
comparisonChart = new Chart(ctx, {
type: 'bar',
data: {
labels,
datasets: [
{ label: 'Domain Authority', data: data.map(d => d.da), backgroundColor: '#3B82F6' },
{ label: 'Backlinks (log scale)', data: data.map(d => Math.log10(d.backlinks)), backgroundColor: '#10B981' },
{ label: 'Keywords (log scale)', data: data.map(d => Math.log10(d.keywords)), backgroundColor: '#8B5CF6' },
]
},
options: { responsive: true, plugins: { title: { display: true, text: 'SEO Metrics Comparison (Log Scale for Links/Keywords)' }}}
});
};
// --- CORE LOGIC ---
const handleAnalysis = () => {
runBtnSpinner.classList.remove('hidden');
runBtnText.textContent = 'Analyzing...';
runBtn.disabled = true;
setTimeout(() => {
const yourData = {
url: document.getElementById('your-url').value,
da: parseInt(document.getElementById('your-da').value),
backlinks: parseInt(document.getElementById('your-backlinks').value),
keywords: parseInt(document.getElementById('your-keywords').value),
isYou: true
};
const allData = [yourData, ...competitors];
const results = {
allData,
highestDa: [...allData].sort((a,b) => b.da - a.da)[0],
mostBacklinks: [...allData].sort((a,b) => b.backlinks - a.backlinks)[0],
mostKeywords: [...allData].sort((a,b) => b.keywords - a.keywords)[0]
};
renderDashboard(results);
switchTab('dashboard');
downloadPdfBtn.disabled = false;
runBtnSpinner.classList.add('hidden');
runBtnText.textContent = 'Run Analysis';
runBtn.disabled = false;
}, 500);
};
// --- UI & EVENT HANDLERS ---
const switchTab = (tabId) => {
currentTab = tabId;
Object.values(tabPanes).forEach(pane => pane.classList.add('hidden'));
tabPanes[tabId].classList.remove('hidden');
Object.values(tabButtons).forEach(btn => btn.classList.replace('tab-active', 'tab-inactive'));
tabButtons[tabId].classList.replace('tab-inactive', 'tab-active');
updateNavButtons();
};
const navigateTabs = (direction) => {
const currentIndex = tabs.indexOf(currentTab);
const newIndex = direction === 'next' ? currentIndex + 1 : currentIndex - 1;
if (newIndex >= 0 && newIndex < tabs.length) switchTab(tabs[newIndex]);
};
const updateNavButtons = () => {
const currentIndex = tabs.indexOf(currentTab);
prevBtn.disabled = currentIndex === 0;
nextBtn.disabled = currentIndex === tabs.length - 1;
prevBtn.classList.toggle('opacity-50', prevBtn.disabled);
nextBtn.classList.toggle('opacity-50', nextBtn.disabled);
};
const handlePdfDownload = () => {
const pdfRenderContainer = document.getElementById('pdf-render-content');
const pdfContent = document.getElementById('pdf-content').innerHTML;
const header = `
SEO Competitor Analysis Report
`;
pdfRenderContainer.innerHTML = header + pdfContent + '`;
const badge = pdfRenderContainer.querySelector('.text-xs');
if (badge) badge.style.display = 'none';
html2canvas(pdfRenderContainer, { scale: 2 }).then(canvas => {
const imgData = canvas.toDataURL('image/png');
const { jsPDF } = window.jspdf;
const pdf = new jsPDF({ orientation: 'landscape', unit: 'pt', format: 'a4' });
const pdfWidth = pdf.internal.pageSize.getWidth(), margin = 40;
const contentWidth = pdfWidth - margin * 2;
const pdfHeight = (canvas.height * contentWidth) / canvas.width;
pdf.addImage(imgData, 'PNG', margin, margin, contentWidth, pdfHeight);
pdf.save('SEO-Competitor-Analysis.pdf');
});
};
// --- EVENT LISTENERS ---
window.switchTab = switchTab;
window.navigateTabs = navigateTabs;
runBtn.addEventListener('click', handleAnalysis);
downloadPdfBtn.addEventListener('click', handlePdfDownload);
addCompetitorBtn.addEventListener('click', () => { competitors.push({ id: nextId++, url: '', da: 0, backlinks: 0, keywords: 0 }); renderConfigTable(); });
configContainer.addEventListener('input', e => {
const id = parseInt(e.target.closest('[data-id]').dataset.id);
const prop = e.target.dataset.prop;
const item = competitors.find(c => c.id === id);
if (item) item[prop] = e.target.type === 'number' ? parseInt(e.target.value) : e.target.value;
});
configContainer.addEventListener('click', e => {
if (!e.target.classList.contains('rm-btn')) return;
const id = parseInt(e.target.closest('[data-id]').dataset.id);
competitors = competitors.filter(c => c.id !== id);
renderConfigTable();
});
// --- INITIALIZATION ---
renderConfigTable();
updateNavButtons();
switchTab('dashboard');
});