feat: easier to read evolution

This commit is contained in:
TresAbhi committed 2023-06-29 18:39:59 +00:00
1 parent 90d4b76b31
commit e34a6c6e4b
8 files changed
+85 -90

No files matched your search

+1 -1
View File
@@ -20,7 +20,7 @@ import { AccountInfo } from '../types/accountInfo.js';
export default {
inProduction: true,
inDevelopment: false,
inDevelopment: true,
inPublic: true,
command: addStatTypeSubCommandGroups(
+1 -1
View File
@@ -20,7 +20,7 @@ import { AccountInfo } from '../types/accountInfo.js';
export default {
inProduction: true,
inDevelopment: true,
inDevelopment: false,
inPublic: true,
command: addStatTypeSubCommandGroups(
+3 -1
View File
@@ -1,16 +1,18 @@
import { blue, green, red } from '@radix-ui/colors';
import { blue, green, red, slateDark } from '@radix-ui/colors';
import { GRAPH_HEIGHT, GRAPH_WIDTH } from './Root.js';
export enum LineColor {
Red,
Green,
Blue,
White,
}
const LINE_COLORS = {
[LineColor.Red]: red.red9,
[LineColor.Green]: green.green9,
[LineColor.Blue]: blue.blue9,
[LineColor.White]: slateDark.slate11,
};
export enum LineStyle {
@@ -1,32 +1,34 @@
import { times } from 'lodash';
import { theme } from '../../../stitches.config.js';
import { MarginProps } from './Root.js';
import { MarginProps as RootMarginProps } from './Root.js';
export enum VerticalMarginAlign {
Left,
Right,
export enum MarginOrientation {
Vertical,
Horizontal,
}
export interface VerticalMarginProps extends MarginProps {
export interface MarginProps extends RootMarginProps {
verticalSeparations: number;
align?: VerticalMarginAlign;
orientation?: MarginOrientation;
}
export function VerticalMargin({
export function Margin({
verticalSeparations,
max,
min,
suffix,
align = VerticalMarginAlign.Left,
}: VerticalMarginProps) {
precision = 0,
orientation = MarginOrientation.Vertical,
}: MarginProps) {
const isVertical = orientation === MarginOrientation.Vertical;
return (
<div
style={{
width: 32,
paddingLeft: isVertical ? 0 : 64,
width: isVertical ? 48 : '100%',
display: 'flex',
flexDirection: 'column',
alignItems:
align === VerticalMarginAlign.Right ? 'flex-end' : 'flex-start',
flexDirection: isVertical ? 'column' : 'row-reverse',
justifyContent: 'space-between',
}}
>
@@ -43,7 +45,7 @@ export function VerticalMargin({
((verticalSeparations - (index + 1)) /
(verticalSeparations - 1)) +
min
).toFixed(0)}${suffix ?? ''}`}
).toFixed(precision)}${suffix ?? ''}`}
</span>
))}
</div>
+35 -38
View File
@@ -1,42 +1,55 @@
import { times } from 'lodash';
import { ReactNode } from 'react';
import { theme } from '../../../stitches.config.js';
import { VerticalMargin, VerticalMarginAlign } from './VerticalMargin.js';
import { Margin, MarginOrientation } from './Margin.js';
export const GRAPH_WIDTH = 512;
export const GRAPH_WIDTH = 544;
export const GRAPH_HEIGHT = 320;
export interface MarginProps {
min: number;
max: number;
suffix?: string;
precision?: number;
}
export interface RootProps {
children: ReactNode;
leftVerticalMargin?: MarginProps;
rightVerticalMargin?: MarginProps;
verticalSeparations?: number;
verticalMargin?: MarginProps;
horizontalMargin?: MarginProps;
separations?: number;
xMinLabel: string;
xMaxLabel: string;
}
export function Root({
children,
leftVerticalMargin,
rightVerticalMargin,
verticalSeparations = 5,
verticalMargin,
horizontalMargin,
separations = 5,
xMinLabel,
xMaxLabel,
}: RootProps) {
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
<div
style={{
paddingLeft: 64,
display: 'flex',
justifyContent: 'space-between',
}}
>
<span style={{ fontSize: 16, color: theme.colors.textLowContrast }}>
{xMinLabel}
</span>
<span style={{ fontSize: 16, color: theme.colors.textLowContrast }}>
{xMaxLabel}
</span>
</div>
<div style={{ display: 'flex', gap: 16 }}>
{leftVerticalMargin && (
<VerticalMargin
{...leftVerticalMargin}
verticalSeparations={verticalSeparations}
/>
{verticalMargin && (
<Margin {...verticalMargin} verticalSeparations={separations} />
)}
<svg
@@ -49,8 +62,8 @@ export function Root({
border: theme.borderStyles.nonInteractive,
}}
>
{times(verticalSeparations - 2, (index) => {
const y = GRAPH_HEIGHT * ((index + 1) / (verticalSeparations - 1));
{times(separations - 2, (index) => {
const y = GRAPH_HEIGHT * ((index + 1) / (separations - 1));
return (
<polyline
@@ -66,31 +79,15 @@ export function Root({
{children}
</svg>
{rightVerticalMargin && (
<VerticalMargin
{...rightVerticalMargin}
verticalSeparations={verticalSeparations}
align={VerticalMarginAlign.Right}
/>
)}
</div>
<div
style={{
paddingLeft: 48,
paddingRight: 48,
display: 'flex',
justifyContent: 'space-between',
}}
>
<span style={{ fontSize: 16, color: theme.colors.textLowContrast }}>
{xMinLabel}
</span>
<span style={{ fontSize: 16, color: theme.colors.textLowContrast }}>
{xMaxLabel}
</span>
</div>
{horizontalMargin && (
<Margin
{...horizontalMargin}
verticalSeparations={separations}
orientation={MarginOrientation.Horizontal}
/>
)}
</div>
);
}
+1 -1
View File
@@ -1,3 +1,3 @@
export * from './components/Line.js';
export * from './components/Margin.js';
export * from './components/Root.js';
export * from './components/VerticalMargin.js';
+27 -33
View File
@@ -61,24 +61,22 @@ export default async function evolution<Type extends StatType>(
});
}
const careerWinrate = histories.map(
const plot = histories.map(
(history) =>
[
history.last_battle_time,
history.all.battles,
(history.all.wins / history.all.battles) * 100,
] as Graph.PlotItem,
);
const careerBattles = histories.map(
(history) =>
[history.last_battle_time, history.all.battles] as Graph.PlotItem,
);
const winrateYs = careerWinrate.map(([, y]) => y);
const maxWinrate = Math.max(...winrateYs);
const minWinrate = Math.min(...winrateYs);
const battleYs = careerBattles.map(([, y]) => y);
const maxBattle = Math.max(...battleYs);
const minBattle = Math.min(...battleYs);
const minTime = Math.min(...careerBattles.map(([x]) => x));
const times = histories.map((history) => history.last_battle_time);
const minTime = Math.min(...times);
const maxTime = Math.max(...times);
const ys = plot.map(([, y]) => y);
const xs = plot.map(([x]) => x);
const maxY = Math.max(...ys);
const minY = Math.min(...ys);
const maxX = Math.max(...xs);
const minX = Math.min(...xs);
const accountInfo = await getWargamingResponse<AccountInfo>(
`https://api.wotblitz.${server}/wotb/account/info/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${id}`,
@@ -96,37 +94,33 @@ export default async function evolution<Type extends StatType>(
/>
{/* goofy ahh bug forces me to call them as functions */}
{careerWinrate.length > 0 && (
{plot.length > 0 && (
<Graph.Root
xMinLabel={new Date(minTime * 1000).toDateString()}
xMaxLabel={new Date(end * 1000).toDateString()}
leftVerticalMargin={{
min: minWinrate,
max: maxWinrate,
verticalMargin={{
min: minY,
max: maxY,
suffix: '%',
precision: 1,
}}
rightVerticalMargin={{
min: minBattle,
max: maxBattle,
horizontalMargin={{
min: minX,
max: maxX,
precision: 0,
}}
xMinLabel={new Date(minTime * 1000).toDateString()}
xMaxLabel={new Date(maxTime * 1000).toDateString()}
>
{Graph.Line({
// total battles
plot: careerBattles!,
color: Graph.LineColor.Blue,
})}
{Graph.Line({
// career winrate
plot: careerWinrate!,
minY: minWinrate,
maxY: maxWinrate,
color: Graph.LineColor.Red,
plot: plot,
minY,
maxY,
})}
</Graph.Root>
)}
{careerWinrate.length === 0 && (
<NoData type={NoDataType.BattlesInPeriod} />
)}
{plot.length === 0 && <NoData type={NoDataType.BattlesInPeriod} />}
<PoweredBy type={PoweredByType.BlitzStars} />
</Wrapper>
+1 -1
View File
@@ -6,7 +6,7 @@ import { RouteRegistry } from '../server.js';
export default {
route: '/stats/:type/:period',
inProduction: true,
inDevelopment: true,
inDevelopment: false,
async handler(req) {
const type = req.params.type as StatType;