96 lines
3.0 KiB
TypeScript
96 lines
3.0 KiB
TypeScript
import { FC } from 'react';
|
|
import { PlayerRanking } from './types';
|
|
|
|
interface BarChartProps {
|
|
players: PlayerRanking[];
|
|
width: number;
|
|
height: number;
|
|
std: boolean;
|
|
}
|
|
|
|
const BarChart: FC<BarChartProps> = ({ players, width, height, std }) => {
|
|
const padding = 24;
|
|
const maxValue = Math.max(...players.map((player) => player.rank)) + 1;
|
|
const barWidth = (width - 2 * padding) / players.length;
|
|
|
|
return (
|
|
<svg width={width} height={height}>
|
|
|
|
{players.map((player, index) => (
|
|
<rect
|
|
key={index}
|
|
x={index * barWidth + padding}
|
|
y={height - (1 - player.rank / maxValue) * height}
|
|
width={barWidth - 8} // subtract 2 for some spacing between bars
|
|
height={(1 - player.rank / maxValue) * height}
|
|
fill="#69f"
|
|
/>
|
|
))}
|
|
|
|
{players.map((player, index) => (
|
|
<text
|
|
key={index}
|
|
x={index * barWidth + barWidth / 2 - 4 + padding}
|
|
y={height - (1 - player.rank / maxValue) * height - 5}
|
|
textAnchor="middle"
|
|
//transform='rotate(-27)'
|
|
//style={{ transformOrigin: "center", transformBox: "fill-box" }}
|
|
fontSize="16px"
|
|
fill="#404040"
|
|
>
|
|
{player.name}
|
|
</text>
|
|
))}
|
|
|
|
{players.map((player, index) => (
|
|
<text
|
|
key={index}
|
|
x={index * barWidth + barWidth / 2 + padding - 4}
|
|
y={height - 8}
|
|
textAnchor="middle"
|
|
fontSize="12px"
|
|
fill="#404040"
|
|
>
|
|
{player.rank}
|
|
</text>
|
|
))}
|
|
|
|
{std && players.map((player, index) => (
|
|
<line
|
|
key={`error-${index}`}
|
|
x1={index * barWidth + barWidth / 2 + padding}
|
|
y1={height - (1 - player.rank / maxValue) * height - (player.std / maxValue) * height}
|
|
x2={index * barWidth + barWidth / 2 + padding}
|
|
y2={height - (1 - player.rank / maxValue) * height + (player.std / maxValue) * height}
|
|
stroke="#ff0000"
|
|
strokeWidth="1"
|
|
/>
|
|
))}
|
|
{std && players.map((player, index) => (
|
|
<line
|
|
key={`cap-${index}-top`}
|
|
x1={index * barWidth + barWidth / 2 - 2 + padding}
|
|
y1={height - (1 - player.rank / maxValue) * height - (player.std / maxValue) * height}
|
|
x2={index * barWidth + barWidth / 2 + 2 + padding}
|
|
y2={height - (1 - player.rank / maxValue) * height - (player.std / maxValue) * height}
|
|
stroke="#ff0000"
|
|
strokeWidth="1"
|
|
/>
|
|
))}
|
|
{std && players.map((player, index) => (
|
|
<line
|
|
key={`cap-${index}-bottom`}
|
|
x1={index * barWidth + barWidth / 2 - 2 + padding}
|
|
y1={height - (1 - player.rank / maxValue) * height + (player.std / maxValue) * height}
|
|
x2={index * barWidth + barWidth / 2 + 2 + padding}
|
|
y2={height - (1 - player.rank / maxValue) * height + (player.std / maxValue) * height}
|
|
stroke="#ff0000"
|
|
strokeWidth="1"
|
|
/>
|
|
))}
|
|
</svg>
|
|
);
|
|
};
|
|
|
|
export default BarChart;
|