Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixing Dragon heatmap and adding dynamic version #40

Merged
merged 3 commits into from
Jul 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,14 @@ Once the prerequisites are installed locally, follow these steps:

1. To enter the container to run development commands, run `./anvilw bash`. Once inside the container, you can start the development server via `task serve`.

#### Running locally against a cloud backend

> NOTE: This assumes you have access to the AWS account with the StatsCollide database

1. Make sure you pull the AWS Amplify environment you want (either `main` or `develop`) via the command: `amplify pull --envName develop`. When asked `Do you plan on modifying this backend?`, select **Yes**. (NOTE: This will update a bunch of files locally. Do not commit these changes in git unless you know what you are doing)

1. Run `task npm-start REACT_APP_LOCAL_BACKEND=false`. Instead of deploying the front-end app locally with a local mock DB, this will deploy your front-end app locally but connect it to the Graphql endpoint in AWS for your given environment. **Make sure this is for read-only operations, as to not overwrite data in the production database**

### Available development commands

In addition to regular `npm` commands, a handful of macros have been set up for common development commands. These commands can be run via `task <command>` when in the container via `./anvilw bash`. The following macros have been configured:
Expand Down
2 changes: 2 additions & 0 deletions Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ tasks:
desc: Starts npm dev server
cmds:
- REACT_APP_LOCAL_BACKEND={{.REACT_APP_LOCAL_BACKEND}} npm start
vars:
REACT_APP_LOCAL_BACKEND: '{{ coalesce .REACT_APP_LOCAL_BACKEND "true"}}'

