feat: nivo graphs

This commit is contained in:
TrèsAbhi committed 2024-10-22 15:08:23 -05:00
1 parent f2da3994e4
commit 5e6f0e5d18
13 files changed
+157 -364

No files matched your search

@@ -1,57 +0,0 @@
import {
TIERS,
TIER_ROMAN_NUMERALS,
fetchAverageDefinitions,
fetchTankDefinitions,
} from '@blitzkit/core';
import { TankPerformanceEphemeral } from '../../../../stores/tankPerformanceEphemeral';
import { EChart } from '../../../EChart';
const averageDefinitions = await fetchAverageDefinitions();
const tankDefinitions = await fetchTankDefinitions();
const averageDefinitionsArray = Object.entries(averageDefinitions.averages);
export function BattleDistributionAcrossTiers() {
const playerCountPeriod = TankPerformanceEphemeral.use(
(state) => state.playerCountPeriod,
);
return (
<EChart
height="25rem"
title="Battle distribution across tiers"
option={{
xAxis: {
type: 'category',
data: TIERS.map((tier) => TIER_ROMAN_NUMERALS[tier]),
},
yAxis: {
type: 'value',
},
series: [
{
data: TIERS.map((tier) => {
return averageDefinitionsArray.reduce(
(accumulator, [idString, entry]) => {
const id = Number(idString);
const tank = tankDefinitions.tanks[id];
if (tank === undefined || tank.tier !== tier) {
return accumulator;
}
return (
accumulator +
entry.mu.battles * entry.samples[playerCountPeriod]
);
},
0,
);
}),
type: 'bar',
},
],
}}
/>
);
}
@@ -1,65 +0,0 @@
import {
TANK_CLASSES,
TIERS,
TIER_ROMAN_NUMERALS,
fetchAverageDefinitions,
fetchTankDefinitions,
} from '@blitzkit/core';
import strings from '@blitzkit/core/lang/en-US.json';
import { TankPerformanceEphemeral } from '../../../../stores/tankPerformanceEphemeral';
import { EChart } from '../../../EChart';
const averageDefinitions = await fetchAverageDefinitions();
const tankDefinitions = await fetchTankDefinitions();
const averageDefinitionsArray = Object.entries(averageDefinitions.averages);
export function BattleDistributionAcrossTiersByClass() {
const playerCountPeriod = TankPerformanceEphemeral.use(
(state) => state.playerCountPeriod,
);
return (
<EChart
height="25rem"
title="Battle distribution across tiers by class"
option={{
xAxis: {
type: 'category',
data: TIERS.map((tier) => TIER_ROMAN_NUMERALS[tier]),
},
yAxis: {
type: 'value',
},
legend: {
data: TANK_CLASSES.map((c) => strings.common.tank_class_short[c]),
},
series: TANK_CLASSES.map((c) => ({
name: strings.common.tank_class_short[c],
data: TIERS.map((tier) => {
return averageDefinitionsArray.reduce(
(accumulator, [idString, entry]) => {
const id = Number(idString);
const tank = tankDefinitions.tanks[id];
if (
tank === undefined ||
tank.tier !== tier ||
tank.class !== c
) {
return accumulator;
}
return (
accumulator +
entry.mu.battles * entry.samples[playerCountPeriod]
);
},
0,
);
}),
type: 'bar',
})),
}}
/>
);
}
@@ -0,0 +1,87 @@
import {
fetchAverageDefinitions,
fetchTankDefinitions,
formatCompact,
TANK_CLASSES,
TankClass,
TIER_ROMAN_NUMERALS,
TIERS,
} from '@blitzkit/core';
import strings from '@blitzkit/core/lang/en-US.json';
import { Box, Flex, Heading } from '@radix-ui/themes';
import { useAveragesExclusionRatio } from '../../../../hooks/useAveragesExclusionRatio';
import { TankPerformanceEphemeral } from '../../../../stores/tankPerformanceEphemeral';
import { ThemedBar } from '../../../Nivo/ThemedBar';
const averageDefinitions = await fetchAverageDefinitions();
const tankDefinitions = await fetchTankDefinitions();
const averageDefinitionsArray = Object.entries(averageDefinitions.averages);
export function BattleDistributionAcrossTiers() {
const playerCountPeriod = TankPerformanceEphemeral.use(
(state) => state.playerCountPeriod,
);
const ratio = useAveragesExclusionRatio();
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) 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,13 +1,11 @@
import { Flex } from '@radix-ui/themes';
import { BattleDistributionAcrossTiers } from './components/BattleDistributionAcrossTiers';
import { BattleDistributionAcrossTiersByClass } from './components/BattleDistributionAcrossTiersByClass';
import { BattleDistributionAcrossTiers } from './components/BattleDistributionAcrossTiersNivo';
export function Charts() {
return (
<Flex justify="center">
<Flex direction="column" maxWidth="45rem" flexGrow="1" py="6" gap="9">
<BattleDistributionAcrossTiers />
<BattleDistributionAcrossTiersByClass />
</Flex>
</Flex>
);
@@ -1,7 +1,7 @@
import { Flex, Select, Text } from '@radix-ui/themes';
import {
PlayerCountPeriod,
TankPerformanceEphemeral,
type PlayerCountPeriod,
} from '../../stores/tankPerformanceEphemeral';
export function PlayerCountControl() {
@@ -23,24 +23,13 @@ export function PlayerCountControl() {
>
<Select.Trigger />
<Select.Content>
<Select.Item value={PlayerCountPeriod.Past120Days}>
Past 120 days
</Select.Item>
<Select.Item value={PlayerCountPeriod.Past90Days}>
Past 90 days
</Select.Item>
<Select.Item value={PlayerCountPeriod.Past60Days}>
Past 60 days
</Select.Item>
<Select.Item value={PlayerCountPeriod.ThisMonth}>
This month
</Select.Item>
<Select.Item value={PlayerCountPeriod.ThisWeek}>
This week
</Select.Item>
<Select.Item value={PlayerCountPeriod.Yesterday}>
Yesterday
</Select.Item>
<Select.Item value="total">Total</Select.Item>
<Select.Item value="d_120">Past 120 days</Select.Item>
<Select.Item value="d_90">Past 90 days</Select.Item>
<Select.Item value="d_60">Past 60 days</Select.Item>
<Select.Item value="d_30">This month</Select.Item>
<Select.Item value="d_7">This week</Select.Item>
<Select.Item value="d_1">Yesterday</Select.Item>
</Select.Content>
</Select.Root>
</Flex>