Siddharaj Shirke
v1 completed successfully
67c8aca
import {
Chart as ChartJS,
ArcElement,
Tooltip,
Legend,
CategoryScale,
LinearScale,
BarElement,
Title,
RadialLinearScale,
PointElement,
LineElement,
Filler,
} from 'chart.js';
import { Doughnut, Bar, Radar } from 'react-chartjs-2';
ChartJS.register(
ArcElement,
Tooltip,
Legend,
CategoryScale,
LinearScale,
BarElement,
Title,
RadialLinearScale,
PointElement,
LineElement,
Filler
);
export function DTIGauge({ dti }) {
const data = {
labels: ['DTI', 'Remaining Capacity'],
datasets: [
{
data: [dti, Math.max(0, 100 - dti)],
backgroundColor: [
dti > 50 ? '#ef4444' : dti > 30 ? '#f59e0b' : '#10b981',
'#f3f4f6'
],
borderWidth: 0,
cutout: '85%'
}
]
};
const options = {
rotation: -90,
circumference: 180,
plugins: {
legend: { display: false },
tooltip: { enabled: false }
},
maintainAspectRatio: true,
};
return (
<div style={{ position: 'relative', width: '220px', margin: '0 auto' }}>
<Doughnut data={data} options={options} />
<div style={{
position: 'absolute',
top: '70%',
left: '50%',
transform: 'translate(-50%, -50%)',
textAlign: 'center'
}}>
<div style={{ fontSize: '1.75rem', fontWeight: '700' }}>{dti.toFixed(1)}%</div>
<div style={{ fontSize: '0.75rem', color: '#6b7280', fontWeight: '600' }}>DEBT-TO-INCOME</div>
</div>
</div>
);
}
export function ComparisonRadar({ userResults }) {
const benchmarks = JSON.parse(userResults.benchmarks_json || "{}");
// Clean keys for display
const labelMap = {
'ApplicantIncome': 'Income',
'LoanAmount': 'Loan Size',
'Total_Income': 'Total Rev',
'EMI': 'EMI Load',
'Credit_History': 'Credit Score'
};
const keys = Object.keys(labelMap);
// Normalize values roughly for radar (0-100 scale)
const normalize = (val, max) => Math.min(100, (val / max) * 100);
const userData = [
normalize(userResults.applicant_income, benchmarks.ApplicantIncome * 2 || 10000),
normalize(userResults.loan_amount, benchmarks.LoanAmount * 2 || 500),
normalize(userResults.applicant_income + userResults.coapplicant_income, benchmarks.Total_Income * 2 || 15000),
normalize((userResults.loan_amount * 1000) / userResults.loan_amount_term, benchmarks.EMI * 2 || 2000),
userResults.credit_history * 100
];
const benchData = [50, 50, 50, 50, 50]; // Benchmarks are normalized to center
const data = {
labels: keys.map(k => labelMap[k]),
datasets: [
{
label: 'Your Profile',
data: userData,
backgroundColor: 'rgba(242, 98, 47, 0.2)',
borderColor: '#f2622f',
borderWidth: 2,
pointBackgroundColor: '#f2622f',
},
{
label: 'Approved Average',
data: benchData,
backgroundColor: 'rgba(107, 114, 128, 0.1)',
borderColor: '#9ca3af',
borderWidth: 1,
borderDash: [5, 5],
pointRadius: 0
}
]
};
const options = {
scales: {
r: {
angleLines: { display: false },
suggestedMin: 0,
suggestedMax: 100,
ticks: { display: false }
}
},
plugins: {
legend: { position: 'bottom', labels: { boxWidth: 12, font: { size: 10 } } }
}
};
return <Radar data={data} options={options} />;
}
export function FeatureImportanceBar({ featuresJson }) {
let features = {};
try {
features = JSON.parse(featuresJson);
} catch(e) {
return null;
}
const sorted = Object.entries(features)
.sort(([, a], [, b]) => b - a)
.slice(0, 5);
const data = {
labels: sorted.map(([k]) => k.replace(/_/g, ' ')),
datasets: [{
label: 'Impact Score',
data: sorted.map(([,v]) => v),
backgroundColor: '#f2622f',
borderRadius: 6
}]
};
const options = {
indexAxis: 'y',
plugins: { legend: { display: false } },
scales: {
x: { display: false },
y: { grid: { display: false }, ticks: { font: { size: 11 } } }
}
};
return <Bar data={data} options={options} />;
}