pokedex-web / frontend /src /components /StatsRadar.js
gpimentel's picture
feat: implement anomaly detection ensemble, feedback system, and upgraded model configuration
d56d352
Raw
History Blame Contribute Delete
2.77 kB
'use client';
import { useEffect, useRef } from 'react';
import styles from './StatsRadar.module.css';
export default function StatsRadar({ stats }) {
const canvasRef = useRef(null);
useEffect(() => {
const canvas = canvasRef.current;
if (!canvas || !stats || Object.keys(stats).length === 0) return;
const ctx = canvas.getContext('2d');
const width = canvas.width;
const height = canvas.height;
const centerX = width / 2;
const centerY = height / 2;
const radius = Math.min(centerX, centerY) - 25;
const statKeys = ['hp', 'attack', 'defense', 'speed', 'sp_defense', 'sp_attack'];
const labels = ['HP', 'ATK', 'DEF', 'SPD', 'SpD', 'SpA'];
ctx.clearRect(0, 0, width, height);
ctx.strokeStyle = 'rgba(255, 255, 255, 0.1)';
ctx.lineWidth = 1;
for (let level = 1; level <= 3; level++) {
const levelRadius = radius * (level / 3);
ctx.beginPath();
for (let i = 0; i < 6; i++) {
const angle = (Math.PI / 3) * i - Math.PI / 2;
const x = centerX + levelRadius * Math.cos(angle);
const y = centerY + levelRadius * Math.sin(angle);
if (i === 0) ctx.moveTo(x, y);
else ctx.lineTo(x, y);
}
ctx.closePath();
ctx.stroke();
}
ctx.font = '10px monospace';
ctx.fillStyle = 'rgba(255, 255, 255, 0.6)';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
for (let i = 0; i < 6; i++) {
const angle = (Math.PI / 3) * i - Math.PI / 2;
const x = centerX + radius * Math.cos(angle);
const y = centerY + radius * Math.sin(angle);
ctx.beginPath();
ctx.moveTo(centerX, centerY);
ctx.lineTo(x, y);
ctx.stroke();
const labelX = centerX + (radius + 15) * Math.cos(angle);
const labelY = centerY + (radius + 15) * Math.sin(angle);
ctx.fillText(labels[i], labelX, labelY);
}
ctx.beginPath();
for (let i = 0; i < 6; i++) {
const statVal = stats[statKeys[i]] || 0;
const normalized = Math.min(statVal / 150, 1);
const angle = (Math.PI / 3) * i - Math.PI / 2;
const x = centerX + (radius * normalized) * Math.cos(angle);
const y = centerY + (radius * normalized) * Math.sin(angle);
if (i === 0) ctx.moveTo(x, y);
else ctx.lineTo(x, y);
}
ctx.closePath();
ctx.fillStyle = 'rgba(255, 255, 255, 0.3)';
ctx.fill();
ctx.strokeStyle = 'rgba(255, 255, 255, 0.8)';
ctx.lineWidth = 2;
ctx.stroke();
}, [stats]);
if (!stats || Object.keys(stats).length === 0) {
return null;
}
return (
<div className={styles.container}>
<canvas
ref={canvasRef}
width={220}
height={220}
className={styles.canvas}
/>
</div>
);
}