Compare commits
19 Commits
feature/ca
...
main
Author | SHA1 | Date | |
---|---|---|---|
24d424bd90 | |||
1345b984d4 | |||
14b80dfea6 | |||
24928c10fa | |||
df7e5c0e97 | |||
d25334d35f | |||
8c8499fb1c | |||
0180e8a3b5 | |||
fa058cc64e | |||
ef95388185 | |||
ad069cb7bf | |||
367b767f52 | |||
c9e14e265f | |||
5abf6fe132 | |||
487bb86a29 | |||
a51d3f8d7b | |||
27eb2ccb45 | |||
94e08c3657 | |||
fa60c3ea53 |
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
These are the public assets for the [wowtoken.app](https://wowtoken.app) website, served off Amazon S3 behind CloudFront.
|
These are the public assets for the [wowtoken.app](https://wowtoken.app) website, served off Amazon S3 behind CloudFront.
|
||||||
|
|
||||||
This project gets picked up by CodePipeline, built via CodeBuild, and deployed.
|
This project gets picked up by CodePipeline, built via CodeBuild, and to S3.
|
||||||
|
|
||||||

|
Backend lambdas can be found at my private git repository [wowtoken.app-backend](https://git.emily.sh/wowtoken-app/wowtoken.app-backend)
|
||||||
|
|
||||||
|

|
||||||
|
812
package-lock.json
generated
812
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -15,9 +15,9 @@
|
|||||||
"webpack-cli": "^4.7.2"
|
"webpack-cli": "^4.7.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chart.js": "^4.4.0",
|
"chart.js": "^4.4.5",
|
||||||
"chartjs-adapter-dayjs-3": "^1.2.3",
|
"chartjs-adapter-dayjs-4": "^1.0.4",
|
||||||
"css-minimizer-webpack-plugin": "^5.0.0",
|
"css-minimizer-webpack-plugin": "^7.0.0",
|
||||||
"dayjs": "^1.11.7"
|
"dayjs": "^1.11.13"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
22
src/datum.js
Normal file
22
src/datum.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
export default class Datum {
|
||||||
|
constructor(time, price) {
|
||||||
|
this._time = time;
|
||||||
|
this._price = price;
|
||||||
|
}
|
||||||
|
|
||||||
|
getTime() {
|
||||||
|
return this._time;
|
||||||
|
}
|
||||||
|
|
||||||
|
getPrice() {
|
||||||
|
return this._price;
|
||||||
|
}
|
||||||
|
|
||||||
|
getX() {
|
||||||
|
return this.getTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
getY() {
|
||||||
|
return this.getPrice();
|
||||||
|
}
|
||||||
|
}
|
4
src/fetchCurrent.js
Normal file
4
src/fetchCurrent.js
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
export default async function fetchCurrent() {
|
||||||
|
const resp = await fetch("https://data.wowtoken.app/v2/current/retail.json");
|
||||||
|
return await resp.json();
|
||||||
|
}
|
13
src/fetchData.js
Normal file
13
src/fetchData.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import Datum from "./datum";
|
||||||
|
import urlBuilder from "./urlBuilder";
|
||||||
|
|
||||||
|
export default async function fetchData(currentRegionSelection, currentTimeSelection, currentAggregateSelection) {
|
||||||
|
const data = [];
|
||||||
|
const resp = await fetch(urlBuilder(currentRegionSelection, currentTimeSelection, currentAggregateSelection));
|
||||||
|
const respData = await resp.json();
|
||||||
|
for (let i = 0, l = respData.length; i < l; i++) {
|
||||||
|
const datum = new Datum(new Date(respData[i][0]), respData[i][1]);
|
||||||
|
data.push(datum);
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
18
src/highTime.js
Normal file
18
src/highTime.js
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import Datum from "./datum";
|
||||||
|
|
||||||
|
|
||||||
|
function updateHighTime() {
|
||||||
|
const highTime= document.getElementById("high-time");
|
||||||
|
|
||||||
|
const currentTime = document.getElementById("time").selectedOptions[0].innerText;
|
||||||
|
if (currentTime.toLowerCase() !== highTime.innerText) {
|
||||||
|
highTime.innerText = currentTime.toLowerCase();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateHighVal(datum) {
|
||||||
|
const highVal = document.getElementById("high-val");
|
||||||
|
highVal.innerHTML = datum.getPrice().toLocaleString();
|
||||||
|
}
|
||||||
|
|
||||||
|
export {updateHighTime, updateHighVal};
|
@ -7,12 +7,18 @@
|
|||||||
<meta name="description" content="Track current and historical gold price trends for the World of Warcraft (WoW) in game token, including the US, EU, TW, and KR regions. Prices updated every minute. Simple, quick, and easy info, no ads or tracking, ever.">
|
<meta name="description" content="Track current and historical gold price trends for the World of Warcraft (WoW) in game token, including the US, EU, TW, and KR regions. Prices updated every minute. Simple, quick, and easy info, no ads or tracking, ever.">
|
||||||
<link rel="preconnect" href="https://data.wowtoken.app">
|
<link rel="preconnect" href="https://data.wowtoken.app">
|
||||||
<link rel="dns-prefetch" href="https://data.wowtoken.app">
|
<link rel="dns-prefetch" href="https://data.wowtoken.app">
|
||||||
<link rel="preload" href="https://data.wowtoken.app/token/current.json" as="fetch" type="application/json" crossorigin="anonymous">
|
<link rel="preload" href="https://data.wowtoken.app/v2/current/retail.json" as="fetch" type="application/json" crossorigin="anonymous">
|
||||||
<link rel="preload" href="https://data.wowtoken.app/token/history/us/72h.json" as="fetch" type="application/json" crossorigin="anonymous">
|
<link rel="preload" href="https://data.wowtoken.app/v2/relative/retail/us/72h.json" as="fetch" type="application/json" crossorigin="anonymous">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="flex-container">
|
<div class="flex-container">
|
||||||
<div><h1>1 Token = <u id="token">0</u> Gold</h1></div>
|
<div class="data-header">
|
||||||
|
<h1>1 Token = <u id="token">0</u> Gold</h1>
|
||||||
|
<div class="high-low">
|
||||||
|
<p>Lowest in last <em id="low-time">3 days</em>: <u id="low-val">0</u></p>
|
||||||
|
<p>Highest in last <em id="high-time">3 days</em>: <u id="high-val">0</u></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div id="chart-frame">
|
<div id="chart-frame">
|
||||||
<div class="lds-ripple" id="loader"><div></div><div></div></div>
|
<div class="lds-ripple" id="loader"><div></div><div></div></div>
|
||||||
<canvas id="token-chart"></canvas>
|
<canvas id="token-chart"></canvas>
|
||||||
@ -49,25 +55,19 @@
|
|||||||
</fieldset>
|
</fieldset>
|
||||||
<fieldset id="advanced-options">
|
<fieldset id="advanced-options">
|
||||||
<legend>Advanced chart options</legend>
|
<legend>Advanced chart options</legend>
|
||||||
<fieldset id="advanced-region-options">
|
|
||||||
<legend>Multi-Region Selection</legend>
|
|
||||||
<label for="adv-r-us">US:</label>
|
|
||||||
<input type="checkbox" id="adv-r-us" name="adv-r-us" value="enable" disabled />
|
|
||||||
<label for="adv-r-eu">EU:</label>
|
|
||||||
<input type="checkbox" id="adv-r-eu" name="adv-r-eu" value="enable" disabled />
|
|
||||||
<label for="adv-r-kr">KR:</label>
|
|
||||||
<input type="checkbox" id="adv-r-kr" name="adv-r-kr" value="enable" disabled />
|
|
||||||
<label for="adv-r-tw">TW:</label>
|
|
||||||
<input type="checkbox" id="adv-r-tw" name="adv-r-tw" value="enable" disabled/>
|
|
||||||
</fieldset>
|
|
||||||
<fieldset id="basic-smoothing">
|
<fieldset id="basic-smoothing">
|
||||||
<label for="aggregate">Smoothing Function:</label>
|
<label for="aggregate">Smoothing Function:</label>
|
||||||
<select name="aggregate" id="aggregate">
|
<select name="aggregate" id="aggregate">
|
||||||
<option id='agg_none' value="none">None</option>
|
<option id='agg_none' value="none">None</option>
|
||||||
<option id='agg_davg' value="daily_mean">Daily Average</option>
|
<option id='agg_davg' value="avg">Daily Average</option>
|
||||||
<option id='agg_wavg' value="weekly_mean" disabled>Weekly Average</option>
|
|
||||||
</select>
|
</select>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
<fieldset id="period-overlay-options">
|
||||||
|
<label for="period-overlay" id="period-overlay-label">
|
||||||
|
Overlay previous <em id="period-time">0 hours</em> on current period:
|
||||||
|
</label>
|
||||||
|
<input type="checkbox" id="period-overlay" name="period-overlay">
|
||||||
|
</fieldset>
|
||||||
<fieldset id="y-start-options">
|
<fieldset id="y-start-options">
|
||||||
<label for="y-start">Start y-axis at 0:</label>
|
<label for="y-start">Start y-axis at 0:</label>
|
||||||
<input type="checkbox" id="y-start" name="y-start"/>
|
<input type="checkbox" id="y-start" name="y-start"/>
|
||||||
@ -80,7 +80,11 @@
|
|||||||
Copy URL to this Chart
|
Copy URL to this Chart
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div class="other-projects">
|
||||||
|
<p><em>
|
||||||
|
Get alerted when the Token hits certain thresholds using GoblinBot, find out more <a href="https://blog.emily.sh/token-bot/">here!</a>
|
||||||
|
</em></p>
|
||||||
|
<hr />
|
||||||
<p><em>Looking for the classic WoW Token price? Find it <a href="https://classic.wowtoken.app">here!</a></em></p>
|
<p><em>Looking for the classic WoW Token price? Find it <a href="https://classic.wowtoken.app">here!</a></em></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
304
src/index.js
304
src/index.js
@ -1,230 +1,99 @@
|
|||||||
import {
|
import 'chartjs-adapter-dayjs-4';
|
||||||
Chart,
|
|
||||||
Legend,
|
|
||||||
LinearScale,
|
|
||||||
LineController,
|
|
||||||
LineElement,
|
|
||||||
PointElement,
|
|
||||||
TimeSeriesScale,
|
|
||||||
Title,
|
|
||||||
Tooltip
|
|
||||||
} from 'chart.js';
|
|
||||||
import 'chartjs-adapter-dayjs-3';
|
|
||||||
import "./style.css"
|
import "./style.css"
|
||||||
|
|
||||||
// TODO: This file should be seperated into multiple with better ownership
|
import fetchCurrent from "./fetchCurrent";
|
||||||
|
import fetchData from "./fetchData";
|
||||||
|
import {updateHighTime} from "./highTime";
|
||||||
|
import {updateLowTime} from "./lowTime";
|
||||||
|
import {addLoader, removeLoader} from "./loader";
|
||||||
|
import {allowOverlay, forceOverlayOff, forceOverlayOn, isOverlayAllowed, isOverlaySelected} from "./overlay";
|
||||||
|
import TokenChart from "./tokenChart";
|
||||||
|
import Datum from "./datum";
|
||||||
|
|
||||||
Chart.register(
|
// TODO: This file should be seperated into multiple with better ownership
|
||||||
LineElement,
|
|
||||||
PointElement,
|
|
||||||
LineController,
|
|
||||||
LinearScale,
|
|
||||||
TimeSeriesScale,
|
|
||||||
Legend,
|
|
||||||
Title,
|
|
||||||
Tooltip
|
|
||||||
)
|
|
||||||
|
|
||||||
let currentRegionSelection = '';
|
let currentRegionSelection = '';
|
||||||
let currentTimeSelection = '';
|
let currentTimeSelection = '';
|
||||||
let currentAggregateSelection = '';
|
let currentAggregateSelection = '';
|
||||||
let startYAtZero = false;
|
let startYAtZero = false;
|
||||||
|
let datum;
|
||||||
|
let chart;
|
||||||
const currentPriceHash = {
|
const currentPriceHash = {
|
||||||
us: 0,
|
us: 0,
|
||||||
eu: 0,
|
eu: 0,
|
||||||
kr: 0,
|
kr: 0,
|
||||||
tw: 0
|
tw: 0
|
||||||
};
|
};
|
||||||
let chartData = {
|
const chartData = {
|
||||||
us: [],
|
us: [],
|
||||||
eu: [],
|
eu: [],
|
||||||
kr: [],
|
kr: [],
|
||||||
tw: []
|
tw: []
|
||||||
}
|
}
|
||||||
let chartOptions = {
|
|
||||||
us: {
|
|
||||||
color: 'gold'
|
|
||||||
},
|
|
||||||
eu: {
|
|
||||||
color: 'red'
|
|
||||||
},
|
|
||||||
kr: {
|
|
||||||
color: 'white'
|
|
||||||
},
|
|
||||||
tw: {
|
|
||||||
color: 'pink'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let chartJsData;
|
|
||||||
let ctx;
|
|
||||||
let tokenChart;
|
|
||||||
|
|
||||||
|
|
||||||
function populateChart() {
|
|
||||||
ctx = document.getElementById("token-chart").getContext('2d');
|
|
||||||
tokenChart = new Chart(ctx, {
|
|
||||||
type: 'line',
|
|
||||||
data: {
|
|
||||||
datasets: [{
|
|
||||||
borderColor: 'gold',
|
|
||||||
label: currentRegionSelection.toUpperCase() + " WoW Token Price",
|
|
||||||
data: chartJsData,
|
|
||||||
cubicInterpolationMode: 'monotone',
|
|
||||||
pointRadius: 0
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
options: {
|
|
||||||
interaction: {
|
|
||||||
intersect: false,
|
|
||||||
mode: "index"
|
|
||||||
},
|
|
||||||
scales: {
|
|
||||||
x: {
|
|
||||||
type: 'time',
|
|
||||||
grid: {
|
|
||||||
color: '#625f62',
|
|
||||||
},
|
|
||||||
ticks: {
|
|
||||||
color: '#a7a4ab',
|
|
||||||
font: {
|
|
||||||
size: 18,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
time: {
|
|
||||||
unit: lookupTimeUnit(currentTimeSelection)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
y: {
|
|
||||||
beginAtZero: startYAtZero,
|
|
||||||
grid: {
|
|
||||||
color: '#2f2c2f',
|
|
||||||
},
|
|
||||||
ticks: {
|
|
||||||
color: '#a7a4ab',
|
|
||||||
font: {
|
|
||||||
size: 18,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function lookupTimeUnit(query){
|
|
||||||
const lookup = {
|
|
||||||
'h': 'day',
|
|
||||||
'd': 'week',
|
|
||||||
'm': 'month',
|
|
||||||
'y': 'month',
|
|
||||||
'l': 'year'
|
|
||||||
}
|
|
||||||
return lookup[query.charAt(query.length - 1)]
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
async function callUpdateURL() {
|
async function callUpdateURL() {
|
||||||
let resp = await fetch("https://data.wowtoken.app/token/current.json");
|
await updateTokens(await fetchCurrent());
|
||||||
let data = await resp.json();
|
|
||||||
updateTokens(data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateTokens(data) {
|
async function updateTokens(data) {
|
||||||
updateRegionalToken('us', data);
|
await Promise.all([
|
||||||
updateRegionalToken('eu', data);
|
updateRegionalToken('us', data),
|
||||||
updateRegionalToken('kr', data);
|
updateRegionalToken('eu', data),
|
||||||
updateRegionalToken('tw', data);
|
updateRegionalToken('kr', data),
|
||||||
|
updateRegionalToken('tw', data)
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateRegionalToken(region, data) {
|
async function updateRegionalToken(region, data) {
|
||||||
if (currentPriceHash[region] !== data['price_data'][region]) {
|
if (currentPriceHash[region] !== data[region][1]) {
|
||||||
currentPriceHash[region] = data['price_data'][region];
|
currentPriceHash[region] = data[region][1];
|
||||||
if (region === currentRegionSelection) {
|
if (region === currentRegionSelection) {
|
||||||
formatToken();
|
formatToken();
|
||||||
if (currentAggregateSelection === 'none') {
|
datum = new Datum(Date.parse(data[region][0]), data[region][1]);
|
||||||
addDataToChart(region, data);
|
if (currentAggregateSelection === 'none' && chart.active()) {
|
||||||
|
await chart.addDataToChart(datum);
|
||||||
|
}
|
||||||
|
else if (currentAggregateSelection === 'none' && !chart.active()) {
|
||||||
|
await chart.lateUpdate(datum);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function addDataToChart(region, data) {
|
async function updateRegionPreference(newRegion) {
|
||||||
if (tokenChart) {
|
|
||||||
const datum = {x: data['current_time'], y: data['price_data'][region]}
|
|
||||||
tokenChart.data.datasets.forEach((dataset) => {
|
|
||||||
dataset.data.push(datum);
|
|
||||||
})
|
|
||||||
tokenChart.update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function aggregateFunctionToggle() {
|
|
||||||
// TODO: We should probably make these global or something
|
|
||||||
// so if the need to be updated in the future we can do so easily
|
|
||||||
const smallTimes = ['72h', '168h', '336h'];
|
|
||||||
const longTimes = ['720h', '30d', '2190h', '90d', '1y', '2y', '6m', 'all'];
|
|
||||||
const idsToModify = ['agg_wavg']
|
|
||||||
if (smallTimes.includes(currentTimeSelection)) {
|
|
||||||
for (const id of idsToModify) {
|
|
||||||
let ele = document.getElementById(id);
|
|
||||||
ele.disabled = true;
|
|
||||||
}
|
|
||||||
} else if (longTimes.includes(currentTimeSelection)) {
|
|
||||||
for (const id of idsToModify) {
|
|
||||||
let ele = document.getElementById(id);
|
|
||||||
ele.disabled = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function addLoader() {
|
|
||||||
let loader = document.getElementById('loader');
|
|
||||||
if (!loader) {
|
|
||||||
const blank_div = document.createElement('div');
|
|
||||||
let loaderNode = blank_div.cloneNode();
|
|
||||||
loaderNode.id = 'loader';
|
|
||||||
loaderNode.className = 'lds-ripple';
|
|
||||||
loaderNode.appendChild(blank_div.cloneNode());
|
|
||||||
loaderNode.appendChild(blank_div.cloneNode());
|
|
||||||
let chartNode = document.getElementById('token-chart');
|
|
||||||
chartNode.before(loaderNode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeLoader () {
|
|
||||||
let loader = document.getElementById('loader');
|
|
||||||
if (loader) {
|
|
||||||
loader.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateRegionPreference(newRegion) {
|
|
||||||
if (newRegion !== currentRegionSelection) {
|
if (newRegion !== currentRegionSelection) {
|
||||||
tokenChart.destroy();
|
await chart.destroyChart();
|
||||||
addLoader();
|
addLoader();
|
||||||
currentRegionSelection = newRegion;
|
currentRegionSelection = newRegion;
|
||||||
}
|
}
|
||||||
formatToken();
|
formatToken();
|
||||||
pullChartData().then(populateChart);
|
await pullChartData();
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateTimePreference(newTime) {
|
async function updateTimePreference(newTime) {
|
||||||
if (newTime !== currentTimeSelection) {
|
if (newTime !== currentTimeSelection) {
|
||||||
tokenChart.destroy();
|
await chart.destroyChart();
|
||||||
addLoader();
|
addLoader();
|
||||||
currentTimeSelection = newTime;
|
currentTimeSelection = newTime;
|
||||||
aggregateFunctionToggle();
|
|
||||||
}
|
}
|
||||||
pullChartData().then(populateChart);
|
if (newTime === "all") {
|
||||||
|
forceOverlayOff();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
allowOverlay();
|
||||||
|
}
|
||||||
|
await pullChartData();
|
||||||
|
updateHighTime();
|
||||||
|
updateLowTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateAggregatePreference(newAggregate) {
|
async function updateAggregatePreference(newAggregate) {
|
||||||
if (newAggregate !== currentAggregateSelection) {
|
if (newAggregate !== currentAggregateSelection) {
|
||||||
tokenChart.destroy();
|
await chart.destroyChart();
|
||||||
addLoader();
|
addLoader();
|
||||||
currentAggregateSelection = newAggregate;
|
currentAggregateSelection = newAggregate;
|
||||||
}
|
}
|
||||||
pullChartData().then(populateChart);
|
await pullChartData();
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleAdvancedSetting() {
|
function toggleAdvancedSetting() {
|
||||||
@ -241,33 +110,32 @@ function toggleAdvancedSetting() {
|
|||||||
|
|
||||||
function toggleStartYAtZero(){
|
function toggleStartYAtZero(){
|
||||||
startYAtZero = document.getElementById('y-start').checked;
|
startYAtZero = document.getElementById('y-start').checked;
|
||||||
if (tokenChart){
|
chart.toggleYStart(startYAtZero);
|
||||||
tokenChart.options.scales.y.beginAtZero = startYAtZero;
|
|
||||||
tokenChart.update();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function urlBuilder() {
|
async function toggleOverlay() {
|
||||||
let url = "https://data.wowtoken.app/token/history/";
|
await chart.destroyChart();
|
||||||
if (currentAggregateSelection !== 'none') {
|
addLoader();
|
||||||
url += `${currentAggregateSelection}/`
|
await pullChartData();
|
||||||
}
|
|
||||||
url += `${currentRegionSelection}/${currentTimeSelection}.json`
|
|
||||||
return url;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function pullChartData() {
|
async function pullChartData() {
|
||||||
let resp = await fetch(urlBuilder());
|
let timeSelection = currentTimeSelection;
|
||||||
let chartData = await resp.json();
|
if (isOverlaySelected()) {
|
||||||
let newChartJSData = [];
|
let timeDigits = parseInt(timeSelection.slice(0, timeSelection.length - 1)) * 2;
|
||||||
for (let i = 0; i < chartData.length; i++) {
|
let timeUnit = timeSelection.slice(timeSelection.length - 1);
|
||||||
let datum = {
|
timeSelection = `${timeDigits}${timeUnit}`;
|
||||||
x: chartData[i]['time'],
|
}
|
||||||
y: chartData[i]['value']
|
chartData[currentRegionSelection] = await fetchData(currentRegionSelection, timeSelection, currentAggregateSelection);
|
||||||
};
|
if (!chart.active()) {
|
||||||
newChartJSData.push(datum);
|
await chart.createChart(currentRegionSelection, currentTimeSelection, startYAtZero, chartData[currentRegionSelection]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (let i = 0; i < chartData[currentRegionSelection].length; i++) {
|
||||||
|
await chart.addDataToChart(chartData[currentRegionSelection][i]);
|
||||||
|
}
|
||||||
|
console.warn("This should never hit, and should be okay to remove");
|
||||||
}
|
}
|
||||||
chartJsData = newChartJSData;
|
|
||||||
removeLoader();
|
removeLoader();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -299,28 +167,36 @@ function detectTimeQuery(urlSearchParams) {
|
|||||||
const validTimes = ['72h', '168h', '336h', '720h', '30d', '2190h', '90d', '1y', '2y', '6m', 'all'];
|
const validTimes = ['72h', '168h', '336h', '720h', '30d', '2190h', '90d', '1y', '2y', '6m', 'all'];
|
||||||
if (validTimes.includes(urlSearchParams.get('time').toLowerCase())) {
|
if (validTimes.includes(urlSearchParams.get('time').toLowerCase())) {
|
||||||
currentTimeSelection = urlSearchParams.get('time').toLowerCase();
|
currentTimeSelection = urlSearchParams.get('time').toLowerCase();
|
||||||
|
if (currentTimeSelection === 'all') {
|
||||||
|
forceOverlayOff();
|
||||||
|
}
|
||||||
let timeDDL = document.getElementById('time');
|
let timeDDL = document.getElementById('time');
|
||||||
for (let i = 0; i < timeDDL.options.length; i++) {
|
for (let i = 0; i < timeDDL.options.length; i++) {
|
||||||
if (timeDDL.options[i].value === currentTimeSelection) {
|
if (timeDDL.options[i].value === currentTimeSelection) {
|
||||||
timeDDL.options[i].selected = true;
|
timeDDL.options[i].selected = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
updateHighTime();
|
||||||
|
updateLowTime();
|
||||||
} else {
|
} else {
|
||||||
console.warn("An incorrect or malformed time selection was made in the query string");
|
console.warn("An incorrect or malformed time selection was made in the query string");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function detectAggregateQuery(urlSearchParams) {
|
function detectAggregateQuery(urlSearchParams) {
|
||||||
const validOperations = ['none', 'daily_mean', 'weekly_mean'];
|
const validOperations = ['none', 'daily_mean', 'avg'];
|
||||||
if (validOperations.includes(urlSearchParams.get('aggregate').toLowerCase())) {
|
if (validOperations.includes(urlSearchParams.get('aggregate').toLowerCase())) {
|
||||||
currentAggregateSelection = urlSearchParams.get('aggregate').toLowerCase();
|
currentAggregateSelection = urlSearchParams.get('aggregate').toLowerCase();
|
||||||
|
// For backwards compatibility
|
||||||
|
if (currentAggregateSelection === 'daily_mean') {
|
||||||
|
currentAggregateSelection = 'avg';
|
||||||
|
}
|
||||||
let aggregateDDL = document.getElementById('aggregate');
|
let aggregateDDL = document.getElementById('aggregate');
|
||||||
for (let i = 0; i < aggregateDDL.options.length; i++) {
|
for (let i = 0; i < aggregateDDL.options.length; i++) {
|
||||||
if (aggregateDDL.options[i].value === currentAggregateSelection) {
|
if (aggregateDDL.options[i].value === currentAggregateSelection) {
|
||||||
aggregateDDL.options[i].selected = true;
|
aggregateDDL.options[i].selected = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
aggregateFunctionToggle();
|
|
||||||
} else {
|
} else {
|
||||||
console.warn("An incorrect or malformed aggregate selection was made in the query string");
|
console.warn("An incorrect or malformed aggregate selection was made in the query string");
|
||||||
}
|
}
|
||||||
@ -336,6 +212,15 @@ function detectZeroQuery(urlSearchParams) {
|
|||||||
toggleStartYAtZero();
|
toggleStartYAtZero();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function detectOverlayQuery(urlSearchParams) {
|
||||||
|
const enableOverlay = urlSearchParams.get('overlay') === 'previous_time';
|
||||||
|
if (enableOverlay) {
|
||||||
|
forceOverlayOn();
|
||||||
|
} else {
|
||||||
|
forceOverlayOff();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function detectURLQuery() {
|
function detectURLQuery() {
|
||||||
const urlSearchParams = new URLSearchParams(window.location.search);
|
const urlSearchParams = new URLSearchParams(window.location.search);
|
||||||
if (urlSearchParams.has('region')) {
|
if (urlSearchParams.has('region')) {
|
||||||
@ -350,6 +235,9 @@ function detectURLQuery() {
|
|||||||
if (urlSearchParams.has('startAtZero')) {
|
if (urlSearchParams.has('startAtZero')) {
|
||||||
detectZeroQuery(urlSearchParams)
|
detectZeroQuery(urlSearchParams)
|
||||||
}
|
}
|
||||||
|
if (urlSearchParams.has('overlay')) {
|
||||||
|
detectOverlayQuery(urlSearchParams);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildDeepLinksURL() {
|
function buildDeepLinksURL() {
|
||||||
@ -366,6 +254,9 @@ function buildDeepLinksURL() {
|
|||||||
if (startYAtZero !== false){
|
if (startYAtZero !== false){
|
||||||
url += `startAtZero=${startYAtZero}&`
|
url += `startAtZero=${startYAtZero}&`
|
||||||
}
|
}
|
||||||
|
if (isOverlaySelected()){
|
||||||
|
url += `overlay=previous_time&`
|
||||||
|
}
|
||||||
return url
|
return url
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -392,6 +283,8 @@ function registerEventHandles() {
|
|||||||
registerAdvancedHandlers();
|
registerAdvancedHandlers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: These need to be moved out into probably tokenChart if not other files
|
||||||
|
|
||||||
function registerAdvancedHandlers() {
|
function registerAdvancedHandlers() {
|
||||||
document.getElementById('enable-advanced').addEventListener('change', () => {
|
document.getElementById('enable-advanced').addEventListener('change', () => {
|
||||||
toggleAdvancedSetting();
|
toggleAdvancedSetting();
|
||||||
@ -399,6 +292,9 @@ function registerAdvancedHandlers() {
|
|||||||
document.getElementById('y-start').addEventListener('change', () => {
|
document.getElementById('y-start').addEventListener('change', () => {
|
||||||
toggleStartYAtZero();
|
toggleStartYAtZero();
|
||||||
})
|
})
|
||||||
|
document.getElementById('period-overlay').addEventListener('change', () => {
|
||||||
|
toggleOverlay();
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function registerCopyHandlers() {
|
function registerCopyHandlers() {
|
||||||
@ -428,7 +324,11 @@ function registerOptionHandlers() {
|
|||||||
document.addEventListener('DOMContentLoaded', function () {
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
registerEventHandles();
|
registerEventHandles();
|
||||||
detectURLQuery();
|
detectURLQuery();
|
||||||
Promise.all([callUpdateURL(), pullChartData()]).then(populateChart)
|
chart = new TokenChart();
|
||||||
|
Promise.all([
|
||||||
|
callUpdateURL(),
|
||||||
|
]).then(pullChartData);
|
||||||
|
|
||||||
setInterval(callUpdateURL, 60*1000);
|
setInterval(callUpdateURL, 60*1000);
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
|
22
src/loader.js
Normal file
22
src/loader.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
function addLoader() {
|
||||||
|
let loader = document.getElementById('loader');
|
||||||
|
if (!loader) {
|
||||||
|
const blank_div = document.createElement('div');
|
||||||
|
let loaderNode = blank_div.cloneNode();
|
||||||
|
loaderNode.id = 'loader';
|
||||||
|
loaderNode.className = 'lds-ripple';
|
||||||
|
loaderNode.appendChild(blank_div.cloneNode());
|
||||||
|
loaderNode.appendChild(blank_div.cloneNode());
|
||||||
|
let chartNode = document.getElementById('token-chart');
|
||||||
|
chartNode.before(loaderNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeLoader () {
|
||||||
|
let loader = document.getElementById('loader');
|
||||||
|
if (loader) {
|
||||||
|
loader.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export {addLoader, removeLoader};
|
17
src/lowTime.js
Normal file
17
src/lowTime.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import Datum from "./datum";
|
||||||
|
|
||||||
|
function updateLowTime() {
|
||||||
|
const lowTime= document.getElementById("low-time");
|
||||||
|
|
||||||
|
const currentTime = document.getElementById("time").selectedOptions[0].innerText;
|
||||||
|
if (currentTime.toLowerCase() !== lowTime.innerText) {
|
||||||
|
lowTime.innerText = currentTime.toLowerCase();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateLowVal(datum) {
|
||||||
|
const lowVal = document.getElementById("low-val");
|
||||||
|
lowVal.innerHTML = datum.getPrice().toLocaleString();
|
||||||
|
}
|
||||||
|
|
||||||
|
export {updateLowTime, updateLowVal};
|
40
src/overlay.js
Normal file
40
src/overlay.js
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
function isOverlaySelected() {
|
||||||
|
return document.getElementById('period-overlay').checked;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getOverlayTime() {
|
||||||
|
return document.getElementById("time").selectedOptions[0].innerText;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setOverlayLabelTime() {
|
||||||
|
const currentTime = document.getElementById("time").selectedOptions[0].innerText;
|
||||||
|
let overlayTimeLabel = document.getElementById("period-time");
|
||||||
|
overlayTimeLabel.innerText = currentTime.toLocaleString();
|
||||||
|
}
|
||||||
|
|
||||||
|
function forceOverlayOff(){
|
||||||
|
const overlaySetting = document.getElementById("period-overlay");
|
||||||
|
const periodOverlayField = document.getElementById("period-overlay-options");
|
||||||
|
overlaySetting.checked = false;
|
||||||
|
periodOverlayField.style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
function forceOverlayOn(){
|
||||||
|
const overlaySetting = document.getElementById("period-overlay");
|
||||||
|
const periodOverlayField = document.getElementById("period-overlay-options");
|
||||||
|
const advancedOptionsField = document.getElementById("advanced-options");
|
||||||
|
overlaySetting.checked = true;
|
||||||
|
advancedOptionsField.style.display = 'flex';
|
||||||
|
periodOverlayField.style.display = 'flex';
|
||||||
|
}
|
||||||
|
|
||||||
|
function isOverlayAllowed(timeSelection) {
|
||||||
|
return !(timeSelection === "all")
|
||||||
|
}
|
||||||
|
|
||||||
|
function allowOverlay(){
|
||||||
|
const periodOverlayField = document.getElementById("period-overlay-options");
|
||||||
|
periodOverlayField.style.display = 'flex';
|
||||||
|
}
|
||||||
|
|
||||||
|
export {isOverlaySelected, getOverlayTime, setOverlayLabelTime, forceOverlayOff, forceOverlayOn, isOverlayAllowed, allowOverlay};
|
@ -367,6 +367,7 @@ details[open] summary {
|
|||||||
margin-bottom: 0.5em;
|
margin-bottom: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#option_select {
|
#option_select {
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
line-height: 40px;
|
line-height: 40px;
|
||||||
@ -419,6 +420,31 @@ details[open] summary {
|
|||||||
margin: 10px;
|
margin: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.other-projects {
|
||||||
|
border: 1px solid silver;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.other-projects > p {
|
||||||
|
line-height: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-header h1 {
|
||||||
|
margin-top: 24px;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.high-low {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
}
|
||||||
|
|
||||||
|
.high-low p {
|
||||||
|
line-height: 1em;
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
.lds-ripple {
|
.lds-ripple {
|
||||||
position: relative;
|
position: relative;
|
||||||
align-self: center;
|
align-self: center;
|
||||||
|
311
src/tokenChart.js
Normal file
311
src/tokenChart.js
Normal file
@ -0,0 +1,311 @@
|
|||||||
|
import {
|
||||||
|
Chart,
|
||||||
|
Legend,
|
||||||
|
LinearScale,
|
||||||
|
LineController,
|
||||||
|
LineElement,
|
||||||
|
PointElement,
|
||||||
|
TimeSeriesScale,
|
||||||
|
Title,
|
||||||
|
Tooltip
|
||||||
|
} from 'chart.js';
|
||||||
|
import 'chartjs-adapter-dayjs-4';
|
||||||
|
|
||||||
|
Chart.register(
|
||||||
|
LineElement,
|
||||||
|
PointElement,
|
||||||
|
LineController,
|
||||||
|
LinearScale,
|
||||||
|
TimeSeriesScale,
|
||||||
|
Legend,
|
||||||
|
Title,
|
||||||
|
Tooltip
|
||||||
|
)
|
||||||
|
|
||||||
|
import {updateHighVal} from "./highTime";
|
||||||
|
import {updateLowVal} from "./lowTime";
|
||||||
|
import {isOverlaySelected, getOverlayTime, setOverlayLabelTime} from "./overlay";
|
||||||
|
import Datum from "./datum";
|
||||||
|
|
||||||
|
function lookupTimeUnit(query){
|
||||||
|
const lookup = {
|
||||||
|
'h': 'day',
|
||||||
|
'd': 'week',
|
||||||
|
'm': 'month',
|
||||||
|
'y': 'month',
|
||||||
|
'l': 'year'
|
||||||
|
}
|
||||||
|
return lookup[query.charAt(query.length - 1)]
|
||||||
|
}
|
||||||
|
|
||||||
|
function timeDeltaInMilliseconds(time) {
|
||||||
|
let timeDigits = (parseInt(time.slice(0, time.length - 1))).toFixed(0);
|
||||||
|
let timeUnit = time.slice(time.length - 1);
|
||||||
|
|
||||||
|
switch (timeUnit) {
|
||||||
|
case 'h':
|
||||||
|
return timeDigits * (60 * 60) * 1000;
|
||||||
|
case 'd':
|
||||||
|
return timeDigits * (24 * 60 * 60) * 1000;
|
||||||
|
case 'm':
|
||||||
|
return (timeDigits * (30.437 * 24 * 60 * 60)).toFixed(0) * 1000;
|
||||||
|
case 'y':
|
||||||
|
return (timeDigits * (365.25 * 24 * 60 * 60)).toFixed(0) * 1000;
|
||||||
|
case 'l':
|
||||||
|
console.warn("This path should not happen, this warning is an error in logic")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class TokenChart {
|
||||||
|
constructor() {
|
||||||
|
this._context = document.getElementById("token-chart").getContext('2d');
|
||||||
|
this._chartActive = false;
|
||||||
|
this._lastDatum = null;
|
||||||
|
this._highDatum = null;
|
||||||
|
this._lowDatum = null;
|
||||||
|
this._lateUpdate = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
get highDatum() {
|
||||||
|
return this._highDatum;
|
||||||
|
}
|
||||||
|
|
||||||
|
get lowDatum() {
|
||||||
|
return this._lowDatum;
|
||||||
|
}
|
||||||
|
|
||||||
|
async #newChart(chartConfig) {
|
||||||
|
this._chart = new Chart(this._context, chartConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
async #updateHighLow(datum) {
|
||||||
|
if (this._highDatum === null) {
|
||||||
|
this._highDatum = new Datum(datum.getTime(), 0);
|
||||||
|
this._lowDatum = datum;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (datum.getPrice() > this._highDatum.getPrice()) {
|
||||||
|
this._highDatum = datum;
|
||||||
|
updateHighVal(this.highDatum);
|
||||||
|
}
|
||||||
|
else if (datum.getPrice() < this._lowDatum.getPrice()) {
|
||||||
|
this._lowDatum = datum;
|
||||||
|
updateLowVal(this.lowDatum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async #createOverlayChart(region, time, yLevel, data){
|
||||||
|
const chartData = [];
|
||||||
|
const overlayData = [];
|
||||||
|
const overlayDelta = timeDeltaInMilliseconds(time);
|
||||||
|
|
||||||
|
for (let i = 0; i < data.length; i++) {
|
||||||
|
const originalDate = data[i].getX();
|
||||||
|
if (i < (data.length / 2)) {
|
||||||
|
overlayData.push({
|
||||||
|
x: new Date(originalDate.getTime() + overlayDelta),
|
||||||
|
y: data[i].getY(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
await this.#updateHighLow(data[i]);
|
||||||
|
|
||||||
|
chartData.push({
|
||||||
|
x: data[i].getX(),
|
||||||
|
y: data[i].getY(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const chartConfig = {
|
||||||
|
type: 'line',
|
||||||
|
data: {
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
borderColor: 'gold',
|
||||||
|
label: region.toUpperCase() + " WoW Token Price",
|
||||||
|
data: chartData,
|
||||||
|
cubicInterpolationMode: 'monotone',
|
||||||
|
pointRadius: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
borderColor: 'red',
|
||||||
|
label: `Previous ${getOverlayTime()} ${region.toUpperCase()} WoW Token Price`,
|
||||||
|
data: overlayData,
|
||||||
|
cubicInterpolationMode: 'monotone',
|
||||||
|
pointRadius: 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
interaction: {
|
||||||
|
intersect: false,
|
||||||
|
mode: "index"
|
||||||
|
},
|
||||||
|
scales: {
|
||||||
|
x: {
|
||||||
|
type: 'time',
|
||||||
|
grid: {
|
||||||
|
color: '#625f62',
|
||||||
|
},
|
||||||
|
ticks: {
|
||||||
|
color: '#a7a4ab',
|
||||||
|
font: {
|
||||||
|
size: 18,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
time: {
|
||||||
|
unit: lookupTimeUnit(time)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
y: {
|
||||||
|
beginAtZero: yLevel,
|
||||||
|
grid: {
|
||||||
|
color: '#2f2c2f',
|
||||||
|
},
|
||||||
|
ticks: {
|
||||||
|
color: '#a7a4ab',
|
||||||
|
font: {
|
||||||
|
size: 18,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.#newChart(chartConfig)
|
||||||
|
}
|
||||||
|
|
||||||
|
async #createNormalChart(region, time, yLevel, data) {
|
||||||
|
const chartData = [];
|
||||||
|
|
||||||
|
|
||||||
|
for (let i = 0; i < data.length; i++) {
|
||||||
|
this._lastDatum = data[i];
|
||||||
|
await this.#updateHighLow(data[i]);
|
||||||
|
|
||||||
|
chartData.push({
|
||||||
|
x: data[i].getX(),
|
||||||
|
y: data[i].getY(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const chartConfig = {
|
||||||
|
type: 'line',
|
||||||
|
data: {
|
||||||
|
datasets: [{
|
||||||
|
borderColor: 'gold',
|
||||||
|
label: region.toUpperCase() + " WoW Token Price",
|
||||||
|
data: chartData,
|
||||||
|
cubicInterpolationMode: 'monotone',
|
||||||
|
pointRadius: 0
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
interaction: {
|
||||||
|
intersect: false,
|
||||||
|
mode: "index"
|
||||||
|
},
|
||||||
|
scales: {
|
||||||
|
x: {
|
||||||
|
type: 'time',
|
||||||
|
grid: {
|
||||||
|
color: '#625f62',
|
||||||
|
},
|
||||||
|
ticks: {
|
||||||
|
color: '#a7a4ab',
|
||||||
|
font: {
|
||||||
|
size: 18,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
time: {
|
||||||
|
unit: lookupTimeUnit(time)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
y: {
|
||||||
|
beginAtZero: yLevel,
|
||||||
|
grid: {
|
||||||
|
color: '#2f2c2f',
|
||||||
|
},
|
||||||
|
ticks: {
|
||||||
|
color: '#a7a4ab',
|
||||||
|
font: {
|
||||||
|
size: 18,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.#newChart(chartConfig)
|
||||||
|
}
|
||||||
|
|
||||||
|
async createChart(region, time, yLevel, data) {
|
||||||
|
let lateUpdateData = this._lastDatum;
|
||||||
|
|
||||||
|
if (isOverlaySelected()) {
|
||||||
|
await this.#createOverlayChart(region, time, yLevel, data)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
await this.#createNormalChart(region, time, yLevel, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
setOverlayLabelTime();
|
||||||
|
|
||||||
|
updateHighVal(this.highDatum);
|
||||||
|
updateLowVal(this.lowDatum);
|
||||||
|
|
||||||
|
if (this._lateUpdate) {
|
||||||
|
if (this._lastDatum.getPrice() !== lateUpdateData.getPrice() &&
|
||||||
|
this._lastDatum.getTime() < lateUpdateData.getTime()) {
|
||||||
|
await this.addDataToChart(lateUpdateData);
|
||||||
|
}
|
||||||
|
this._lateUpdate = false
|
||||||
|
}
|
||||||
|
|
||||||
|
this._chartActive = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
async destroyChart() {
|
||||||
|
await this._chart.destroy();
|
||||||
|
this._chartActive = false;
|
||||||
|
this._lastDatum = null;
|
||||||
|
this._highDatum = null;
|
||||||
|
this._lowDatum = null;
|
||||||
|
this._lateUpdate = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
async lateUpdate(datum){
|
||||||
|
this._lastDatum = datum;
|
||||||
|
this._lateUpdate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
async addDataToChart(datum) {
|
||||||
|
this._lastDatum = datum;
|
||||||
|
if (datum.getPrice() > this._highDatum.getPrice()) {
|
||||||
|
this._highDatum = datum;
|
||||||
|
updateHighVal(this.highDatum);
|
||||||
|
}
|
||||||
|
else if (datum.getPrice() < this._lowDatum.getPrice()) {
|
||||||
|
this._lowDatum = datum;
|
||||||
|
updateLowVal(this.lowDatum);
|
||||||
|
}
|
||||||
|
this._chart.data.datasets[0].data.push({
|
||||||
|
x: datum.getX(),
|
||||||
|
y: datum.getY(),
|
||||||
|
});
|
||||||
|
this._chart.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
active() {
|
||||||
|
return this._chartActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleYStart(startYAtZero) {
|
||||||
|
this._chart.options.scales.y.beginAtZero = startYAtZero;
|
||||||
|
this._chart.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
12
src/urlBuilder.js
Normal file
12
src/urlBuilder.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
export default function urlBuilder(currentRegionSelection, currentTimeSelection, currentAggregateSelection) {
|
||||||
|
let url = "https://data.wowtoken.app/v2/";
|
||||||
|
if (currentAggregateSelection !== '' && currentAggregateSelection !== 'none'){
|
||||||
|
url += `math/${currentAggregateSelection}/retail/`
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
url += `relative/retail/`
|
||||||
|
}
|
||||||
|
|
||||||
|
url += `${currentRegionSelection}/${currentTimeSelection}.json`;
|
||||||
|
return url;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user