======= // Premium player data with enhanced metrics and real-time updates const premiumPlayers = { "top-scorer": { name: "Erling Haaland", team: "Manchester City", image: "http://static.photos/sport/200x200/101", stats: [ { stat: 'Goals', value: 94, max: 100 }, { stat: 'Assists', value: 31, max: 50 }, { stat: 'Pass Accuracy', value: 85, max: 100 }, { stat: 'Dribbles', value: 68, max: 100 }, { stat: 'Tackles', value: 22, max: 50 }, { stat: 'Duels Win %', value: 71, max: 100 }, { stat: 'Expected Goals', value: 88, max: 100 }, { stat: 'Shot Conversion', value: 92, max: 100 }, { stat: 'Aerial Duels', value: 84, max: 100 } ], marketValue: "€180M", form: "8.4/10", aiPrediction: "92% chance of Golden Boot" }, "top-assists": { name: "Kevin De Bruyne", team: "Manchester City", image: "http://static.photos/sport/200x200/102", stats: [ { stat: 'Goals', value: 21, max: 100 }, { stat: 'Assists', value: 49, max: 50 }, { stat: 'Pass Accuracy', value: 93, max: 100 }, { stat: 'Dribbles', value: 82, max: 100 }, { stat: 'Tackles', value: 37, max: 50 }, { stat: 'Duels Win %', value: 63, max: 100 }, { stat: 'Key Passes', value: 95, max: 100 }, { stat: 'Through Balls', value: 91, max: 100 }, { stat: 'Chances Created', value: 89, max: 100 } ], marketValue: "€90M", form: "8.7/10", aiPrediction: "Top 3 in Assists next season" }, "top-passer": { name: "Rodri", team: "Manchester City", image: "http://static.photos/sport/200x200/103", stats: [ { stat: 'Goals', value: 15, max: 100 }, { stat: 'Assists', value: 22, max: 50 }, { stat: 'Pass Accuracy', value: 96, max: 100 }, { stat: 'Dribbles', value: 86, max: 100 }, { stat: 'Tackles', value: 72, max: 50 }, { stat: 'Duels Win %', value: 79, max: 100 }, { stat: 'Long Passes', value: 94, max: 100 }, { stat: 'Passes Completed', value: 97, max: 100 }, { stat: 'Possession Won', value: 88, max: 100 } ], marketValue: "€110M", form: "8.9/10", aiPrediction: "Best Defensive Midfielder in Europe" }, "top-defender": { name: "Virgil van Dijk", team: "Liverpool", image: "http://static.photos/sport/200x200/104", stats: [ { stat: 'Goals', value: 7, max: 100 }, { stat: 'Assists', value: 5, max: 50 }, { stat: 'Pass Accuracy', value: 92, max: 100 }, { stat: 'Dribbles', value: 58, max: 100 }, { stat: 'Tackles', value: 83, max: 50 }, { stat: 'Duels Win %', value: 86, max: 100 }, { stat: 'Aerial Duels', value: 95, max: 100 }, { stat: 'Interceptions', value: 89, max: 100 }, { stat: 'Clearances', value: 91, max: 100 }, { stat: 'Blocks', value: 87, max: 100 }, { stat: 'Recoveries', value: 93, max: 100 } ], marketValue: "€75M", form: "8.6/10", aiPrediction: "Return to peak defensive form" }, "top-creator": { name: "Lionel Messi", team: "Inter Miami", image: "http://static.photos/sport/200x200/105", stats: [ { stat: 'Goals', value: 28, max: 100 }, { stat: 'Assists', value: 42, max: 50 }, { stat: 'Pass Accuracy', value: 89, max: 100 }, { stat: 'Dribbles', value: 95, max: 100 }, { stat: 'Tackles', value: 26, max: 50 }, { stat: 'Duels Win %', value: 72, max: 100 }, { stat: 'Key Passes', value: 97, max: 100 }, { stat: 'Chances Created', value: 94, max: 100 }, { stat: 'Free Kicks', value: 93, max: 100 }, { stat: 'Dribbles Success', value: 91, max: 100 } ], marketValue: "€60M", form: "8.8/10", aiPrediction: "Top creator in MLS with 15+ assists" }, "top-goalkeeper": { name: "Alisson Becker", team: "Liverpool", image: "http://static.photos/sport/200x200/106", stats: [ { stat: 'Clean Sheets', value: 78, max: 100 }, { stat: 'Saves', value: 86, max: 100 }, { stat: 'Pass Accuracy', value: 88, max: 100 }, { stat: 'Goals Conceded', value: 24, max: 100 }, { stat: 'Penalty Saves', value: 82, max: 100 }, { stat: 'Claims', value: 91, max: 100 }, { stat: 'Sweeper Actions', value: 87, max: 100 }, { stat: 'Distribution', value: 89, max: 100 }, { stat: 'Reflex Saves', value: 94, max: 100 }, { stat: 'Aerial Duels', value: 92, max: 100 }, { stat: 'Command Area', value: 95, max: 100 } ], marketValue: "€70M", form: "8.5/10", aiPrediction: "Golden Glove contender in Premier League" } }; document.addEventListener('DOMContentLoaded', function() { // Load initial premium player data loadPremiumPlayerData('top-scorer'); }); function loadPremiumPlayerData(playerType) { // Enhanced loading animation const placeholder = document.getElementById('chart-placeholder'); placeholder.innerHTML = '
Loading premium analytics...
'; placeholder.style.display = 'block'; // Show real-time data indicator const liveIndicator = document.querySelector('.flex.items-center.gap-2'); if (liveIndicator) { liveIndicator.classList.add('animate-pulse'); } // Simulate API delay with enhanced UX setTimeout(() => { // Hide placeholder placeholder.style.display = 'none'; // Get premium player data const playerData = premiumPlayers[playerType]; // Draw enhanced radar chart drawPremiumRadarChart(playerData); // Update additional info panels updatePlayerInfo(playerData); }, 600); } function updatePlayerInfo(playerData) { // Update player info card if it exists const infoCard = document.querySelector('.player-info-card'); if (infoCard) { infoCard.innerHTML = `
${playerData.name}

