2dc55f29db
Donut chart showing exact/tendency/wrong distribution. Scrollable tip history with point badges. Fun stats: favorite tip, home win percentage. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
66 lines
2.0 KiB
TypeScript
66 lines
2.0 KiB
TypeScript
import styles from './StatsRing.module.css';
|
|
|
|
interface Props {
|
|
exact: number;
|
|
tendency: number;
|
|
wrong: number;
|
|
total: number;
|
|
}
|
|
|
|
export default function StatsRing({ exact, tendency, wrong, total }: Props) {
|
|
const radius = 55;
|
|
const circumference = 2 * Math.PI * radius;
|
|
const all = exact + tendency + wrong || 1;
|
|
|
|
const segments = [
|
|
{ value: exact / all, color: 'var(--gold)', label: 'Exakt' },
|
|
{ value: tendency / all, color: 'var(--success)', label: 'Tendenz' },
|
|
{ value: wrong / all, color: 'var(--error)', label: 'Falsch' },
|
|
];
|
|
|
|
let offset = 0;
|
|
|
|
return (
|
|
<div className={styles.ring}>
|
|
<svg viewBox="0 0 140 140" className={styles.svg}>
|
|
{/* Background circle */}
|
|
<circle cx="70" cy="70" r={radius} fill="none" stroke="var(--surface-high)" strokeWidth="12" />
|
|
{segments.map((seg, i) => {
|
|
if (seg.value === 0) return null;
|
|
const dashArray = `${seg.value * circumference} ${circumference}`;
|
|
const rotation = offset * 360 - 90;
|
|
offset += seg.value;
|
|
return (
|
|
<circle
|
|
key={i}
|
|
cx="70" cy="70" r={radius}
|
|
fill="none"
|
|
stroke={seg.color}
|
|
strokeWidth="12"
|
|
strokeDasharray={dashArray}
|
|
transform={`rotate(${rotation} 70 70)`}
|
|
strokeLinecap="round"
|
|
/>
|
|
);
|
|
})}
|
|
<text x="70" y="65" textAnchor="middle" dominantBaseline="central"
|
|
fill="var(--text-primary)" fontSize="28" fontWeight="700">
|
|
{total}
|
|
</text>
|
|
<text x="70" y="85" textAnchor="middle"
|
|
fill="var(--text-secondary)" fontSize="11">
|
|
Punkte
|
|
</text>
|
|
</svg>
|
|
<div className={styles.legend}>
|
|
{segments.map((seg, i) => (
|
|
<span key={i} className={styles.legendItem}>
|
|
<span className={styles.dot} style={{ background: seg.color }} />
|
|
{seg.label}: {Math.round(seg.value * all)}
|
|
</span>
|
|
))}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|