feat: add value ± standard deviation to RaceChart

This commit is contained in:
julius 2025-03-02 20:09:54 +01:00
parent a52dae5605
commit de79970987
Signed by: julius
GPG Key ID: C80A63E6A5FD7092

View File

@ -1,5 +1,5 @@
import { FC, useEffect, useState } from 'react';
import { PlayerRanking } from './types';
import { FC, useEffect, useState } from "react";
import { PlayerRanking } from "./types";
interface RaceChartProps {
players: PlayerRanking[];
@ -8,38 +8,35 @@ interface RaceChartProps {
const determineNiceWidth = (width: number) => {
const max = 1080;
if (width >= max)
return max
else if (width > 768)
return width * 0.8
else
return width * 0.96
}
if (width >= max) return max;
else if (width > 768) return width * 0.8;
else return width * 0.96;
};
const RaceChart: FC<RaceChartProps> = ({ players, std }) => {
// State to store window's width and height
const [width, setWidth] = useState(determineNiceWidth(window.innerWidth));
const [height, setHeight] = useState(window.innerHeight);
//const [height, setHeight] = useState(window.innerHeight);
const height = players.length * 40;
// Update state on resize
useEffect(() => {
const handleResize = () => {
setWidth(determineNiceWidth(window.innerWidth));
setHeight(window.innerHeight);
//setHeight(window.innerHeight);
};
window.addEventListener('resize', handleResize);
window.addEventListener("resize", handleResize);
return () => {
window.removeEventListener('resize', handleResize);
window.removeEventListener("resize", handleResize);
};
}, []);
const padding = 24;
const gap = 8
const gap = 8;
const maxValue = Math.max(...players.map((player) => player.rank)) + 1;
const barHeight = (height - 2 * padding) / players.length;
return (
<svg width={width} height={height}>
{players.map((player, index) => (
<rect
key={index}
@ -48,25 +45,50 @@ const RaceChart: FC<RaceChartProps> = ({ players, std }) => {
width={(1 - player.rank / maxValue) * width}
height={barHeight - gap} // subtract 2 for some spacing between bars
fill="#36c"
/>))}
{players.map((player, index) => (
<text
key={index}
x={4}
y={index * barHeight + barHeight / 2 + padding + gap / 2}
width={(1 - player.rank / maxValue) * width}
height={barHeight - 8} // subtract 2 for some spacing between bars
fontSize={`${barHeight - 1.5 * gap}px`}
fill="aliceblue"
stroke='#36c'
strokeWidth={1.6}
fontWeight={"bold"}
paintOrder={"stroke fill"}
>{player.name}</text>
/>
))}
{players.map((player, index) => (
<g>
<text
key={index}
x={4}
y={index * barHeight + barHeight / 2 + padding + gap / 2}
width={(1 - player.rank / maxValue) * width}
height={barHeight - 8} // subtract 2 for some spacing between bars
fontSize={`${barHeight - 1.5 * gap}px`}
fill="aliceblue"
stroke="#36c"
strokeWidth={4}
fontWeight={"bold"}
paintOrder={"stroke fill"}
fontFamily="monospace"
>
{player.name}
</text>
<text
key={index}
x={
4 +
Math.max(...players.map((p, _) => p.name.length)) *
(barHeight - 1.5 * gap) *
0.66
}
y={index * barHeight + barHeight / 2 + padding + gap / 2}
width={(1 - player.rank / maxValue) * width}
height={barHeight - 8} // subtract 2 for some spacing between bars
fontSize={`${0.75 * (barHeight - 1.5 * gap)}px`}
fill="aliceblue"
stroke="#36c"
fontWeight={"bold"}
strokeWidth={4}
paintOrder={"stroke fill"}
>
{`${player.rank} ± ${player.std}`}
</text>
</g>
))}
</svg>
)
}
);
};
export default RaceChart;