${playerData.name}

${playerData.team}

Market Value
${playerData.marketValue}
Current Form
${playerData.form}
AI Prediction
${playerData.aiPrediction}
`; } } function drawPremiumRadarChart(playerData) { // Enhanced radar chart with premium features d3.select("#player-radar-chart svg").remove(); const data = playerData.stats; const playerName = playerData.name; const playerTeam = playerData.team; // Premium dimensions and margins const margin = { top: 120, right: 120, bottom: 120, left: 120 }; const width = Math.min(800, window.innerWidth - 80) - margin.left - margin.right; const height = Math.min(width, window.innerHeight - margin.top - margin.bottom - 40); const radius = Math.min(width, height) / 2; // Create enhanced SVG const svg = d3.select("#player-radar-chart") .append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", `translate(${margin.left + width/2}, ${margin.top + height/2})`); // Enhanced levels and axes const levels = 6; const angleSlice = Math.PI * 2 / data.length; // Premium scale with smooth interpolation const rScale = d3.scaleLinear() .range([0, radius]) .domain([0, 100]); // Draw premium circular grid with gradient effects for (let level = 1; level <= levels; level++) { const levelFactor = radius * level / levels; // Enhanced grid lines svg.selectAll(".premium-levels") .data(data) .enter() .append("line") .attr("x1", (d, i) => levelFactor * Math.cos(angleSlice * i - Math.PI / 2)) .attr("y1", (d, i) => levelFactor * Math.sin(angleSlice * i - Math.PI / 2)) .attr("x2", (d, i) => levelFactor * Math.cos(angleSlice * (i + 1) - Math.PI / 2)) .attr("y2", (d, i) => levelFactor * Math.sin(angleSlice * (i + 1) - Math.PI / 2)) .attr("stroke", level === levels ? "#3b82f6" : "#e2e8f0") .attr("stroke-width", level === levels ? 2 : 1) .attr("stroke-opacity", 0.6); // Premium level circles with gradient svg.append("circle") .attr("cx", 0) .attr("cy", 0) .attr("r", levelFactor) .attr("fill", "none") .attr("stroke", level === levels ? "#3b82f6" : "#e2e8f0") .attr("stroke-width", level === levels ? 2 : 0.5) .attr("stroke-opacity", 0.4); } // Enhanced axes with premium styling const axis = svg.selectAll(".premium-axis") .data(data) .enter() .append("g") .attr("class", "premium-axis"); axis.append("line") .attr("x1", 0) .attr("y1", 0) .attr("x2", (d, i) => radius * Math.cos(angleSlice * i - Math.PI / 2)) .attr("y2", (d, i) => radius * Math.sin(angleSlice * i - Math.PI / 2)) .attr("stroke", "#94a3b8") .attr("stroke-width", 1) .attr("stroke-opacity", 0.5); // Premium axis labels axis.append("text") .attr("class", "premium-axis-label") .attr("x", (d, i) => (radius + 30) * Math.cos(angleSlice * i - Math.PI / 2)) .attr("y", (d, i) => (radius + 30) * Math.sin(angleSlice * i - Math.PI / 2)) .attr("dy", "0.35em") .attr("text-anchor", "middle") .text(d => d.stat) .attr("fill", "#475569") .attr("font-size", "13px") .attr("font-weight", "600"); // Enhanced radar line with premium styling const radarLine = d3.line() .x((d, i) => rScale(d.value) * Math.cos(angleSlice * i - Math.PI / 2)) .y((d, i) => rScale(d.value) * Math.sin(angleSlice * i - Math.PI / 2)) .curve(d3.curveCatmullRomClosed); // Premium radar group const radarGroup = svg.append("g") .attr("class", "premium-radar-group"); // Enhanced radar area with gradient radarGroup.append("path") .datum(data) .attr("class", "premium-radar-area") .attr("d", radarLine) .attr("fill", "url(#radar-gradient)") .attr("stroke", "url(#radar-line-gradient)") .attr("stroke-width", 3); // Enhanced data points radarGroup.selectAll(".premium-radar-circle") .data(data) .enter() .append("circle") .attr("class", "premium-radar-circle") .attr("cx", (d, i) => rScale(d.value) * Math.cos(angleSlice * i - Math.PI / 2)) .attr("cy", (d, i) => rScale(d.value) * Math.sin(angleSlice * i - Math.PI / 2)) .attr("r", 6) .attr("fill", "url(#point-gradient)") .attr("stroke", "#ffffff") .attr("stroke-width", 2); // Premium player name with enhanced styling svg.append("text") .attr("class", "premium-player-name") .attr("x", 0) .attr("y", -height/2 + 40) .attr("text-anchor", "middle") .text(`${playerName} | ${playerTeam}") .attr("fill", "#1e293b") .attr("font-size", "22px") .attr("font-weight", "bold"); // Enhanced value labels radarGroup.selectAll(".premium-value-label") .data(data) .enter() .append("text") .attr("class", "premium-value-label") .attr("x", (d, i) => (rScale(d.value) + 20) * Math.cos(angleSlice * i - Math.PI / 2)) .attr("y", (d, i) => (rScale(d.value) + 20) * Math.sin(angleSlice * i - Math.PI / 2)) .attr("dy", "0.35em") .attr("text-anchor", "middle") .text(d => d.value) .attr("fill", "#3b82f6") .attr("font-size", "14px") .attr("font-weight", "bold"); } function initializePremiumCharts() { // Initialize the performance trend chart const ctx = document.getElementById('performanceChart'); if (ctx) { const chartLoader = document.getElementById('chartLoader'); if (chartLoader) chartLoader.style.display = 'none'; new Chart(ctx, { type: 'line', data: { labels: ['Aug', 'Sep', 'Oct', 'Nov', 'Dec', 'Jan', 'Feb'], datasets: [{ label: 'Form Rating', data: [7.8, 8.2, 8.6, 8.9, 8.7, 8.8, 9.1], borderColor: '#3b82f6', backgroundColor: 'rgba(59, 130, 246, 0.1), tension: 0.4, fill: true, pointBackgroundColor: '#3b82f6', pointBorderColor: '#ffffff', pointBorderWidth: 2, pointRadius: 4, pointHoverRadius: 6 }] }, options: { responsive: true, plugins: { legend: { display: false }, tooltip: { backgroundColor: 'rgba(0, 0, 0, 0.8), titleColor: '#ffffff', bodyColor: '#ffffff' } }, scales: { y: { beginAtZero: false, min: 7, max: 10, grid: { color: 'rgba(0, 0, 0, 0.05), border: { dash: [4, 4] } }, x: { grid: { display: false } } } } }); } } function drawRadarChart(playerData) { // Clear previous chart d3.select("#player-radar-chart svg").remove(); const data = playerData.stats; const playerName = playerData.name; const playerTeam = playerData.team; // Set up dimensions const margin = { top: 100, right: 100, bottom: 100, left: 100 }; const width = Math.min(700, window.innerWidth - 40) - margin.left - margin.right; const height = Math.min(width, window.innerHeight - margin.top - margin.bottom - 20); const radius = Math.min(width, height) / 2; // Create SVG const svg = d3.select("#player-radar-chart") .append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", `translate(${margin.left + width/2}, ${margin.top + height/2})`); // Levels and axes const levels = 5; const angleSlice = Math.PI * 2 / data.length; // Scale for the radius const rScale = d3.scaleLinear() .range([0, radius]) .domain([0, 100]); // Draw circular grid lines for (let level = 1; level <= levels; level++) { const levelFactor = radius * level / levels; svg.selectAll(".levels") .data(data) .enter() .append("line") .attr("x1", (d, i) => levelFactor * Math.cos(angleSlice * i - Math.PI / 2)) .attr("y1", (d, i) => levelFactor * Math.sin(angleSlice * i - Math.PI / 2)) .attr("x2", (d, i) => levelFactor * Math.cos(angleSlice * (i + 1) - Math.PI / 2)) .attr("y2", (d, i) => levelFactor * Math.sin(angleSlice * (i + 1) - Math.PI / 2)) .attr("stroke", "#e2e8f0") .attr("stroke-width", 1); // Draw level circles svg.append("circle") .attr("cx", 0) .attr("cy", 0) .attr("r", levelFactor) .attr("fill", "none") .attr("stroke", "#e2e8f0") .attr("stroke-width", 0.5); } // Draw axes const axis = svg.selectAll(".axis") .data(data) .enter() .append("g") .attr("class", "axis"); axis.append("line") .attr("x1", 0) .attr("y1", 0) .attr("x2", (d, i) => radius * Math.cos(angleSlice * i - Math.PI / 2)) .attr("y2", (d, i) => radius * Math.sin(angleSlice * i - Math.PI / 2)) .attr("stroke", "#94a3b8") .attr("stroke-width", 1); // Draw axis labels axis.append("text") .attr("class", "axis-label") .attr("x", (d, i) => (radius + 20) * Math.cos(angleSlice * i - Math.PI / 2)) .attr("y", (d, i) => (radius + 20) * Math.sin(angleSlice * i - Math.PI / 2)) .attr("dy", "0.35em") .attr("text-anchor", "middle") .text(d => d.stat) .attr("fill", "#64748b") .attr("font-size", "12px"); // Draw radar area const radarLine = d3.line() .x((d, i) => rScale(d.value) * Math.cos(angleSlice * i - Math.PI / 2)) .y((d, i) => rScale(d.value) * Math.sin(angleSlice * i - Math.PI / 2)) .curve(d3.curveLinearClosed); // Create a group for the radar const radarGroup = svg.append("g") .attr("class", "radar-group"); // Draw the radar area radarGroup.append("path") .datum(data) .attr("class", "radar-area") .attr("d", radarLine) .attr("fill", "rgba(59, 130, 246, 0.4)") .attr("stroke", "rgba(59, 130, 246, 1)") .attr("stroke-width", 2); // Draw data points radarGroup.selectAll(".radar-circle") .data(data) .enter() .append("circle") .attr("class", "radar-circle") .attr("cx", (d, i) => rScale(d.value) * Math.cos(angleSlice * i - Math.PI / 2)) .attr("cy", (d, i) => rScale(d.value) * Math.sin(angleSlice * i - Math.PI / 2)) .attr("r", 4) .attr("fill", "rgba(59, 130, 246, 1)") .attr("stroke", "#fff") .attr("stroke-width", 1); // Add player name svg.append("text") .attr("class", "player-name") .attr("x", 0) .attr("y", -height/2 + 30) .attr("text-anchor", "middle") .text(`${playerName} - ${playerTeam}`) .attr("fill", "#1e293b") .attr("font-size", "18px") .attr("font-weight", "bold"); // Add value labels radarGroup.selectAll(".value-label") .data(data) .enter() .append("text") .attr("class", "value-label") .attr("x", (d, i) => (rScale(d.value) + 15) * Math.cos(angleSlice * i - Math.PI / 2)) .attr("y", (d, i) => (rScale(d.value) + 15) * Math.sin(angleSlice * i - Math.PI / 2)) .attr("dy", "0.35em") .attr("text-anchor", "middle") .text(d => d.value) .attr("fill", "#64748b") .attr("font-size", "11px") .attr("font-weight", "bold"); }