Detailed Scoring Breakdown
| Criteria | Score (out of 10) | Weight | Weighted Score |
|---|---|---|---|
| ${c.label} | ${c.score} | ${(c.weight * 100).toFixed(0)}% | ${(c.score * c.weight).toFixed(2)} |
${c.score}
${criteriaForms}
`;
};
// --- DATA & EVENT HANDLERS ---
window.updateProject = (key, value) => {
projectDetails[key] = (key === 'name' || key === 'ticker') ? value : parseFloat(value) || 0;
};
window.updateCriteria = (id, value) => {
const criteria = evaluationCriteria.find(c => c.id === id);
if(criteria) criteria.score = parseInt(value, 10);
const scoreVal = document.getElementById(`score-val-${id}`);
if (scoreVal) scoreVal.textContent = value;
};
const handleAnalysis = () => {
let overallScore = 0;
evaluationCriteria.forEach(c => {
overallScore += c.score * c.weight;
});
let verdict = 'Proceed with Caution';
let scoreColor = 'text-yellow-600';
if (overallScore >= 8.0) { verdict = 'High Potential'; scoreColor = 'text-green-600'; }
else if (overallScore >= 6.0) { verdict = 'Promising'; scoreColor = 'text-blue-600'; }
else if (overallScore < 4.0) { verdict = 'High Risk'; scoreColor = 'text-red-600'; }
const impliedValuation = projectDetails.totalSupply * projectDetails.icoPrice;
analysisResults = {
...projectDetails,
criteria: JSON.parse(JSON.stringify(evaluationCriteria)), // deep copy
overallScore,
verdict,
scoreColor,
valuation: impliedValuation,
};
switchTab(0);
};
// --- CHART & PDF ---
const renderChart = () => {
if (analysisChart) analysisChart.destroy();
const ctx = document.getElementById('analysisChart')?.getContext('2d');
if (!ctx || !analysisResults) return;
analysisChart = new Chart(ctx, {
type: 'radar',
data: {
labels: analysisResults.criteria.map(c => c.label),
datasets: [{
label: 'Score',
data: analysisResults.criteria.map(c => c.score),
backgroundColor: 'rgba(13, 148, 136, 0.2)',
borderColor: 'rgba(13, 148, 136, 1)',
pointBackgroundColor: 'rgba(13, 148, 136, 1)',
pointBorderColor: '#fff',
}]
},
options: {
responsive: true, maintainAspectRatio: false,
scales: { r: { beginAtZero: true, max: 10, ticks: { stepSize: 2 } } },
plugins: { title: { display: true, text: 'Evaluation Criteria Scores' } }
}
});
};
window.downloadPDF = () => {
if (!analysisResults) return;
const { jsPDF } = window.jspdf;
const doc = new jsPDF();
doc.setFontSize(20);
doc.text(`ICO Analysis Report: ${analysisResults.name}`, doc.internal.pageSize.getWidth() / 2, 20, { align: 'center' });
const summaryText = `
Overall Score: ${analysisResults.overallScore.toFixed(2)} / 10
Verdict: ${analysisResults.verdict}
Implied Valuation: $${(analysisResults.valuation / 1000000).toFixed(2)}M
`;
doc.setFontSize(12);
doc.text(summaryText, 14, 35);
const finalY = analysisChart ? 75 : 55;
if(analysisChart) {
const chartImage = analysisChart.toBase64Image();
doc.addImage(chartImage, 'PNG', 14, finalY, 180, 90);
}
const head = [['Criteria', 'Score', 'Weight', 'Weighted Score']];
const body = analysisResults.criteria.map(c => [
c.label, c.score, `${(c.weight * 100)}%`, (c.score * c.weight).toFixed(2)
]);
doc.autoTable({ startY: finalY + (analysisChart ? 100 : 10), head: head, body: body, theme: 'striped', headStyles: { fillColor: [13, 148, 136] } });
doc.save(`${analysisResults.ticker}-ICO-Analysis.pdf`);
};
// --- INITIALIZATION ---
DOM.nextBtn.addEventListener('click', () => switchTab(currentTab + 1));
DOM.prevBtn.addEventListener('click', () => switchTab(currentTab - 1));
DOM.tabButtons.forEach((btn, i) => btn.addEventListener('click', () => switchTab(i)));
renderCurrentTab();
updateNavButtons();
});
