feat: add vertical BarChart
This commit is contained in:
parent
5cd793b278
commit
5c21cf1fc3
95
src/BarChart.tsx
Normal file
95
src/BarChart.tsx
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
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;
|
Loading…
x
Reference in New Issue
Block a user