mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-11-04 16:30:37 +01:00
Feature: tank distribution scale on Tankopedia stats
This commit is contained in:
1 parent
2e10052732
commit
a0c54b50fc
2 files changed
+97
-8
No files matched your search
+26
-8
@@ -1,5 +1,5 @@
|
||||
import { createDefaultSkills } from "@blitzkit/core";
|
||||
import { Flex, Progress, Text } from "@radix-ui/themes";
|
||||
import { Box, Flex, Progress, Text } from "@radix-ui/themes";
|
||||
import { clamp } from "lodash-es";
|
||||
import { memo, useMemo, type ComponentProps, type ReactNode } from "react";
|
||||
import { api } from "../../../../../../core/blitzkit/api";
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
TankopediaRelativeAgainst,
|
||||
} from "../../../../../../stores/tankopedia";
|
||||
import { Info, type InfoProps } from "./Info";
|
||||
import { StatScale } from "./StatScale";
|
||||
|
||||
type InfoWithDeltaProps = Omit<InfoProps, "name"> & {
|
||||
stats: TankCharacteristics;
|
||||
@@ -122,6 +123,15 @@ export const InfoWithDelta = memo<InfoWithDeltaProps>(
|
||||
return othersValue !== undefined;
|
||||
}) as TankCharacteristics[];
|
||||
}, [relativeAgainst, shellIndex, equipmentMatrix, equalize]);
|
||||
const values = useMemo(
|
||||
() =>
|
||||
others.map((tank) =>
|
||||
typeof props.value === "function"
|
||||
? props.value(tank)!
|
||||
: (tank[props.value] as number),
|
||||
),
|
||||
[others],
|
||||
);
|
||||
const betterTanks = others.filter((tank) => {
|
||||
const othersValue =
|
||||
typeof props.value === "function"
|
||||
@@ -161,13 +171,21 @@ export const InfoWithDelta = memo<InfoWithDeltaProps>(
|
||||
|
||||
{!noRanking && (
|
||||
<Flex pl={indent ? "2" : "0"} align="center" gap="2">
|
||||
<Progress
|
||||
variant="soft"
|
||||
size="1"
|
||||
value={goodness * 100}
|
||||
color={color}
|
||||
style={{ height: "0.125rem", opacity: 0.5 }}
|
||||
/>
|
||||
<Box position="relative" flexGrow="1">
|
||||
<StatScale
|
||||
values={values}
|
||||
value={uhWhatDoICallThisVariable}
|
||||
lowerIsBetter={deltaType === "lowerIsBetter"}
|
||||
/>
|
||||
|
||||
<Progress
|
||||
variant="soft"
|
||||
size="1"
|
||||
value={goodness * 100}
|
||||
color={color}
|
||||
style={{ height: "0.125rem", opacity: 0.5 }}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<Text color="gray" size="1">
|
||||
{clamp(betterTanks.length + 1, 1, others.length)} /{" "}
|
||||
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
import { memo, useMemo } from "react";
|
||||
|
||||
const RESOLUTION = 1000;
|
||||
const HEIGHT = 9;
|
||||
const DENSE_TICKS = 100;
|
||||
|
||||
interface StatScaleProps {
|
||||
values: number[];
|
||||
value: number;
|
||||
lowerIsBetter?: boolean;
|
||||
}
|
||||
|
||||
export const StatScale = memo<StatScaleProps>(
|
||||
({ values, value, lowerIsBetter }) => {
|
||||
const ticks = useMemo(() => {
|
||||
const min = Math.min(value, ...values);
|
||||
const max = Math.max(value, ...values);
|
||||
const range = max - min;
|
||||
const counts = new Map<number, number>();
|
||||
|
||||
for (const other of values) {
|
||||
const raw = range === 0 ? 0.5 : (other - min) / range;
|
||||
const x = Math.round((lowerIsBetter ? 1 - raw : raw) * RESOLUTION);
|
||||
|
||||
if (x === 0 || x === RESOLUTION) continue;
|
||||
|
||||
counts.set(x, (counts.get(x) ?? 0) + 1);
|
||||
}
|
||||
|
||||
return Array.from(counts, ([x, count]) => ({
|
||||
x,
|
||||
color:
|
||||
count === 1
|
||||
? "var(--gray-a5)"
|
||||
: count <= 3
|
||||
? "var(--gray-a6)"
|
||||
: "var(--gray-a7)",
|
||||
}));
|
||||
}, [values, value, lowerIsBetter]);
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
width: "100%",
|
||||
height: HEIGHT,
|
||||
margin: "auto 0",
|
||||
opacity: Math.min(1, Math.sqrt(DENSE_TICKS / ticks.length)),
|
||||
pointerEvents: "none",
|
||||
}}
|
||||
>
|
||||
{ticks.map(({ x, color }) => (
|
||||
<div
|
||||
key={x}
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: 0,
|
||||
left: `${(x / RESOLUTION) * 100}%`,
|
||||
width: 1,
|
||||
height: "100%",
|
||||
backgroundColor: color,
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
);
|
||||
Reference in new issue
Block a user