Skip to content

Commit

Permalink
Add ELO filtering to the match (#505)
Browse files Browse the repository at this point in the history
  • Loading branch information
petrvecera committed Jun 22, 2024
1 parent dbe5f6d commit 4e6b5de
Show file tree
Hide file tree
Showing 8 changed files with 470 additions and 145 deletions.
3 changes: 2 additions & 1 deletion __tests__/src/apis/coh3stats-api.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
getPlayerRecentMatches,
getTwitchStreams,
getStatsData,
GET_ANALYSIS_STATS,
} from "../../../src/apis/coh3stats-api";

describe("coh3stats-api", () => {
Expand Down Expand Up @@ -305,7 +306,7 @@ describe("coh3stats-api", () => {

const response = await getStatsData(123, "now", "gameStats", "cache-key-4");
expect(global.fetch).toBeCalledWith(
"https://cache.coh3stats.com/getAnalysisStatsHttp?startDate=123&endDate=now&type=gameStats&v=v9&ock=cache-key-4",
`https://cache.coh3stats.com/getAnalysisStatsHttp?startDate=123&endDate=now&type=gameStats&v=${GET_ANALYSIS_STATS}&ock=cache-key-4`,
);

expect(response).toEqual(fakeStatsData);
Expand Down
12 changes: 6 additions & 6 deletions config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const getEdgioEnvName = (): string | null => {
};

// This controls the default patch selector in the stats page // this needs to be key statsPatchSelector object
const defaultStatsPatchSelector = "1.6.9";
const defaultStatsPatchSelector = "1.6.10";

// This controls the patch selector in the stats page
const statsPatchSelector: Record<
Expand All @@ -55,11 +55,11 @@ const statsPatchSelector: Record<
group: string;
}
> = {
"1.6.9": {
"1.6.10": {
from: "2024-05-02",
to: "now",
value: "1.6.9",
label: "1.6.5 - 1.6.9",
value: "1.6.10",
label: "1.6.5 - 1.6.10",
group: "Coral Viper",
},
"1.6.1": {
Expand Down Expand Up @@ -159,12 +159,12 @@ const statsPatchSelector: Record<
};

// Latest patch needs to be a key to patches object
const latestPatch = "1.6.9";
const latestPatch = "1.6.10";

// Get patchTimeSeconds here https://www.unixtimestamp.com/
const patches: Record<string, { dataTag: string; dataTime: string; patchTimeSeconds?: number }> =
{
"1.6.9": {
"1.6.10": {
dataTag: "v1.6.6-1", // This is the tag of the data repo
dataTime: "03/May/2024", // The date when was the data tag created (the data extracted from game)
},
Expand Down
44 changes: 23 additions & 21 deletions screens/stats/game/charts/playtime-histogram.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,29 @@ const PlayTimeHistogramChart: React.FC<IProps> = ({ data }) => {
const { colorScheme } = useMantineColorScheme();
const chartData: any[] | undefined = [];

for (const [key, value] of Object.entries(data.gameTimeSpread)) {
if (key === "0") {
chartData.push({
time: "0 - 5",
games: value,
});
} else if (key === "5") {
chartData.push({
time: "5 - 10",
games: value,
});
} else if (key === "60") {
chartData.push({
time: "60+",
games: value,
});
} else {
chartData.push({
time: `${key} - ${parseInt(key) + 10}`,
games: value,
});
if (data.gameTimeSpread) {
for (const [key, value] of Object.entries(data.gameTimeSpread)) {
if (key === "0") {
chartData.push({
time: "0 - 5",
games: value,
});
} else if (key === "5") {
chartData.push({
time: "5 - 10",
games: value,
});
} else if (key === "60") {
chartData.push({
time: "60+",
games: value,
});
} else {
chartData.push({
time: `${key} - ${parseInt(key) + 10}`,
games: value,
});
}
}
}

Expand Down
175 changes: 96 additions & 79 deletions screens/stats/game/inner-game-stats-page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import React, { useEffect, useState } from "react";
import { getStatsData } from "../../../src/apis/coh3stats-api";
import {
analysisFilterType,
analysisMapFilterType,
AnalysisObjectType,
getAnalysisStatsHttpResponse,
StatsDataObject,
Expand Down Expand Up @@ -75,11 +77,17 @@ const ChartCard = ({
);
};

function useDeepCompareMemo(timeStamps: { from: number | null; to: number | null }) {
const [storedValue, setStoredValue] = useState(timeStamps);
function useDeepCompareMemo(
timeStamps: {
from: number | null;
to: number | null;
},
filters: Array<analysisFilterType | analysisMapFilterType | "all">,
) {
const [storedValue, setStoredValue] = useState({ timeStamps, filters });

if (JSON.stringify(timeStamps) !== JSON.stringify(storedValue)) {
setStoredValue(timeStamps);
if (JSON.stringify({ timeStamps, filters }) !== JSON.stringify(storedValue)) {
setStoredValue({ timeStamps, filters });
}

return storedValue;
Expand All @@ -88,11 +96,13 @@ function useDeepCompareMemo(timeStamps: { from: number | null; to: number | null
const InnerGameStatsPage = ({
timeStamps,
mode,
filters,
}: {
timeStamps: { from: number | null; to: number | null };
mode: "1v1" | "2v2" | "3v3" | "4v4" | "all";
filters: Array<analysisFilterType | analysisMapFilterType | "all">;
}) => {
const memoizedTimeStamps = useDeepCompareMemo(timeStamps);
const memoizedTimeStampsAndFilters = useDeepCompareMemo(timeStamps, filters);
const [data, setData] = useState<null | getAnalysisStatsHttpResponse>(null);
const [error, setError] = useState<null | string>(null);
const [loading, setLoading] = useState<boolean>(false);
Expand All @@ -111,6 +121,7 @@ const InnerGameStatsPage = ({
timeStamps.to,
"gameStats",
buildOriginHeaderValue(),
filters,
);
setData(data);
} catch (e: any) {
Expand All @@ -121,7 +132,7 @@ const InnerGameStatsPage = ({
setLoading(false);
}
})();
}, [memoizedTimeStamps]);
}, [memoizedTimeStampsAndFilters]);

let content = <></>;

Expand Down Expand Up @@ -179,92 +190,98 @@ const InnerGameStatsPage = ({
/>
</Group>
</Flex>
{matchCount > 0 && (
<>
<Flex gap={"xl"} wrap="wrap" justify="center">
<ChartCard title={`Factions Played ${mode}`} size={"md"}>
<DynamicFactionsPlayedPieChart data={analysisData} />
</ChartCard>

<Flex gap={"xl"} wrap="wrap" justify="center">
<ChartCard title={`Factions Played ${mode}`} size={"md"}>
<DynamicFactionsPlayedPieChart data={analysisData} />
</ChartCard>

<ChartCard title={`Games Results ${mode}`} size={"md"}>
<DynamicGamesBarChart data={analysisData} />
</ChartCard>
<ChartCard title={`Games Results ${mode}`} size={"md"}>
<DynamicGamesBarChart data={analysisData} />
</ChartCard>

<ChartCard title={`Faction Winrate ${mode}`} size={"md"}>
<DynamicWinRateBarChart data={analysisData} />
</ChartCard>
<ChartCard title={`Faction Winrate ${mode}`} size={"md"}>
<DynamicWinRateBarChart data={analysisData} />
</ChartCard>

<ChartCard
title={
<Group position={"apart"}>
<Group spacing={"xs"}>
<Text>Maps {mode}</Text>
<HelperIcon
width={280}
text={"This chart has no value until we get map bans as we have in coh2."}
/>
</Group>
<Button
component={Link}
href={getMapsStatsRoute()}
variant={"default"}
size={"sm"}
>
<Group spacing={4}>
<IconCirclePlus size={"18"} />
More
<ChartCard
title={
<Group position={"apart"}>
<Group spacing={"xs"}>
<Text>Maps {mode}</Text>
<HelperIcon
width={280}
text={"This chart has no value until we get map bans as we have in coh2."}
/>
</Group>
<Button
component={Link}
href={getMapsStatsRoute()}
variant={"default"}
size={"sm"}
>
<Group spacing={4}>
<IconCirclePlus size={"18"} />
More
</Group>
</Button>
</Group>
</Button>
</Group>
}
size={"md"}
>
<DynamicMapsPlayedBarChart data={analysisData} />
</ChartCard>
</Flex>
}
size={"md"}
>
<DynamicMapsPlayedBarChart data={analysisData} />
</ChartCard>
</Flex>

<Space h="xl" />
<Flex gap={"xl"} wrap="wrap" justify="center">
<FactionVsFactionCard data={analysisData} title={`Team composition ${mode}`} />
<ChartCard title={`Game Time ${mode}`} size={"xl"}>
<DynamicPlayTimeHistogramChart data={analysisData} />
</ChartCard>
</Flex>
<Space h="xl" />
<Space h="xl" />
<Flex gap={"xl"} wrap="wrap" justify="center">
<FactionVsFactionCard data={analysisData} title={`Team composition ${mode}`} />
<ChartCard title={`Game Time ${mode}`} size={"xl"}>
<DynamicPlayTimeHistogramChart data={analysisData} />
</ChartCard>
</Flex>
<Space h="xl" />

<Flex gap={"xl"} wrap="wrap" justify="center">
<DynamicWinRateLineChart data={analysis.days} mode={mode} />
</Flex>
<Flex gap={"xl"} wrap="wrap" justify="center">
<DynamicWinRateLineChart data={analysis.days} mode={mode} />
</Flex>

<Space h="xl" />
<Flex gap={"xl"} wrap="wrap" justify="center">
<DynamicGamesLineChart
data={analysis.days}
mode={mode}
helperText={"However over the chart to see the amount of games for each faction."}
stacked={false}
/>
</Flex>
<Space h="xl" />
<Flex gap={"xl"} wrap="wrap" justify="center">
<DynamicGamesLineChart
data={analysis.days}
mode={mode}
helperText={
"This is stacked area chart. It's summary for all factions. However over the chart to see the amount of games for each faction."
}
stacked={true}
/>
</Flex>
<Space h="xl" />
<Flex gap={"xl"} wrap="wrap" justify="center">
<DynamicGamesPercentageLineChartCard data={analysis.days} mode={mode} />
</Flex>
<Space h="xl" />
<Flex gap={"xl"} wrap="wrap" justify="center">
<DynamicGamesLineChart
data={analysis.days}
mode={mode}
helperText={"However over the chart to see the amount of games for each faction."}
stacked={false}
/>
</Flex>
<Space h="xl" />
<Flex gap={"xl"} wrap="wrap" justify="center">
<DynamicGamesLineChart
data={analysis.days}
mode={mode}
helperText={
"This is stacked area chart. It's summary for all factions. However over the chart to see the amount of games for each faction."
}
stacked={true}
/>
</Flex>
<Space h="xl" />
<Flex gap={"xl"} wrap="wrap" justify="center">
<DynamicGamesPercentageLineChartCard data={analysis.days} mode={mode} />
</Flex>
</>
)}

<Text fz="xs" align={"center"} pt={20} c="dimmed">
Analysis type {data.type} from{" "}
{dayjs.unix(data.fromTimeStampSeconds).format("YYYY-MM-DD")} to{" "}
{dayjs.unix(data.toTimeStampSeconds).format("YYYY-MM-DD")}
</Text>
<Text fz="xs" align={"center"} c="dimmed">
Applied ELO filters {data.filters ? data.filters?.join(", ") : "none"}
</Text>
</>
);
} else if (!loading && !error) {
Expand Down
Loading

0 comments on commit 4e6b5de

Please sign in to comment.