mock-api:
desc: Starts a local mock api server
Expand Down
2 changes: 1 addition & 1 deletion amplify/team-provider-info.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
"function": {
"submitRun": {
"deploymentBucketName": "amplify-ff6wcstats-main-215331-deployment",
"s3Key": "amplify-builds/submitRun-76324d6738566e5a7448-build.zip"
"s3Key": "amplify-builds/submitRun-56617a4a54746c624d4e-build.zip"
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import CONFIG from "./config";
// Amplify auto-generates aws-exports but sets it to the host IP and not localhost if you use mock
// This breaks in docker because docker networking is crazy.
// This logic allows us to toggle it
if (process.env.REACT_APP_LOCAL_BACKEND) {
if (process.env.REACT_APP_LOCAL_BACKEND === true) {
var localAwsExports = {
...awsExports,
aws_appsync_graphqlEndpoint: "http://localhost:20002/graphql",
Expand Down Expand Up @@ -156,6 +156,7 @@ function App() {
<Footer
discordUserdata={discordUserdata}
setUserdataState={setUserdataState}
config={CONFIG}
/>
</Router>
</div>
Expand Down
52 changes: 43 additions & 9 deletions src/components/Footer.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from "react";
import React, { useState, useEffect } from "react";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faLink } from "@fortawesome/free-solid-svg-icons";
import {
Expand All @@ -10,6 +10,30 @@ import Menu from "./Navigation/Menu";
import "./scss/main.scss";

function Footer(props) {
const [latestTag, setLatestTag] = useState("");

useEffect(() => {
const fetchLatestTag = async () => {
// Fetches the lastest tagged release from the Github repo
try {
const response = await fetch(
`https://api.github.com/repos/${props.config.footer.github.owner}/${props.config.footer.github.repo}/tags`,
);
const data = await response.json();
if (Array.isArray(data) && data.length > 0) {
setLatestTag(data[0].name);
} else {
setLatestTag("No tags found");
}
} catch (error) {
console.error("Error fetching latest tag:", error);
setLatestTag("Error fetching latest tag");
}
};

fetchLatestTag();
}, [props.config]);

return (
<footer className="site-footer">
<div className="wrapper">
Expand All @@ -32,38 +56,44 @@ function Footer(props) {
<ul className="social-media-list">
<li>
<a
href="https://ff6worldscollide.com/"
title="FFVI Worlds Collide"
href={props.config.footer.ff6wc.url}
title={props.config.footer.ff6wc.title}
>
<FontAwesomeIcon icon={faLink} fixedWidth />
<span className="username">&nbsp;FF6WC Home</span>
</a>
</li>
<li>
<a href="https://discord.gg/5MPeng5" title="FF6WC Discord">
<a
href={props.config.footer.discord.url}
title={props.config.footer.discord.title}
>
<FontAwesomeIcon icon={faDiscord} fixedWidth />
<span className="username">&nbsp;Discord</span>
</a>
</li>
<li>
<a href="https://twitter.com/FF6_WC" title="Twitter">
<a
href={props.config.footer.twitter.url}
title={props.config.footer.twitter.title}
>
<FontAwesomeIcon icon={faTwitter} fixedWidth />
<span className="username">&nbsp;Twitter</span>
</a>
</li>
<li>
<a
href="https://github.com/bstascavage/ff6wc-stats"
title="Github"
href={props.config.footer.github.url}
title={props.config.footer.github.title}
>
<FontAwesomeIcon icon={faGithub} fixedWidth />
<span className="username">&nbsp;Github</span>
</a>
</li>
<li>
<a
href="https://github.com/peroquenariz/StatsCompanion"
title="StatsCompanion"
href={props.config.footer.statscompanion.url}
title={props.config.footer.statscompanion.title}
>
<FontAwesomeIcon icon={faLink} fixedWidth />
<span className="username">&nbsp;StatsCompanion</span>
Expand All @@ -76,6 +106,10 @@ function Footer(props) {
<strong>Site Description</strong>
</p>
<p className="text">A collection of Worlds Collide stats.</p>
<p className="text">
<b>Version: </b>
{latestTag}
</p>
</div>
</div>
</footer>
Expand Down
12 changes: 11 additions & 1 deletion src/components/Stats/Data.js
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ export class Data {
* `numOfDragons (an INT for the number of dragons fought in a run),
* and `numOfRuns` (an INT for the number of runs with this combination of `dragonName` and `numOfDragons`)
*/
let data = { dragons: [] };
let data = { dragons: [], interval: 0 };

// Populate the initial list of 64 combinations
for (
Expand Down Expand Up @@ -372,8 +372,18 @@ export class Data {

let numOfDragons = this.runData[run].dragons.length;
data.dragons[dragonIndex * 8 + (numOfDragons - 1)].numOfRuns++;

// Setting the heatmap interval to the highest runs per dragon
if (
data.dragons[dragonIndex * 8 + (numOfDragons - 1)].numOfRuns >
data.interval
) {
data.interval =
data.dragons[dragonIndex * 8 + (numOfDragons - 1)].numOfRuns;
}
}
}

return data;
}

Expand Down
2 changes: 0 additions & 2 deletions src/components/Stats/Stats.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -634,8 +634,6 @@ function Stats(props) {
xHeight={75}
data={data.dragonHeatMap()}
yAxisMap={data.getFriendlyDragonList()}
threshold={data.runData.length}
numOfIntervals={8}
/>
</Col>
</Row>
Expand Down
17 changes: 8 additions & 9 deletions src/components/Stats/StatsHeatMap.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,19 @@ import {
ResponsiveContainer,
} from "recharts";

const getHeatGroups = (dataset, threshold, numOfIntervals) => {
const getHeatGroups = (dataset, numOfIntervals) => {
let breakpoints = [];

// Dynamically set the number of breakpoints based on the `numOfIntervals`
// `threshold` is the threshold for the max color, ie. total runs
for (let i = 0; i <= numOfIntervals; i++) {
const colorInterval = 185 / numOfIntervals;
i === 0
? breakpoints.push({ temp: 0, color: "none" })
: breakpoints.push({
temp: threshold * (i / numOfIntervals),
color: `rgb(${194 / i}, ${219 / i}, 255)`,
temp: i,
color: `rgb(${192 - colorInterval * i}, ${
219 - colorInterval * i
}, 255)`,
});
}

Expand Down Expand Up @@ -128,6 +130,7 @@ function HeatMap(props) {
? ""
: props.yAxisMap[dragonName];
};

return (
<div id="heat-map" style={{ height: "100%" }}>
<Card className={`${background} shadow`} style={{ height: "100%" }}>
Expand Down Expand Up @@ -182,11 +185,7 @@ function HeatMap(props) {
/>

<Tooltip content={<CustomTooltip />} />
{getHeatGroups(
dataset,
props.threshold,
props.numOfIntervals,
).map((group) => (
{getHeatGroups(dataset, props.data.interval).map((group) => (
<Scatter
key={group.label}
name={group.label}
Expand Down
24 changes: 24 additions & 0 deletions src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,30 @@ const CONFIG = {
],
demoPath: "/stats#user=158730578454118401",
},
footer: {
github: {
owner: "bstascavage",
repo: "ff6wc-stats",
url: "https://github.com/bstascavage/ff6wc-stats",
title: "Github",
},
ff6wc: {
url: "https://ff6worldscollide.com/",
title: "FFVI Worlds Collide",
},
discord: {
url: "https://discord.gg/5MPeng5",
title: "FF6WC Discord",
},
twitter: {
url: "https://twitter.com/FF6_WC",
title: "Twitter",
},
statscompanion: {
url: "https://github.com/peroquenariz/StatsCompanion",
title: "StatsCompanion",
},
},
submit: {
runTime: {
type: "textInput",
Expand Down