Compare commits
No commits in common. "main" and "release-0.8" have entirely different histories.
main
...
release-0.
|
@ -2,43 +2,59 @@ import React from "react";
|
|||
import { useQuery } from "react-query";
|
||||
import axios from "axios";
|
||||
|
||||
import { SimpleGrid, Stat, StatLabel, StatNumber } from "@chakra-ui/react";
|
||||
import {
|
||||
AspectRatio,
|
||||
Box,
|
||||
Flex,
|
||||
Heading,
|
||||
HStack,
|
||||
Icon,
|
||||
SimpleGrid,
|
||||
Stat,
|
||||
StatLabel,
|
||||
StatNumber,
|
||||
StatHelpText,
|
||||
StatArrow,
|
||||
StatGroup,
|
||||
Tooltip,
|
||||
} from "@chakra-ui/react";
|
||||
import { FaUserCircle, FaArrowAltCircleRight } from "react-icons/fa";
|
||||
import { Link } from "react-router-dom";
|
||||
import { AutoSizer, WindowScroller, List } from "react-virtualized";
|
||||
import prettifyStatisticName from "./PrettifyStatisticName";
|
||||
import StackedBar from "./StackedBar";
|
||||
|
||||
const AggregatesShowcase = () => {
|
||||
const aggregates = useQuery(`aggregates`, async () => {
|
||||
const { data } = await axios.get(`/api/aggregates`);
|
||||
return data;
|
||||
});
|
||||
const aggregates = useQuery(
|
||||
`aggregates`,
|
||||
async () => {
|
||||
const { data } = await axios.get(`/api/aggregates`);
|
||||
return data;
|
||||
},
|
||||
{
|
||||
placeholderData: [],
|
||||
}
|
||||
);
|
||||
|
||||
const killedAggregates = aggregates.isSuccess
|
||||
? aggregates.data
|
||||
.filter((x) => x.type === "minecraft:killed")
|
||||
.sort((a, b) => b.value - a.value)
|
||||
: [];
|
||||
// const killedTotal = killedAggregates.reduce((acc, val) => acc + val.value, 0);
|
||||
const killedAggregates = aggregates.data
|
||||
.filter((x) => x.type === "minecraft:killed")
|
||||
.sort((a, b) => b.value - a.value);
|
||||
const killedTotal = killedAggregates.reduce((acc, val) => acc + val.value, 0);
|
||||
|
||||
const killedByAggregates = aggregates.isSuccess
|
||||
? aggregates.data
|
||||
.filter((x) => x.type === "minecraft:killed_by")
|
||||
.sort((a, b) => b.value - a.value)
|
||||
: [];
|
||||
// const killedByTotal = killedByAggregates.reduce(
|
||||
// (acc, val) => acc + val.value,
|
||||
// 0
|
||||
// );
|
||||
const killedByAggregates = aggregates.data
|
||||
.filter((x) => x.type === "minecraft:killed_by")
|
||||
.sort((a, b) => b.value - a.value);
|
||||
const killedByTotal = killedByAggregates.reduce(
|
||||
(acc, val) => acc + val.value,
|
||||
0
|
||||
);
|
||||
|
||||
const travelAggregates = aggregates.isSuccess
|
||||
? aggregates.data
|
||||
.filter(
|
||||
(x) => x.type === "minecraft:custom" && x.name.endsWith("one_cm")
|
||||
)
|
||||
.sort((a, b) => b.value - a.value)
|
||||
: [];
|
||||
// const travelTotal = travelAggregates.reduce((acc, val) => acc + val.value, 0);
|
||||
const travelAggregates = aggregates.data
|
||||
.filter((x) => x.type === "minecraft:custom" && x.name.endsWith("one_cm"))
|
||||
.sort((a, b) => b.value - a.value);
|
||||
const travelTotal = travelAggregates.reduce((acc, val) => acc + val.value, 0);
|
||||
|
||||
return aggregates.isSuccess ? (
|
||||
return aggregates.isFetched ? (
|
||||
<>
|
||||
<StackedBar heading="Mobs Killed" aggregates={killedAggregates} />
|
||||
|
||||
|
@ -57,13 +73,13 @@ const AggregatesShowcase = () => {
|
|||
.map((x, i) => {
|
||||
var value = x.value;
|
||||
if (x.name === "minecraft:play_one_minute") {
|
||||
value = Math.floor(x.value / 20 / 60);
|
||||
value = x.value / 20 / 60;
|
||||
}
|
||||
|
||||
return (
|
||||
<Stat key={i}>
|
||||
<StatLabel>{prettifyStatisticName(x.type, x.name)}</StatLabel>
|
||||
<StatNumber>{`${value
|
||||
<StatNumber>{`${x.value
|
||||
.toString()
|
||||
.replace(/\B(?=(\d{3})+(?!\d))/g, ",")}`}</StatNumber>
|
||||
</Stat>
|
||||
|
|
|
@ -41,17 +41,14 @@ const App = () => {
|
|||
<Statistic
|
||||
type={routeProps.match.params.type}
|
||||
name={routeProps.match.params.name}
|
||||
players={players.data}
|
||||
players={players}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<Route
|
||||
path="/player/:id"
|
||||
render={(routeProps) => (
|
||||
<Player
|
||||
playerId={routeProps.match.params.id}
|
||||
players={players.data}
|
||||
/>
|
||||
<Player playerId={routeProps.match.params.id} players={players} />
|
||||
)}
|
||||
/>
|
||||
<Route>
|
||||
|
|
|
@ -16,13 +16,19 @@ import { Link } from "react-router-dom";
|
|||
import prettifyStatisticName from "./PrettifyStatisticName";
|
||||
|
||||
const Player = ({ playerId, players }) => {
|
||||
const playerStats = useQuery(`player ${playerId}`, async () => {
|
||||
const { data } = await axios.get(`/api/players/${playerId}`);
|
||||
data.sort((a, b) => a.rank - b.rank || b.value - a.value);
|
||||
return data.filter((x) => x.value > 0);
|
||||
});
|
||||
const playerStats = useQuery(
|
||||
`player ${playerId}`,
|
||||
async () => {
|
||||
const { data } = await axios.get(`/api/players/${playerId}`);
|
||||
data.sort((a, b) => a.rank - b.rank);
|
||||
return data.filter((x) => x.value > 0);
|
||||
},
|
||||
{
|
||||
placeholderData: [],
|
||||
}
|
||||
);
|
||||
|
||||
const playerName = players?.find((x) => x.id === playerId)?.name;
|
||||
const playerName = players.data.find((x) => x.id === playerId)?.name;
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -54,23 +60,19 @@ const Player = ({ playerId, players }) => {
|
|||
</Tr>
|
||||
</Thead>
|
||||
<Tbody>
|
||||
{playerStats.isSuccess ? (
|
||||
playerStats.data.map((x, i) => {
|
||||
return (
|
||||
<Tr key={i}>
|
||||
<Td>
|
||||
<Link to={`/statistic/${x.type}/${x.name}`}>
|
||||
{prettifyStatisticName(x.type, x.name)}
|
||||
</Link>
|
||||
</Td>
|
||||
<Td isNumeric>{x.rank}</Td>
|
||||
<Td isNumeric>{x.value}</Td>
|
||||
</Tr>
|
||||
);
|
||||
})
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
{playerStats.data.map((x, i) => {
|
||||
return (
|
||||
<Tr key={i}>
|
||||
<Td>
|
||||
<Link to={`/statistic/${x.type}/${x.name}`}>
|
||||
{prettifyStatisticName(x.type, x.name)}
|
||||
</Link>
|
||||
</Td>
|
||||
<Td isNumeric>{x.rank}</Td>
|
||||
<Td isNumeric>{x.value}</Td>
|
||||
</Tr>
|
||||
);
|
||||
})}
|
||||
</Tbody>
|
||||
</Table>
|
||||
</>
|
||||
|
|
|
@ -1,6 +1,21 @@
|
|||
import React, { useMemo } from "react";
|
||||
import useHover from "./useHover";
|
||||
import { Box, Heading, HStack, Tooltip } from "@chakra-ui/react";
|
||||
import {
|
||||
AspectRatio,
|
||||
Box,
|
||||
Button,
|
||||
Heading,
|
||||
HStack,
|
||||
Icon,
|
||||
Input,
|
||||
Stat,
|
||||
StatLabel,
|
||||
StatNumber,
|
||||
StatHelpText,
|
||||
StatArrow,
|
||||
StatGroup,
|
||||
Tooltip,
|
||||
} from "@chakra-ui/react";
|
||||
import prettifyStatisticName from "./PrettifyStatisticName";
|
||||
|
||||
const randomColor = () =>
|
||||
|
@ -26,7 +41,7 @@ const StackedBarSegment = ({ aggregate, total }) => {
|
|||
<Box
|
||||
width={aggregate.value / total}
|
||||
height="100%"
|
||||
filter={isHovered ? "clear" : "saturate(0.5)"}
|
||||
filter={isHovered ? "clear" : "saturate(0.15)"}
|
||||
backgroundColor={color}
|
||||
ref={hoverRef}
|
||||
></Box>
|
||||
|
|
|
@ -15,13 +15,19 @@ import { Link } from "react-router-dom";
|
|||
import prettifyStatisticName from "./PrettifyStatisticName";
|
||||
|
||||
const Statistic = ({ type, name, players }) => {
|
||||
const ranking = useQuery(`statistic ${type} ${name}`, async () => {
|
||||
const { data } = await axios.get(`/api/statistics/${type}/${name}`);
|
||||
return data.filter((x) => x.value > 0);
|
||||
});
|
||||
const ranking = useQuery(
|
||||
`statistic ${type} ${name}`,
|
||||
async () => {
|
||||
const { data } = await axios.get(`/api/statistics/${type}/${name}`);
|
||||
return data.filter((x) => x.value > 0);
|
||||
},
|
||||
{
|
||||
placeholderData: [],
|
||||
}
|
||||
);
|
||||
|
||||
const playerDict = useMemo(() => {
|
||||
return Object.assign({}, ...players.map((x) => ({ [x.id]: x.name })));
|
||||
return Object.assign({}, ...players.data.map((x) => ({ [x.id]: x.name })));
|
||||
}, [players]);
|
||||
|
||||
return (
|
||||
|
@ -46,23 +52,19 @@ const Statistic = ({ type, name, players }) => {
|
|||
</Tr>
|
||||
</Thead>
|
||||
<Tbody>
|
||||
{ranking.isSuccess ? (
|
||||
ranking.data.map((x, i) => {
|
||||
return (
|
||||
<Tr key={i}>
|
||||
<Td>
|
||||
<Link to={`/player/${x.playerId}`}>
|
||||
{playerDict[x.playerId]}
|
||||
</Link>
|
||||
</Td>
|
||||
<Td isNumeric>{x.rank}</Td>
|
||||
<Td isNumeric>{x.value}</Td>
|
||||
</Tr>
|
||||
);
|
||||
})
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
{ranking.data.map((x, i) => {
|
||||
return (
|
||||
<Tr key={i}>
|
||||
<Td>
|
||||
<Link to={`/player/${x.playerId}`}>
|
||||
{playerDict[x.playerId]}
|
||||
</Link>
|
||||
</Td>
|
||||
<Td isNumeric>{x.rank}</Td>
|
||||
<Td isNumeric>{x.value}</Td>
|
||||
</Tr>
|
||||
);
|
||||
})}
|
||||
</Tbody>
|
||||
</Table>
|
||||
</>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { useEffect, useRef, useState } from "react";
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
|
||||
function useHover() {
|
||||
const [value, setValue] = useState(false);
|
||||
|
@ -16,8 +16,8 @@ function useHover() {
|
|||
node.removeEventListener("mouseout", handleMouseOut);
|
||||
};
|
||||
}
|
||||
} //,
|
||||
//[ref.current] // Recall only if ref changes
|
||||
},
|
||||
[ref.current] // Recall only if ref changes
|
||||
);
|
||||
return [ref, value];
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue