NTA Analytics Hub
Precision Percentile, AIR Rank & Normalisation Predictor
NTA Scorecard Normalisation Engine
NTA Score to Percentile & AIR Predictor
Algorithmically models standard deviation shifts, candidate volume distribution curves, and difficulty normalization rules for official NTA scorecards (JEE Main, NEET UG, CUET UG).
Quick Presets:
Input Parameters
JEE Main (Engineering) - Max 300
NEET UG (Medical) - Max 720
CUET UG (General) - Max 800
Custom Score Mode
210 / 300
Marks
Moderate Shift (1.0x)
Very Hard (+5%)
Moderate
Very Easy (-4%)
Official NTA Volume
Official NTA Percentile Formula
NTA calculates Percentile Scores up to 7 decimal places to eliminate ties:
P = (100 × Candidates with score ≤ Raw Score) / Total Candidates
Estimated NTA Percentile
99.1847251
Confidence Range: 98.95% - 99.35%
Estimated All India Rank (AIR)
#12,030
AIR Range: 11,100 - 12,900
Performance Band
Top 1.0% (Elite Tier)
High probability of top-tier premier national institutes.
Candidates Below You
1,463,050
Candidates Above You
12,053
Raw Marks %
70.0%
Shift Normalisation
Baseline (1.0x)
Institute & Category Cutoff Eligibility
Category: GEN
NTA
Detailed NTA Score Summary
Official Modelled Projection Report
Examination:
JEE Main (Engineering)
Reservation Category:
General (UR)
Raw Score Obtained:
210 / 300
Shift Normalisation:
Moderate Shift
Modelled NTA Percentile Score
99.1847251
Estimated AIR Rank
#12,030
Total Exam Candidates
1,475,103
Category Cutoff Qualification Forecast:
${isEligible ? 'Qualified' : 'Target ' + requiredPct + '%ile'}
${item.name}
Est. ${selectedCategory} Cutoff: ${requiredPct}%ile
`; container.appendChild(card); }); } function switchTab(tabName) { activeTab = tabName; ['curve', 'trend'].forEach(t => { const btn = document.getElementById(`tab-${t}`); const view = document.getElementById(`view-${t}`); if (t === tabName) { btn.className = "tab-btn px-3.5 py-1.5 rounded-lg text-xs font-semibold bg-white dark:bg-slate-800 text-brand-600 dark:text-brand-400 shadow-sm transition"; view.classList.remove('hidden'); } else { btn.className = "tab-btn px-3.5 py-1.5 rounded-lg text-xs font-semibold text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-white transition"; view.classList.add('hidden'); } }); calculatePercentile(); } function updateActiveChart(percentile, rawMarks, maxMarks) { const isDark = document.documentElement.classList.contains('dark'); const gridColor = isDark ? 'rgba(255,255,255,0.06)' : 'rgba(0,0,0,0.06)'; const textColor = isDark ? '#94a3b8' : '#64748b'; if (activeTab === 'curve') { renderBellCurveChart(percentile, isDark, gridColor, textColor); } else if (activeTab === 'trend') { renderTrendChart(rawMarks, maxMarks, isDark, gridColor, textColor); } } function renderBellCurveChart(userPercentile, isDark, gridColor, textColor) { const ctx = document.getElementById('bellCurveChart').getContext('2d'); if (chartCurveInstance) chartCurveInstance.destroy(); const labels = []; const data = []; for (let x = 0; x ctx.dataIndex === closestIndex ? 8 : 0, pointBackgroundColor: '#06b6d4', pointBorderColor: '#ffffff', pointBorderWidth: 2 }] }, options: { responsive: true, maintainAspectRatio: false, plugins: { legend: { display: false }, tooltip: { callbacks: { label: function(context) { if (context.dataIndex === closestIndex) { return ` Your Position: ${userPercentile.toFixed(2)} %ile`; } return ` Candidate Density at ${context.label}`; } } } }, scales: { x: { grid: { color: gridColor }, ticks: { color: textColor, maxTicksLimit: 10 } }, y: { display: false } } } }); } function renderTrendChart(rawMarks, maxMarks, isDark, gridColor, textColor) { const ctx = document.getElementById('trendChart').getContext('2d'); if (chartTrendInstance) chartTrendInstance.destroy(); const marksData = []; const percentileData = []; for (let pct = 0; pct m + ' Marks'), datasets: [{ label: 'Projected Percentile Curve', data: percentileData, borderColor: '#10b981', backgroundColor: 'rgba(16, 185, 129, 0.1)', fill: true, tension: 0.3, borderWidth: 3, pointRadius: 4 }] }, options: { responsive: true, maintainAspectRatio: false, plugins: { legend: { labels: { color: textColor } } }, scales: { x: { grid: { color: gridColor }, ticks: { color: textColor } }, y: { grid: { color: gridColor }, ticks: { color: textColor } } } } }); } function openModal() { const examKey = document.getElementById('examSelect').value; const data = EXAM_DATASETS[examKey]; document.getElementById('modalExamName').innerText = data.name; document.getElementById('modalCategory').innerText = selectedCategory; document.getElementById('modalRawMarks').innerText = `${document.getElementById('rawMarks').value} / ${document.getElementById('maxMarks').value}`; document.getElementById('modalShift').innerText = document.getElementById('shiftLabel').innerText; document.getElementById('modalPercentile').innerText = document.getElementById('percentileDisplay').innerText; document.getElementById('modalRank').innerText = document.getElementById('midRankDisplay').innerText; document.getElementById('modalCandidates').innerText = parseInt(document.getElementById('totalCandidates').value).toLocaleString(); const list = document.getElementById('modalCutoffsList'); list.innerHTML = ''; const userPct = parseFloat(document.getElementById('percentileDisplay').innerText); data.cutoffs.forEach(c => { let reqPct = c.genPct; if (selectedCategory === 'OBC') reqPct = c.obcPct; else if (selectedCategory === 'EWS') reqPct = c.ewsPct; else if (selectedCategory === 'SC') reqPct = c.scPct; else if (selectedCategory === 'ST') reqPct = c.stPct; const passed = userPct >= reqPct; const row = document.createElement('div'); row.className = "flex items-center justify-between p-2 rounded-lg bg-slate-100 dark:bg-slate-900"; row.innerHTML = ` ${c.name} (Req: ${reqPct}%ile) ${passed ? 'ELIGIBLE' : 'NOT ELIGIBLE'} `; list.appendChild(row); }); document.getElementById('scorecardModal').classList.remove('hidden'); } function closeModal() { document.getElementById('scorecardModal').classList.add('hidden'); }