Skip to content

Commit

Permalink
Add Map Stats (#241)
Browse files Browse the repository at this point in the history
* Add map stats WIP

* WIP map stats

* Finish map stats

* Fix typos
  • Loading branch information
petrvecera authored Aug 28, 2023
1 parent c1127b6 commit 7effd0e
Show file tree
Hide file tree
Showing 31 changed files with 1,624 additions and 415 deletions.
54 changes: 29 additions & 25 deletions components/Header/components/StatisticsMenu.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,14 @@
import {
Accordion,
ActionIcon,
Anchor,
Group,
HoverCard,
Stack,
Text,
Tooltip,
} from "@mantine/core";
import { Accordion, Anchor, Group, HoverCard, Stack, Text } from "@mantine/core";
import Link from "next/link";
import {
getGameStatsRoute,
getLeaderBoardStatsRoute,
getMapsStatsRoute,
getPlayersStatsRoute,
} from "../../../src/routes";
import React from "react";
import {
IconBarrierBlock,
IconChartArea,
IconChartAreaLine,
IconChevronDown,
IconDeviceDesktopAnalytics,
Expand Down Expand Up @@ -47,6 +39,12 @@ const StatisticsMenu = ({
Games Stats
</Anchor>
</Group>
<Group spacing={"xs"}>
<IconChartArea size={16} />
<Anchor component={Link} href={getMapsStatsRoute()} onClick={close}>
Maps Stats
</Anchor>
</Group>
<Group spacing={"xs"}>
<IconUsersGroup size={16} />
<Anchor component={Link} href={getPlayersStatsRoute()} onClick={close}>
Expand Down Expand Up @@ -85,6 +83,12 @@ const StatisticsMenu = ({
Games Stats
</Anchor>
</Group>
<Group spacing={"xs"}>
<IconChartArea size={16} />
<Anchor component={Link} href={getMapsStatsRoute()}>
Maps Stats
</Anchor>
</Group>
<Group spacing={"xs"}>
<IconUsersGroup size={16} />
<Anchor component={Link} href={getPlayersStatsRoute()}>
Expand All @@ -97,20 +101,20 @@ const StatisticsMenu = ({
Leaderboards Stats
</Anchor>
</Group>
<Tooltip label="Coming Later" color="orange" withArrow position={"bottom"}>
<Anchor
className={cx(classes.disabledLink)}
component={Link}
href={getLeaderBoardStatsRoute()}
>
<Group spacing={"xs"}>
<ActionIcon color="orange" size="sm" radius="xl" variant="transparent">
<IconBarrierBlock size={16} />
</ActionIcon>
<span> Map Statistics</span>
</Group>
</Anchor>
</Tooltip>
{/*<Tooltip label="Coming Later" color="orange" withArrow position={"bottom"}>*/}
{/* <Anchor*/}
{/* className={cx(classes.disabledLink)}*/}
{/* component={Link}*/}
{/* href={getLeaderBoardStatsRoute()}*/}
{/* >*/}
{/* <Group spacing={"xs"}>*/}
{/* <ActionIcon color="orange" size="sm" radius="xl" variant="transparent">*/}
{/* <IconBarrierBlock size={16} />*/}
{/* </ActionIcon>*/}
{/* <span> Map Statistics</span>*/}
{/* </Group>*/}
{/* </Anchor>*/}
{/*</Tooltip>*/}
</Group>
</HoverCard.Dropdown>
</HoverCard>
Expand Down
7 changes: 4 additions & 3 deletions components/charts/card-factions-heatmap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ interface IProps {
data: AnalysisObjectType;
style: Record<string, any>;
title: string;
width?: number;
}

const extractFactionString = (factionString: string): Record<string, string> => {
Expand Down Expand Up @@ -62,8 +63,8 @@ const legend = (
</div>
);

const _FactionVsFactionCard: React.FC<IProps> = ({ title, data, style }) => {
const factionData = data["factionMatrix"];
const _FactionVsFactionCard: React.FC<IProps> = ({ title, data, style, width = 780 }) => {
const factionData = (data && data["factionMatrix"]) || {};
const largeScreen = useMediaQuery("(min-width: 30em)");

// Change all A (american) to U (US Forces)
Expand Down Expand Up @@ -206,7 +207,7 @@ const _FactionVsFactionCard: React.FC<IProps> = ({ title, data, style }) => {
</Card>
)}
{largeScreen && (
<Card p="md" shadow="sm" w={780} withBorder>
<Card p="md" shadow="sm" w={width} withBorder>
{/* top, right, left margins are negative – -1 * theme.spacing.xl */}

<Card.Section withBorder inheritPadding py="xs">
Expand Down
57 changes: 57 additions & 0 deletions components/charts/chart-utils.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { raceType } from "../../src/coh3/coh3-types";

export const getNivoTooltipTheme = (colorScheme: "dark" | "light") => {
if (colorScheme === "dark") {
return {
Expand Down Expand Up @@ -107,3 +109,58 @@ export const getNivoTooltipTheme = (colorScheme: "dark" | "light") => {
return {};
}
};

export const minMaxRange = (mapsData: { value: string | number }[]) => {
let maxValue = -Infinity;
let minValue = Infinity;

// Find the maximum and minimum values from the input data
for (const { value } of mapsData) {
const numericValue = parseFloat(`${value}`);
if (!isNaN(numericValue)) {
maxValue = Math.max(maxValue, numericValue);
minValue = Math.min(minValue, numericValue);
}
}

const rangeIncrement = 5;
const rangeMin = Math.floor(minValue / rangeIncrement) * rangeIncrement;
const rangeMax = Math.ceil(maxValue / rangeIncrement) * rangeIncrement;

// Determine the absolute value that is greater
const absMaxValue = Math.abs(rangeMin);
const absMinValue = Math.abs(rangeMax);
const rangeValue = absMaxValue > absMinValue ? absMaxValue : absMinValue;

// Return the range with the determined value
return { min: -rangeValue, max: rangeValue };
};

export const chartDataObjectsForTimeSeries: {
[key in raceType]: {
id: raceType;
color: string;
data: Array<any>;
};
} = {
german: {
id: "german",
color: "#D62728",
data: [],
},
dak: {
id: "dak",
color: "#f1e05b",
data: [],
},
american: {
id: "american",
color: "#2DA02C",
data: [],
},
british: {
id: "british",
color: "#1E77B4",
data: [],
},
};
160 changes: 160 additions & 0 deletions components/charts/inner-wr-line-chart.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
import React, { useState } from "react";
import { ResponsiveLine } from "@nivo/line";
import { Card, Group, Select, Title, useMantineColorScheme, Text } from "@mantine/core";

import { raceType } from "../../src/coh3/coh3-types";
import { generateWeeklyAverages } from "../../src/charts/utils";
import HelperIcon from "../icon/helper";
import { getNivoTooltipTheme } from "./chart-utils";

const InnerWinRateLineChartCard = ({
data,
title,
width = 1270,
}: {
data: {
[key in raceType]: {
id: raceType;
color: string;
data: Array<any>;
};
};
title: string;
width?: number;
}) => {
const { colorScheme } = useMantineColorScheme();
const [displayBy, setDisplayBy] = useState<"days" | "weeks">("days");

const chartData = Object.values(data).map((factionObject) => {
return {
id: factionObject.id,
color: factionObject.color,
data:
displayBy === "days"
? factionObject.data
: generateWeeklyAverages(factionObject.data, false),
// "data": factionObject.data
};
});

return (
<Card p="md" shadow="sm" w={width} withBorder>
<Card.Section withBorder inheritPadding py="xs">
<Group position={"apart"}>
<Group>
<Title order={3}>{title}</Title>
<HelperIcon
width={360}
text={
"Winrate for each day can fluctuate a lot because there isn't enough games. Switch to weeks to see a more accurate representation."
}
/>
</Group>
<Group>
<Text fw={500}>Display as</Text>
<Select
style={{ width: 120, marginRight: 30 }}
// label="Display as"
value={displayBy}
onChange={(value) => setDisplayBy(value as "days" | "weeks")}
data={[
{ value: "days", label: "Days" },
{ value: "weeks", label: "Weeks" },
]}
/>
</Group>
</Group>
</Card.Section>
<Card.Section h={350} p="xs">
<ResponsiveLine
data={chartData}
margin={{ top: 25, right: 50, bottom: 70, left: 50 }}
xFormat="time: %a - %Y-%m-%d"
// tooltip={(data) => {
// return <>{data.point.data.xFormatted} and {data.point.data.yFormatted}</>
// }}
xScale={{
format: "%Y-%m-%d",
precision: "day",
type: "time",
useUTC: false,
}}
yScale={{
type: "linear",
min: 0.3,
max: 0.7,
}}
yFormat=" >-.2f"
axisTop={null}
axisRight={{
tickSize: 5,
tickPadding: 5,
tickRotation: 0,
legend: "Win Rate",
legendOffset: 45,
legendPosition: "middle",
}}
axisBottom={{
format: "%a - %b %d",
// legend: 'time scale',
legendOffset: 36,
legendPosition: "middle",
// tickValues: chartConfig?.tickValues,
// legend: chartConfig?.bottomAxisLegend,
}}
axisLeft={{
tickSize: 5,
tickPadding: 5,
tickRotation: 0,
legend: "Win Rate",
legendOffset: -45,
legendPosition: "middle",
}}
curve="monotoneX"
colors={{ datum: "color" }}
//colors={{ scheme: "category10" }}
enablePoints={true}
pointSize={8}
// pointColor={{ theme: "background" }}
// pointBorderWidth={2}
pointBorderColor={{ from: "serieColor" }}
pointLabelYOffset={-12}
useMesh={true}
enableGridX={true}
enableCrosshair={true}
// Helps site performance
animate={false}
theme={getNivoTooltipTheme(colorScheme)}
legends={[
{
anchor: "bottom",
direction: "row",
justify: false,
translateX: -1,
translateY: 65,
itemsSpacing: 0,
itemDirection: "left-to-right",
itemWidth: 80,
itemHeight: 20,
itemOpacity: 0.75,
symbolSize: 12,
symbolShape: "circle",
symbolBorderColor: "rgba(0, 0, 0, .5)",
effects: [
{
on: "hover",
style: {
itemBackground: "rgba(0, 0, 0, .03)",
itemOpacity: 1,
},
},
],
},
]}
/>
</Card.Section>
</Card>
);
};

export default InnerWinRateLineChartCard;
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ const GamesLineChartCard = ({
tickSize: 5,
tickPadding: 5,
tickRotation: 0,
legend: "Amount of games",
legend: "Factions played",
legendOffset: 45,
legendPosition: "middle",
}}
Expand All @@ -138,7 +138,7 @@ const GamesLineChartCard = ({
tickSize: 5,
tickPadding: 5,
tickRotation: 0,
legend: "Amount of games",
legend: "Factions played",
legendOffset: -45,
legendPosition: "middle",
}}
Expand Down
6 changes: 3 additions & 3 deletions components/screens/stats/game/charts/maps-played-bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const MapsPlayedBarChart: React.FC<IProps> = ({ data }) => {

return (
<ResponsiveBar
margin={{ top: 10, right: 30, bottom: 40, left: 140 }}
margin={{ top: 10, right: 30, bottom: 50, left: 140 }}
// @ts-ignore
data={sortedMapData as data[] | undefined}
layout={"horizontal"}
Expand All @@ -50,9 +50,9 @@ const MapsPlayedBarChart: React.FC<IProps> = ({ data }) => {
tickSize: 5,
tickPadding: 5,
legend: "Number of games",
tickRotation: 0,
tickRotation: -45,
legendPosition: "middle",
legendOffset: 32,
legendOffset: 38,
}}
axisLeft={{
tickSize: 5,
Expand Down
Loading

0 comments on commit 7effd0e

Please sign in to comment.