305 lines
8.7 KiB
JavaScript
305 lines
8.7 KiB
JavaScript
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";
|
|
|
|
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 #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 {
|
|
|
|
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++) {
|
|
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
|
|
}]
|
|
},
|
|
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(datum);
|
|
this._chart.update();
|
|
}
|
|
|
|
active() {
|
|
return this._chartActive;
|
|
}
|
|
|
|
toggleYStart(startYAtZero) {
|
|
this._chart.options.scales.y.beginAtZero = startYAtZero;
|
|
this._chart.update();
|
|
}
|
|
|
|
} |