mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-24 20:19:49 +02:00
feat: nivo graph
This commit is contained in:
1 parent
499bcde320
commit
86d7007dc2
8 files changed
+102
-2
No files matched your search
Vendored
+1
@@ -102,6 +102,7 @@
|
|||||||
"NEGATIVEX",
|
"NEGATIVEX",
|
||||||
"NEGATIVEY",
|
"NEGATIVEY",
|
||||||
"NEGATIVEZ",
|
"NEGATIVEZ",
|
||||||
|
"nivo",
|
||||||
"nmatname",
|
"nmatname",
|
||||||
"noout",
|
"noout",
|
||||||
"normalmap",
|
"normalmap",
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@gltf-transform/core": "^3.9.0",
|
"@gltf-transform/core": "^3.9.0",
|
||||||
|
"@nivo/bar": "^0.87.0",
|
||||||
"@octokit/plugin-throttling": "^8.1.3",
|
"@octokit/plugin-throttling": "^8.1.3",
|
||||||
"@octokit/rest": "^20.0.1",
|
"@octokit/rest": "^20.0.1",
|
||||||
"@prisma/client": "^5.4.1",
|
"@prisma/client": "^5.4.1",
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ export function Header() {
|
|||||||
const sort = useTankPerformanceSort();
|
const sort = useTankPerformanceSort();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Table.Header style={{ whiteSpace: 'nowrap' }}>
|
<Table.Header>
|
||||||
<Table.Row align="center">
|
<Table.Row align="center">
|
||||||
<Table.ColumnHeaderCell>Tank</Table.ColumnHeaderCell>
|
<Table.ColumnHeaderCell>Tank</Table.ColumnHeaderCell>
|
||||||
{tankPerformanceSortTypeNamesArray.map((type) => {
|
{tankPerformanceSortTypeNamesArray.map((type) => {
|
||||||
@@ -24,6 +24,7 @@ export function Header() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Table.ColumnHeaderCell
|
<Table.ColumnHeaderCell
|
||||||
|
px="2"
|
||||||
key={type}
|
key={type}
|
||||||
width="0"
|
width="0"
|
||||||
justify="center"
|
justify="center"
|
||||||
|
|||||||
@@ -0,0 +1,85 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { ResponsiveBar } from '@nivo/bar';
|
||||||
|
import { Box, Flex, Heading } from '@radix-ui/themes';
|
||||||
|
import { times } from 'lodash';
|
||||||
|
import { use } from 'react';
|
||||||
|
import { TankClass } from '../../../../components/Tanks';
|
||||||
|
import { TANK_CLASSES } from '../../../../components/Tanks/components/Item/constants';
|
||||||
|
import { averageDefinitionsArray } from '../../../../core/blitzkit/averageDefinitions';
|
||||||
|
import {
|
||||||
|
tankDefinitions,
|
||||||
|
Tier,
|
||||||
|
} from '../../../../core/blitzkit/tankDefinitions';
|
||||||
|
import { TIER_ROMAN_NUMERALS } from '../../../../core/blitzkit/tankDefinitions/constants';
|
||||||
|
import { nivoTheme } from '../../../../core/nivo/theme';
|
||||||
|
import strings from '../../../../lang/en-US.json';
|
||||||
|
|
||||||
|
export function TierBreakdown() {
|
||||||
|
const awaitedAverageDefinitionsArray = use(averageDefinitionsArray);
|
||||||
|
const awaitedTankDefinitions = use(tankDefinitions);
|
||||||
|
const numberFormat = Intl.NumberFormat(undefined, { notation: 'compact' });
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Flex justify="center" py="6">
|
||||||
|
<Flex direction="column" flexGrow="1" gap="4" maxWidth="640px">
|
||||||
|
<Heading ml="2" size="4">
|
||||||
|
Players (30d) per tier
|
||||||
|
</Heading>
|
||||||
|
|
||||||
|
<Box height="320px" width="100%">
|
||||||
|
<ResponsiveBar
|
||||||
|
{...nivoTheme}
|
||||||
|
data={times(10, (index) => {
|
||||||
|
const tier = (index + 1) as Tier;
|
||||||
|
const tierTanks = awaitedAverageDefinitionsArray.filter(
|
||||||
|
({ id }) => awaitedTankDefinitions[id].tier === tier,
|
||||||
|
);
|
||||||
|
const populations: Record<TankClass, number> = {
|
||||||
|
'AT-SPG': 0,
|
||||||
|
heavyTank: 0,
|
||||||
|
lightTank: 0,
|
||||||
|
mediumTank: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
tierTanks.forEach((stats) => {
|
||||||
|
const tank = awaitedTankDefinitions[stats.id];
|
||||||
|
populations[tank.class] += stats.mu.battles * stats.samples;
|
||||||
|
});
|
||||||
|
|
||||||
|
TANK_CLASSES.forEach((tankClass) => {
|
||||||
|
populations[tankClass] = Math.round(populations[tankClass]);
|
||||||
|
});
|
||||||
|
|
||||||
|
return { tier: TIER_ROMAN_NUMERALS[tier], ...populations };
|
||||||
|
})}
|
||||||
|
keys={[...TANK_CLASSES].reverse()}
|
||||||
|
indexBy="tier"
|
||||||
|
colors={{ scheme: 'dark2' }}
|
||||||
|
label={(d) => numberFormat.format(d.value as number)}
|
||||||
|
margin={{ right: 96, bottom: 20, left: 40 }}
|
||||||
|
legendLabel={(d) =>
|
||||||
|
strings.common.tank_class_short[d.id as TankClass]
|
||||||
|
}
|
||||||
|
axisLeft={{
|
||||||
|
tickSize: 0,
|
||||||
|
format: (value) => numberFormat.format(value as number),
|
||||||
|
}}
|
||||||
|
axisBottom={{ tickSize: 0 }}
|
||||||
|
legends={[
|
||||||
|
{
|
||||||
|
dataFrom: 'keys',
|
||||||
|
anchor: 'bottom-right',
|
||||||
|
direction: 'column',
|
||||||
|
translateX: 120,
|
||||||
|
itemsSpacing: 4,
|
||||||
|
itemWidth: 100,
|
||||||
|
itemHeight: 20,
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -3,12 +3,14 @@ import { TankFiltersProvider } from '../../../stores/tankFilters';
|
|||||||
import { FilterControl } from '../tankopedia/components/FilterControl';
|
import { FilterControl } from '../tankopedia/components/FilterControl';
|
||||||
import { Info } from './components/Info';
|
import { Info } from './components/Info';
|
||||||
import { TankTable } from './components/Table';
|
import { TankTable } from './components/Table';
|
||||||
|
import { TierBreakdown } from './components/TierBreakdown';
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
return (
|
return (
|
||||||
<TankFiltersProvider>
|
<TankFiltersProvider>
|
||||||
<PageWrapper color="jade" noMaxWidth>
|
<PageWrapper color="jade" noMaxWidth>
|
||||||
<Info />
|
<Info />
|
||||||
|
<TierBreakdown />
|
||||||
<FilterControl />
|
<FilterControl />
|
||||||
<TankTable />
|
<TankTable />
|
||||||
</PageWrapper>
|
</PageWrapper>
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ export const tankPerformanceTool: Tool = {
|
|||||||
id: 'tank-performance',
|
id: 'tank-performance',
|
||||||
title: 'Tank performance',
|
title: 'Tank performance',
|
||||||
description: 'Tank performance statistics',
|
description: 'Tank performance statistics',
|
||||||
pageDescription: 'Tank performance statistics in World of Tanks Blitz',
|
pageDescription: 'Best tanks and their performances in World of Tanks Blitz',
|
||||||
button: {
|
button: {
|
||||||
text: 'View tanks',
|
text: 'View tanks',
|
||||||
color: 'jade',
|
color: 'jade',
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import { Theme } from '@nivo/core';
|
||||||
|
|
||||||
|
export const nivoTheme = {
|
||||||
|
theme: {
|
||||||
|
text: { fill: 'var(--gray-11)' },
|
||||||
|
grid: { line: { stroke: 'var(--gray-3)' } },
|
||||||
|
} satisfies Theme,
|
||||||
|
borderRadius: 2,
|
||||||
|
innerPadding: 1,
|
||||||
|
};
|
||||||
Reference in new issue
Block a user