Initial implementation of overlay functionality
This commit is contained in:
parent
8c8499fb1c
commit
d25334d35f
@ -6,7 +6,7 @@ export default async function fetchData(currentRegionSelection, currentTimeSelec
|
|||||||
const resp = await fetch(urlBuilder(currentRegionSelection, currentTimeSelection, currentAggregateSelection));
|
const resp = await fetch(urlBuilder(currentRegionSelection, currentTimeSelection, currentAggregateSelection));
|
||||||
const respData = await resp.json();
|
const respData = await resp.json();
|
||||||
for (let i = 0, l = respData.length; i < l; i++) {
|
for (let i = 0, l = respData.length; i < l; i++) {
|
||||||
let datum = new Datum(Date.parse(respData[i][0]), respData[i][1]);
|
const datum = new Datum(new Date(respData[i][0]), respData[i][1]);
|
||||||
data.push(datum);
|
data.push(datum);
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
|
@ -62,6 +62,12 @@
|
|||||||
<option id='agg_davg' value="avg">Daily Average</option>
|
<option id='agg_davg' value="avg">Daily 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"/>
|
||||||
|
34
src/index.js
34
src/index.js
@ -6,6 +6,7 @@ import fetchData from "./fetchData";
|
|||||||
import {updateHighTime} from "./highTime";
|
import {updateHighTime} from "./highTime";
|
||||||
import {updateLowTime} from "./lowTime";
|
import {updateLowTime} from "./lowTime";
|
||||||
import {addLoader, removeLoader} from "./loader";
|
import {addLoader, removeLoader} from "./loader";
|
||||||
|
import {allowOverlay, forceOverlayOff, isOverlaySelected} from "./overlay";
|
||||||
import TokenChart from "./tokenChart";
|
import TokenChart from "./tokenChart";
|
||||||
import Datum from "./datum";
|
import Datum from "./datum";
|
||||||
|
|
||||||
@ -66,7 +67,6 @@ async function updateRegionPreference(newRegion) {
|
|||||||
currentRegionSelection = newRegion;
|
currentRegionSelection = newRegion;
|
||||||
}
|
}
|
||||||
formatToken();
|
formatToken();
|
||||||
chart = new TokenChart();
|
|
||||||
await pullChartData();
|
await pullChartData();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,7 +76,12 @@ async function updateTimePreference(newTime) {
|
|||||||
addLoader();
|
addLoader();
|
||||||
currentTimeSelection = newTime;
|
currentTimeSelection = newTime;
|
||||||
}
|
}
|
||||||
chart = new TokenChart();
|
if (newTime === "all") {
|
||||||
|
forceOverlayOff();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
allowOverlay();
|
||||||
|
}
|
||||||
await pullChartData();
|
await pullChartData();
|
||||||
updateHighTime();
|
updateHighTime();
|
||||||
updateLowTime();
|
updateLowTime();
|
||||||
@ -88,7 +93,6 @@ async function updateAggregatePreference(newAggregate) {
|
|||||||
addLoader();
|
addLoader();
|
||||||
currentAggregateSelection = newAggregate;
|
currentAggregateSelection = newAggregate;
|
||||||
}
|
}
|
||||||
chart = new TokenChart();
|
|
||||||
await pullChartData();
|
await pullChartData();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,16 +113,28 @@ function toggleStartYAtZero(){
|
|||||||
chart.toggleYStart(startYAtZero);
|
chart.toggleYStart(startYAtZero);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function toggleOverlay() {
|
||||||
|
await chart.destroyChart();
|
||||||
|
addLoader();
|
||||||
|
await pullChartData();
|
||||||
|
}
|
||||||
|
|
||||||
async function pullChartData() {
|
async function pullChartData() {
|
||||||
chartData[currentRegionSelection] = await fetchData(currentRegionSelection, currentTimeSelection, currentAggregateSelection);
|
let timeSelection = currentTimeSelection;
|
||||||
|
if (isOverlaySelected()) {
|
||||||
|
let timeDigits = parseInt(timeSelection.slice(0, timeSelection.length - 1)) * 2;
|
||||||
|
let timeUnit = timeSelection.slice(timeSelection.length - 1);
|
||||||
|
timeSelection = `${timeDigits}${timeUnit}`;
|
||||||
|
}
|
||||||
|
chartData[currentRegionSelection] = await fetchData(currentRegionSelection, timeSelection, currentAggregateSelection);
|
||||||
if (!chart.active()) {
|
if (!chart.active()) {
|
||||||
await chart.createChart(currentRegionSelection, currentTimeSelection, startYAtZero, chartData[currentRegionSelection]);
|
await chart.createChart(currentRegionSelection, currentTimeSelection, startYAtZero, chartData[currentRegionSelection]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for (let i = 0; i < chartData[currentRegionSelection].length; i++) {
|
for (let i = 0; i < chartData[currentRegionSelection].length; i++) {
|
||||||
await chart.addDataToChart(chartData[currentRegionSelection][i]);
|
await chart.addDataToChart(chartData[currentRegionSelection][i]);
|
||||||
console.warn("This should never hit, and should be okay to remove");
|
|
||||||
}
|
}
|
||||||
|
console.warn("This should never hit, and should be okay to remove");
|
||||||
}
|
}
|
||||||
removeLoader();
|
removeLoader();
|
||||||
}
|
}
|
||||||
@ -151,6 +167,9 @@ 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) {
|
||||||
@ -249,6 +268,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();
|
||||||
@ -256,6 +277,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() {
|
||||||
|
27
src/overlay.js
Normal file
27
src/overlay.js
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
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 allowOverlay(){
|
||||||
|
const periodOverlayField = document.getElementById("period-overlay-options");
|
||||||
|
periodOverlayField.style.display = 'flex';
|
||||||
|
}
|
||||||
|
|
||||||
|
export {isOverlaySelected, getOverlayTime, setOverlayLabelTime, forceOverlayOff, allowOverlay};
|
@ -24,6 +24,7 @@ Chart.register(
|
|||||||
|
|
||||||
import {updateHighVal} from "./highTime";
|
import {updateHighVal} from "./highTime";
|
||||||
import {updateLowVal} from "./lowTime";
|
import {updateLowVal} from "./lowTime";
|
||||||
|
import {isOverlaySelected, getOverlayTime, setOverlayLabelTime} from "./overlay";
|
||||||
|
|
||||||
function lookupTimeUnit(query){
|
function lookupTimeUnit(query){
|
||||||
const lookup = {
|
const lookup = {
|
||||||
@ -36,6 +37,24 @@ function lookupTimeUnit(query){
|
|||||||
return lookup[query.charAt(query.length - 1)]
|
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 {
|
export default class TokenChart {
|
||||||
constructor() {
|
constructor() {
|
||||||
this._context = document.getElementById("token-chart").getContext('2d');
|
this._context = document.getElementById("token-chart").getContext('2d');
|
||||||
@ -54,9 +73,104 @@ export default class TokenChart {
|
|||||||
return this._lowDatum;
|
return this._lowDatum;
|
||||||
}
|
}
|
||||||
|
|
||||||
async createChart(region, time, yLevel, data) {
|
async #newChart(chartConfig) {
|
||||||
|
this._chart = new Chart(this._context, chartConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
async #createOverlayChart(region, time, yLevel, data){
|
||||||
const chartData = [];
|
const chartData = [];
|
||||||
let lateUpdateData = this._lastDatum;
|
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 {
|
||||||
|
|
||||||
|
this._lastDatum = data[i];
|
||||||
|
if (this._highDatum === null || this._lastDatum.getPrice() > this._highDatum.getPrice()) {
|
||||||
|
this._highDatum = data[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._lowDatum === null || this._lowDatum.getPrice() > this._lastDatum.getPrice()) {
|
||||||
|
this._lowDatum = 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++) {
|
for (let i = 0; i < data.length; i++) {
|
||||||
this._lastDatum = data[i];
|
this._lastDatum = data[i];
|
||||||
@ -74,10 +188,7 @@ export default class TokenChart {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
updateHighVal(this.highDatum);
|
const chartConfig = {
|
||||||
updateLowVal(this.lowDatum);
|
|
||||||
|
|
||||||
this._chart = new Chart(this._context, {
|
|
||||||
type: 'line',
|
type: 'line',
|
||||||
data: {
|
data: {
|
||||||
datasets: [{
|
datasets: [{
|
||||||
@ -123,7 +234,25 @@ export default class TokenChart {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
|
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._lateUpdate) {
|
||||||
if (this._lastDatum.getPrice() !== lateUpdateData.getPrice() &&
|
if (this._lastDatum.getPrice() !== lateUpdateData.getPrice() &&
|
||||||
@ -160,12 +289,7 @@ export default class TokenChart {
|
|||||||
this._lowDatum = datum;
|
this._lowDatum = datum;
|
||||||
updateLowVal(this.lowDatum);
|
updateLowVal(this.lowDatum);
|
||||||
}
|
}
|
||||||
this._chart.data.datasets.forEach((dataset) => {
|
this._chart.data.datasets[0].data.push(datum);
|
||||||
dataset.data.push({
|
|
||||||
x: datum.getX(),
|
|
||||||
y: datum.getY(),
|
|
||||||
})
|
|
||||||
});
|
|
||||||
this._chart.update();
|
this._chart.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user