feat: start of charts

This commit is contained in:
tresabhi committed 2024-12-23 12:48:52 -06:00
1 parent b6fd5eaa66
commit eb95230a5f
11 files changed
+192 -165

No files matched your search

@@ -1,100 +0,0 @@
import {
formatCompact,
TANK_CLASSES,
TankClass,
TIER_ROMAN_NUMERALS,
TIERS,
} from '@blitzkit/core';
import strings from '@blitzkit/core/lang/en-US.json';
import { useStore } from '@nanostores/react';
import { Box, Flex, Heading } from '@radix-ui/themes';
import { awaitableAverageDefinitions } from '../../../../core/awaitables/averageDefinitions';
import { awaitableTankDefinitions } from '../../../../core/awaitables/tankDefinitions';
import { filterTank } from '../../../../core/blitzkit/filterTank';
import { useAveragesExclusionRatio } from '../../../../hooks/useAveragesExclusionRatio';
import { $tankFilters } from '../../../../stores/tankFilters';
import { TankPerformanceEphemeral } from '../../../../stores/tankPerformanceEphemeral';
import { ThemedBar } from '../../../Nivo/ThemedBar';
const [tankDefinitions, averageDefinitions] = await Promise.all([
awaitableTankDefinitions,
awaitableAverageDefinitions,
]);
const averageDefinitionsArray = Object.entries(averageDefinitions.averages);
export function PlayersByTierAndClass() {
const playerCountPeriod = TankPerformanceEphemeral.use(
(state) => state.playerCountPeriod,
);
const ratio = useAveragesExclusionRatio();
const filters = useStore($tankFilters);
return (
<Flex direction="column" gap="4">
<Heading align="center">Players by tier & class</Heading>
<Box height="25rem">
<ThemedBar
data={TIERS.map((tier) => {
const players: Record<TankClass, number> = {
0: 0,
1: 0,
2: 0,
3: 0,
};
averageDefinitionsArray.forEach(([idString, entry]) => {
const id = Number(idString);
const tank = tankDefinitions.tanks[id];
if (
tank === undefined ||
tank.tier !== tier ||
!filterTank(filters, tank)
) {
return;
}
players[tank.class] += entry.samples[playerCountPeriod] * ratio;
});
const bar: Record<string, number | string> = {
tier: TIER_ROMAN_NUMERALS[tier],
};
TANK_CLASSES.forEach((c) => {
bar[strings.common.tank_class_short[c]] = players[c];
});
return bar;
})}
keys={TANK_CLASSES.map((c) => strings.common.tank_class_short[c])}
indexBy="tier"
margin={{ right: 90, bottom: 50, left: 90 }}
axisBottom={{
legend: 'Tier',
legendPosition: 'middle',
legendOffset: 32,
}}
axisLeft={{
legend: 'Players',
legendPosition: 'middle',
legendOffset: -60,
format: formatCompact,
}}
legends={[
{
dataFrom: 'keys',
anchor: 'bottom-right',
direction: 'column',
translateX: 120,
itemWidth: 100,
itemHeight: 20,
},
]}
valueFormat={formatCompact}
/>
</Box>
</Flex>
);
}
@@ -1,12 +0,0 @@
import { Flex } from '@radix-ui/themes';
import { PlayersByTierAndClass } from './components/PlayersByTierAndClass';
export function Charts() {
return (
<Flex justify="center">
<Flex direction="column" maxWidth="45rem" flexGrow="1" py="6" gap="9">
<PlayersByTierAndClass />
</Flex>
</Flex>
);
}
@@ -1,31 +0,0 @@
import { Tabs } from '@radix-ui/themes';
import {
TankPerformanceEphemeral,
TankPerformanceMode,
} from '../../stores/tankPerformanceEphemeral';
export function ModeSwitcher() {
const mode = TankPerformanceEphemeral.use((state) => state.mode);
const mutateTankPerformanceMode = TankPerformanceEphemeral.useMutation();
return (
<Tabs.Root
value={`${mode}`}
onValueChange={(value) => {
mutateTankPerformanceMode((draft) => {
draft.mode = Number(value) as TankPerformanceMode;
});
}}
mb="5"
>
<Tabs.List justify="center">
<Tabs.Trigger value={`${TankPerformanceMode.Table}`}>
Table
</Tabs.Trigger>
<Tabs.Trigger value={`${TankPerformanceMode.Charts}`}>
Charts
</Tabs.Trigger>
</Tabs.List>
</Tabs.Root>
);
}