Created
January 28, 2026 21:41
-
-
Save invalidred/99bd73e2be2e3975fbee09f66b511a83 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Resume Scoring V2 - Visualization</title> | |
| <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> | |
| <style> | |
| * { | |
| margin: 0; | |
| padding: 0; | |
| box-sizing: border-box; | |
| } | |
| body { | |
| font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif; | |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | |
| min-height: 100vh; | |
| padding: 20px; | |
| } | |
| .container { | |
| max-width: 1200px; | |
| margin: 0 auto; | |
| } | |
| header { | |
| text-align: center; | |
| color: white; | |
| margin-bottom: 30px; | |
| } | |
| header h1 { | |
| font-size: 2.5rem; | |
| margin-bottom: 10px; | |
| } | |
| header p { | |
| font-size: 1.1rem; | |
| opacity: 0.9; | |
| } | |
| .card { | |
| background: white; | |
| border-radius: 16px; | |
| padding: 24px; | |
| margin-bottom: 24px; | |
| box-shadow: 0 10px 40px rgba(0,0,0,0.2); | |
| } | |
| .card h2 { | |
| color: #333; | |
| margin-bottom: 16px; | |
| font-size: 1.4rem; | |
| border-bottom: 2px solid #667eea; | |
| padding-bottom: 8px; | |
| } | |
| .formula { | |
| background: #f8f9fa; | |
| border-left: 4px solid #667eea; | |
| padding: 16px; | |
| margin: 16px 0; | |
| font-family: 'Courier New', monospace; | |
| font-size: 1rem; | |
| border-radius: 0 8px 8px 0; | |
| } | |
| .grid { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); | |
| gap: 24px; | |
| } | |
| .chart-container { | |
| position: relative; | |
| height: 300px; | |
| } | |
| .slider-group { | |
| margin: 16px 0; | |
| } | |
| .slider-group label { | |
| display: block; | |
| margin-bottom: 8px; | |
| font-weight: 500; | |
| color: #333; | |
| } | |
| .slider-group input[type="range"] { | |
| width: 100%; | |
| height: 8px; | |
| border-radius: 4px; | |
| background: #ddd; | |
| outline: none; | |
| -webkit-appearance: none; | |
| } | |
| .slider-group input[type="range"]::-webkit-slider-thumb { | |
| -webkit-appearance: none; | |
| width: 20px; | |
| height: 20px; | |
| border-radius: 50%; | |
| background: #667eea; | |
| cursor: pointer; | |
| } | |
| .value-display { | |
| text-align: right; | |
| font-weight: bold; | |
| color: #667eea; | |
| font-size: 1.2rem; | |
| } | |
| .score-display { | |
| display: flex; | |
| justify-content: space-around; | |
| flex-wrap: wrap; | |
| gap: 16px; | |
| margin-top: 20px; | |
| } | |
| .score-box { | |
| text-align: center; | |
| padding: 20px 30px; | |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | |
| border-radius: 12px; | |
| color: white; | |
| min-width: 150px; | |
| } | |
| .score-box .label { | |
| font-size: 0.9rem; | |
| opacity: 0.9; | |
| margin-bottom: 8px; | |
| } | |
| .score-box .value { | |
| font-size: 2rem; | |
| font-weight: bold; | |
| } | |
| .explanation { | |
| color: #666; | |
| line-height: 1.6; | |
| margin: 12px 0; | |
| } | |
| .highlight { | |
| background: #fff3cd; | |
| padding: 2px 6px; | |
| border-radius: 4px; | |
| } | |
| table { | |
| width: 100%; | |
| border-collapse: collapse; | |
| margin: 16px 0; | |
| } | |
| th, td { | |
| padding: 12px; | |
| text-align: left; | |
| border-bottom: 1px solid #eee; | |
| } | |
| th { | |
| background: #f8f9fa; | |
| font-weight: 600; | |
| color: #333; | |
| } | |
| .weight-input { | |
| width: 60px; | |
| padding: 6px; | |
| border: 2px solid #ddd; | |
| border-radius: 6px; | |
| text-align: center; | |
| font-size: 1rem; | |
| } | |
| .weight-input:focus { | |
| border-color: #667eea; | |
| outline: none; | |
| } | |
| .competency-score { | |
| width: 80px; | |
| padding: 6px; | |
| border: 2px solid #ddd; | |
| border-radius: 6px; | |
| text-align: center; | |
| } | |
| footer { | |
| text-align: center; | |
| color: white; | |
| margin-top: 30px; | |
| opacity: 0.8; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <header> | |
| <h1>Resume Scoring V2</h1> | |
| <p>Interactive visualization of the scoring algorithm</p> | |
| </header> | |
| <!-- Overview Section --> | |
| <div class="card"> | |
| <h2>How V2 Scoring Works</h2> | |
| <p class="explanation"> | |
| The V2 scoring algorithm combines <span class="highlight">human-defined competency weights</span> | |
| with <span class="highlight">AI predictions</span> to produce a final resume score. | |
| The formula balances manual assessment with machine learning insights. | |
| </p> | |
| <div class="formula"> | |
| Combined Score = DISC Adjustment × (0.4 × Manual Score + 0.6 × Predicted Score) | |
| </div> | |
| <p class="explanation"> | |
| <strong>DISC Adjustment:</strong> Based on personality fit (0.85 to 1.15 multiplier)<br> | |
| <strong>Manual Score:</strong> Weighted average of competency scores (0-100)<br> | |
| <strong>Predicted Score:</strong> ML model prediction based on resume content (0-100) | |
| </p> | |
| </div> | |
| <!-- Interactive Calculator --> | |
| <div class="card"> | |
| <h2>Interactive Score Calculator</h2> | |
| <h3 style="margin: 20px 0 10px; color: #666;">Competency Scores & Weights</h3> | |
| <table> | |
| <thead> | |
| <tr> | |
| <th>Competency</th> | |
| <th>Weight (1-5)</th> | |
| <th>Score (0-5)</th> | |
| </tr> | |
| </thead> | |
| <tbody> | |
| <tr> | |
| <td>Experience</td> | |
| <td><input type="number" class="weight-input" id="w1" value="5" min="1" max="5"></td> | |
| <td><input type="number" class="competency-score" id="s1" value="4" min="0" max="5" step="0.5"></td> | |
| </tr> | |
| <tr> | |
| <td>Education</td> | |
| <td><input type="number" class="weight-input" id="w2" value="3" min="1" max="5"></td> | |
| <td><input type="number" class="competency-score" id="s2" value="3" min="0" max="5" step="0.5"></td> | |
| </tr> | |
| <tr> | |
| <td>Skills</td> | |
| <td><input type="number" class="weight-input" id="w3" value="4" min="1" max="5"></td> | |
| <td><input type="number" class="competency-score" id="s3" value="4.5" min="0" max="5" step="0.5"></td> | |
| </tr> | |
| <tr> | |
| <td>Communication</td> | |
| <td><input type="number" class="weight-input" id="w4" value="3" min="1" max="5"></td> | |
| <td><input type="number" class="competency-score" id="s4" value="3.5" min="0" max="5" step="0.5"></td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| <div class="grid"> | |
| <div class="slider-group"> | |
| <label>Predicted Score (ML Model): <span id="predictedValue" class="value-display">72</span></label> | |
| <input type="range" id="predictedScore" min="0" max="100" value="72"> | |
| </div> | |
| <div class="slider-group"> | |
| <label>DISC Adjustment: <span id="discValue" class="value-display">1.00</span></label> | |
| <input type="range" id="discAdjustment" min="85" max="115" value="100"> | |
| </div> | |
| </div> | |
| <div class="score-display"> | |
| <div class="score-box"> | |
| <div class="label">Manual Score</div> | |
| <div class="value" id="manualScoreDisplay">78</div> | |
| </div> | |
| <div class="score-box"> | |
| <div class="label">Predicted Score</div> | |
| <div class="value" id="predictedScoreDisplay">72</div> | |
| </div> | |
| <div class="score-box" style="background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%);"> | |
| <div class="label">Combined Score</div> | |
| <div class="value" id="combinedScoreDisplay">74</div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Charts --> | |
| <div class="grid"> | |
| <div class="card"> | |
| <h2>Score Composition</h2> | |
| <div class="chart-container"> | |
| <canvas id="compositionChart"></canvas> | |
| </div> | |
| </div> | |
| <div class="card"> | |
| <h2>Competency Breakdown</h2> | |
| <div class="chart-container"> | |
| <canvas id="competencyChart"></canvas> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Weight Impact Visualization --> | |
| <div class="card"> | |
| <h2>Combined Score vs. Manual Score (at different DISC adjustments)</h2> | |
| <p class="explanation"> | |
| This chart shows how the combined score changes as the manual score varies, | |
| with the predicted score held constant at the current slider value. | |
| </p> | |
| <div class="chart-container" style="height: 350px;"> | |
| <canvas id="sensitivityChart"></canvas> | |
| </div> | |
| </div> | |
| <!-- Formulas Reference --> | |
| <div class="card"> | |
| <h2>Formula Reference</h2> | |
| <div class="formula"> | |
| <strong>Manual Score Calculation:</strong><br><br> | |
| manual_score = (Σ weight[i] × score[i]) / (Σ weight[i]) × 20<br><br> | |
| <em>Where scores are 0-5 and result is scaled to 0-100</em> | |
| </div> | |
| <div class="formula"> | |
| <strong>Combined Score Calculation:</strong><br><br> | |
| combined_score = disc_adjustment × (0.4 × manual_score + 0.6 × predicted_score)<br><br> | |
| <em>Manual contributes 40%, AI prediction contributes 60%</em> | |
| </div> | |
| <div class="formula"> | |
| <strong>DISC Adjustment Range:</strong><br><br> | |
| 0.85 (poor fit) → 1.00 (neutral) → 1.15 (excellent fit) | |
| </div> | |
| </div> | |
| <footer> | |
| <p>WizeHire Resume Scoring V2 Visualization</p> | |
| </footer> | |
| </div> | |
| <script> | |
| // Chart instances | |
| let compositionChart, competencyChart, sensitivityChart; | |
| // Initialize charts | |
| function initCharts() { | |
| // Composition Chart (Doughnut) | |
| const compositionCtx = document.getElementById('compositionChart').getContext('2d'); | |
| compositionChart = new Chart(compositionCtx, { | |
| type: 'doughnut', | |
| data: { | |
| labels: ['Manual Score (40%)', 'Predicted Score (60%)'], | |
| datasets: [{ | |
| data: [40, 60], | |
| backgroundColor: ['#667eea', '#764ba2'], | |
| borderWidth: 0 | |
| }] | |
| }, | |
| options: { | |
| responsive: true, | |
| maintainAspectRatio: false, | |
| plugins: { | |
| legend: { | |
| position: 'bottom' | |
| } | |
| } | |
| } | |
| }); | |
| // Competency Chart (Radar) | |
| const competencyCtx = document.getElementById('competencyChart').getContext('2d'); | |
| competencyChart = new Chart(competencyCtx, { | |
| type: 'radar', | |
| data: { | |
| labels: ['Experience', 'Education', 'Skills', 'Communication'], | |
| datasets: [{ | |
| label: 'Weighted Score', | |
| data: [80, 60, 90, 70], | |
| backgroundColor: 'rgba(102, 126, 234, 0.2)', | |
| borderColor: '#667eea', | |
| pointBackgroundColor: '#667eea', | |
| borderWidth: 2 | |
| }] | |
| }, | |
| options: { | |
| responsive: true, | |
| maintainAspectRatio: false, | |
| scales: { | |
| r: { | |
| beginAtZero: true, | |
| max: 100 | |
| } | |
| }, | |
| plugins: { | |
| legend: { | |
| display: false | |
| } | |
| } | |
| } | |
| }); | |
| // Sensitivity Chart (Line) | |
| const sensitivityCtx = document.getElementById('sensitivityChart').getContext('2d'); | |
| sensitivityChart = new Chart(sensitivityCtx, { | |
| type: 'line', | |
| data: { | |
| labels: Array.from({length: 21}, (_, i) => i * 5), | |
| datasets: [ | |
| { | |
| label: 'DISC = 0.85 (Poor Fit)', | |
| data: [], | |
| borderColor: '#e74c3c', | |
| backgroundColor: 'transparent', | |
| borderWidth: 2, | |
| tension: 0.4 | |
| }, | |
| { | |
| label: 'DISC = 1.00 (Neutral)', | |
| data: [], | |
| borderColor: '#3498db', | |
| backgroundColor: 'transparent', | |
| borderWidth: 2, | |
| tension: 0.4 | |
| }, | |
| { | |
| label: 'DISC = 1.15 (Excellent Fit)', | |
| data: [], | |
| borderColor: '#2ecc71', | |
| backgroundColor: 'transparent', | |
| borderWidth: 2, | |
| tension: 0.4 | |
| } | |
| ] | |
| }, | |
| options: { | |
| responsive: true, | |
| maintainAspectRatio: false, | |
| scales: { | |
| x: { | |
| title: { | |
| display: true, | |
| text: 'Manual Score' | |
| } | |
| }, | |
| y: { | |
| title: { | |
| display: true, | |
| text: 'Combined Score' | |
| }, | |
| min: 0, | |
| max: 120 | |
| } | |
| }, | |
| plugins: { | |
| legend: { | |
| position: 'top' | |
| } | |
| } | |
| } | |
| }); | |
| } | |
| // Calculate scores | |
| function calculateScores() { | |
| // Get competency weights and scores | |
| const weights = [ | |
| parseFloat(document.getElementById('w1').value) || 1, | |
| parseFloat(document.getElementById('w2').value) || 1, | |
| parseFloat(document.getElementById('w3').value) || 1, | |
| parseFloat(document.getElementById('w4').value) || 1 | |
| ]; | |
| const scores = [ | |
| parseFloat(document.getElementById('s1').value) || 0, | |
| parseFloat(document.getElementById('s2').value) || 0, | |
| parseFloat(document.getElementById('s3').value) || 0, | |
| parseFloat(document.getElementById('s4').value) || 0 | |
| ]; | |
| // Calculate manual score | |
| const weightedSum = weights.reduce((sum, w, i) => sum + w * scores[i], 0); | |
| const totalWeight = weights.reduce((sum, w) => sum + w, 0); | |
| const manualScore = (weightedSum / totalWeight) * 20; // Scale to 0-100 | |
| // Get predicted score and DISC adjustment | |
| const predictedScore = parseFloat(document.getElementById('predictedScore').value); | |
| const discAdjustment = parseFloat(document.getElementById('discAdjustment').value) / 100; | |
| // Calculate combined score | |
| const combinedScore = discAdjustment * (0.4 * manualScore + 0.6 * predictedScore); | |
| // Update displays | |
| document.getElementById('predictedValue').textContent = predictedScore; | |
| document.getElementById('discValue').textContent = discAdjustment.toFixed(2); | |
| document.getElementById('manualScoreDisplay').textContent = manualScore.toFixed(0); | |
| document.getElementById('predictedScoreDisplay').textContent = predictedScore; | |
| document.getElementById('combinedScoreDisplay').textContent = Math.min(100, combinedScore).toFixed(0); | |
| // Update competency chart | |
| const competencyScores = scores.map((s, i) => (s / 5) * 100 * (weights[i] / 5)); | |
| competencyChart.data.datasets[0].data = competencyScores; | |
| competencyChart.update(); | |
| // Update sensitivity chart | |
| const manualScoreRange = Array.from({length: 21}, (_, i) => i * 5); | |
| sensitivityChart.data.datasets[0].data = manualScoreRange.map(m => 0.85 * (0.4 * m + 0.6 * predictedScore)); | |
| sensitivityChart.data.datasets[1].data = manualScoreRange.map(m => 1.00 * (0.4 * m + 0.6 * predictedScore)); | |
| sensitivityChart.data.datasets[2].data = manualScoreRange.map(m => 1.15 * (0.4 * m + 0.6 * predictedScore)); | |
| sensitivityChart.update(); | |
| } | |
| // Event listeners | |
| document.querySelectorAll('input').forEach(input => { | |
| input.addEventListener('input', calculateScores); | |
| }); | |
| // Initialize | |
| initCharts(); | |
| calculateScores(); | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment