Analyzing demand data...
';
placeholder.classList.remove('hidden');
resultsContainer.classList.add('hidden');
setTimeout(() => {
const analysisData = generateSimulatedData(nicheQuery, regionInput.value.trim());
renderResults(analysisData);
}, 1500);
};
const renderResults = (data) => {
placeholder.classList.add('hidden');
resultsContainer.classList.remove('hidden');
nicheTitle.textContent = data.niche;
// Top Markets
topMarketsList.innerHTML = data.topMarkets.map(market => `
${market.country}
`).join('');
renderScoreChart(data.region, data.scores.local, data.scores.global);
renderTrendChart(data.trends.local, data.trends.global);
};
// --- Data Simulation ---
const hashCode = (str) => {
let hash = 0;
for (let i = 0; i < str.length; i++) {
const char = str.charCodeAt(i);
hash = ((hash << 5) - hash) + char;
hash |= 0; // Convert to 32bit integer
}
return Math.abs(hash);
};
const generateSimulatedData = (niche, region) => {
const seed = hashCode(niche.toLowerCase());
let localSeed = hashCode(region.toLowerCase());
const seededRandom = (s) => {
const x = Math.sin(s) * 10000;
return x - Math.floor(x);
};
const globalScore = Math.floor(seededRandom(seed) * 60 + 40); // 40-100
const localScore = Math.floor(seededRandom(seed + localSeed) * 80 + 20); // 20-100
const globalTrend = Array.from({length: 12}, (_, i) => Math.floor(seededRandom(seed + i) * globalScore + 10));
const localTrend = Array.from({length: 12}, (_, i) => Math.floor(seededRandom(seed + localSeed + i) * localScore + 5));
const countries = ["USA", "China", "Germany", "UK", "Japan", "India", "France", "Canada"];
const topMarkets = countries.slice(0, 5).map((c, i) => ({
country: c,
share: Math.floor(seededRandom(seed + i * 10) * 70 + 30)
})).sort((a,b) => b.share - a.share);
return {
niche,
region,
scores: { local: localScore, global: globalScore },
trends: { local: localTrend, global: globalTrend },
topMarkets
};
};
// --- Chart Rendering ---
const renderScoreChart = (region, localScore, globalScore) => {
const ctx = document.getElementById('score-bar-chart').getContext('2d');
if (scoreChartInstance) scoreChartInstance.destroy();
scoreChartInstance = new Chart(ctx, {
type: 'bar',
data: {
labels: [region, 'Global'],
datasets: [{
label: 'Demand Score',
data: [localScore, globalScore],
backgroundColor: ['rgba(59, 130, 246, 0.7)', 'rgba(75, 85, 99, 0.7)'],
borderColor: ['rgba(59, 130, 246, 1)', 'rgba(75, 85, 99, 1)'],
borderWidth: 1
}]
},
options: {
indexAxis: 'y',
responsive: true,
scales: { x: { beginAtZero: true, max: 100 } },
plugins: { legend: { display: false } }
}
});
};
const renderTrendChart = (localData, globalData) => {
const ctx = document.getElementById('trend-line-chart').getContext('2d');
if (trendChartInstance) trendChartInstance.destroy();
const labels = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
trendChartInstance = new Chart(ctx, {
type: 'line',
data: {
labels: labels,
datasets: [
{
label: 'Local Trend',
data: localData,
borderColor: 'rgba(59, 130, 246, 1)',
backgroundColor: 'rgba(59, 130, 246, 0.2)',
fill: true,
tension: 0.3
},
{
label: 'Global Trend',
data: globalData,
borderColor: 'rgba(75, 85, 99, 1)',
backgroundColor: 'rgba(75, 85, 99, 0.2)',
fill: true,
tension: 0.3
}
]
},
options: {
responsive: true,
scales: { y: { beginAtZero: true, max: 100 } },
}
});
};
const handleDownloadPdf = async () => {
const pdfContentEl = document.getElementById('pdf-content');
if (!pdfContentEl || !scoreChartInstance || !trendChartInstance) return;
// Populate PDF
document.getElementById('pdf-niche-title').textContent = nicheInput.value;
document.getElementById('pdf-timestamp').textContent = new Date().toLocaleString('en-US');
document.getElementById('pdf-top-markets').innerHTML = topMarketsList.outerHTML;
// Convert charts to images
document.getElementById('pdf-score-chart-img').src = scoreChartInstance.toBase64Image();
document.getElementById('pdf-trend-chart-img').src = trendChartInstance.toBase64Image();
pdfContentEl.classList.remove('hidden');
await new Promise(resolve => setTimeout(resolve, 100));
html2canvas(pdfContentEl, { scale: 2 }).then(canvas => {
pdfContentEl.classList.add('hidden');
const imgData = canvas.toDataURL('image/png');
const pdf = new jsPDF({ orientation: 'portrait', unit: 'pt', format: 'a4' });
const pdfWidth = pdf.internal.pageSize.getWidth();
const margin = 40;
const imgWidth = pdfWidth - (margin * 2);
const imgHeight = (canvas.height * imgWidth) / canvas.width;
pdf.addImage(imgData, 'PNG', margin, margin, imgWidth, imgHeight);
pdf.save(`${nicheInput.value.replace(/\s+/g, '-')}-demand-analysis.pdf`);
}).catch(err => {
console.error("Error generating PDF:", err);
pdfContentEl.classList.add('hidden');
});
};
// --- Event Listeners ---
analyzeBtn.addEventListener('click', handleAnalysis);
pdfBtn.addEventListener('click', handleDownloadPdf);
});