wowtoken.app

git clone https://git.emily.sh/wowtoken-app/wowtoken.app.git
Log | Files | Refs | README | LICENSE

tokenChart.js (8871B)


      1 import {
      2     Chart,
      3     Legend,
      4     LinearScale,
      5     LineController,
      6     LineElement,
      7     PointElement,
      8     TimeSeriesScale,
      9     Title,
     10     Tooltip
     11 } from 'chart.js';
     12 import 'chartjs-adapter-dayjs-4';
     13 
     14 Chart.register(
     15     LineElement,
     16     PointElement,
     17     LineController,
     18     LinearScale,
     19     TimeSeriesScale,
     20     Legend,
     21     Title,
     22     Tooltip
     23 )
     24 
     25 import {updateHighVal} from "./highTime";
     26 import {updateLowVal} from "./lowTime";
     27 import {isOverlaySelected, getOverlayTime, setOverlayLabelTime} from "./overlay";
     28 import Datum from "./datum";
     29 
     30 function lookupTimeUnit(query){
     31     const lookup = {
     32         'h': 'day',
     33         'd': 'week',
     34         'm': 'month',
     35         'y': 'month',
     36         'l': 'year'
     37     }
     38     return lookup[query.charAt(query.length - 1)]
     39 }
     40 
     41 function timeDeltaInMilliseconds(time) {
     42     let timeDigits = (parseInt(time.slice(0, time.length - 1))).toFixed(0);
     43     let timeUnit = time.slice(time.length - 1);
     44 
     45     switch (timeUnit) {
     46         case 'h':
     47             return timeDigits * (60 * 60) * 1000;
     48         case 'd':
     49             return timeDigits * (24 * 60 * 60) * 1000;
     50         case 'm':
     51             return (timeDigits * (30.437 * 24 * 60 * 60)).toFixed(0) * 1000;
     52         case 'y':
     53             return (timeDigits * (365.25 * 24 * 60 * 60)).toFixed(0) * 1000;
     54         case 'l':
     55             console.warn("This path should not happen, this warning is an error in logic")
     56     }
     57 }
     58 
     59 export default class TokenChart {
     60     constructor() {
     61         this._context = document.getElementById("token-chart").getContext('2d');
     62         this._chartActive = false;
     63         this._lastDatum = null;
     64         this._highDatum = null;
     65         this._lowDatum = null;
     66         this._lateUpdate = false;
     67     }
     68 
     69     get highDatum() {
     70         return this._highDatum;
     71     }
     72 
     73     get lowDatum() {
     74         return this._lowDatum;
     75     }
     76 
     77     async #newChart(chartConfig) {
     78         this._chart = new Chart(this._context, chartConfig);
     79     }
     80 
     81     async #updateHighLow(datum) {
     82         if (this._highDatum === null) {
     83             this._highDatum = new Datum(datum.getTime(), 0);
     84             this._lowDatum = datum;
     85             return;
     86         }
     87         if (datum.getPrice() > this._highDatum.getPrice()) {
     88             this._highDatum = datum;
     89             updateHighVal(this.highDatum);
     90         }
     91         else if (datum.getPrice() < this._lowDatum.getPrice()) {
     92             this._lowDatum = datum;
     93             updateLowVal(this.lowDatum);
     94         }
     95     }
     96 
     97     async #createOverlayChart(region, time, yLevel, data){
     98         const chartData = [];
     99         const overlayData = [];
    100         const overlayDelta = timeDeltaInMilliseconds(time);
    101 
    102         for (let i = 0; i < data.length; i++) {
    103             const originalDate = data[i].getX();
    104             if (i < (data.length / 2)) {
    105                 overlayData.push({
    106                     x: new Date(originalDate.getTime() + overlayDelta),
    107                     y: data[i].getY(),
    108                 });
    109             }
    110             else {
    111                 await this.#updateHighLow(data[i]);
    112 
    113                 chartData.push({
    114                     x: data[i].getX(),
    115                     y: data[i].getY(),
    116                 })
    117             }
    118         }
    119 
    120         const chartConfig = {
    121             type: 'line',
    122             data: {
    123                 datasets: [
    124                     {
    125                         borderColor: 'gold',
    126                         label: region.toUpperCase() + " WoW Token Price",
    127                         data: chartData,
    128                         cubicInterpolationMode: 'monotone',
    129                         pointRadius: 0
    130                     },
    131                     {
    132                         borderColor: 'red',
    133                         label: `Previous ${getOverlayTime()} ${region.toUpperCase()} WoW Token Price`,
    134                         data: overlayData,
    135                         cubicInterpolationMode: 'monotone',
    136                         pointRadius: 0
    137                     }
    138                 ]
    139             },
    140             options: {
    141                 interaction: {
    142                     intersect: false,
    143                     mode: "index"
    144                 },
    145                 scales: {
    146                     x: {
    147                         type: 'time',
    148                         grid: {
    149                             color: '#625f62',
    150                         },
    151                         ticks: {
    152                             color: '#a7a4ab',
    153                             font: {
    154                                 size: 18,
    155                             }
    156                         },
    157                         time: {
    158                             unit: lookupTimeUnit(time)
    159                         }
    160                     },
    161                     y: {
    162                         beginAtZero: yLevel,
    163                         grid: {
    164                             color: '#2f2c2f',
    165                         },
    166                         ticks: {
    167                             color: '#a7a4ab',
    168                             font: {
    169                                 size: 18,
    170                             }
    171                         }
    172                     }
    173                 },
    174             }
    175         }
    176 
    177         await this.#newChart(chartConfig)
    178     }
    179 
    180     async #createNormalChart(region, time, yLevel, data) {
    181         const chartData = [];
    182 
    183 
    184         for (let i = 0; i < data.length; i++) {
    185             this._lastDatum = data[i];
    186             await this.#updateHighLow(data[i]);
    187 
    188             chartData.push({
    189                 x: data[i].getX(),
    190                 y: data[i].getY(),
    191             })
    192         }
    193 
    194         const chartConfig = {
    195             type: 'line',
    196             data: {
    197                 datasets: [{
    198                     borderColor: 'gold',
    199                     label: region.toUpperCase() + " WoW Token Price",
    200                     data: chartData,
    201                     cubicInterpolationMode: 'monotone',
    202                     pointRadius: 0
    203                 }]
    204             },
    205             options: {
    206                 interaction: {
    207                     intersect: false,
    208                     mode: "index"
    209                 },
    210                 scales: {
    211                     x: {
    212                         type: 'time',
    213                         grid: {
    214                             color: '#625f62',
    215                         },
    216                         ticks: {
    217                             color: '#a7a4ab',
    218                             font: {
    219                                 size: 18,
    220                             }
    221                         },
    222                         time: {
    223                             unit: lookupTimeUnit(time)
    224                         }
    225                     },
    226                     y: {
    227                         beginAtZero: yLevel,
    228                         grid: {
    229                             color: '#2f2c2f',
    230                         },
    231                         ticks: {
    232                             color: '#a7a4ab',
    233                             font: {
    234                                 size: 18,
    235                             }
    236                         }
    237                     }
    238                 },
    239             }
    240         }
    241 
    242         await this.#newChart(chartConfig)
    243     }
    244 
    245     async createChart(region, time, yLevel, data) {
    246         let lateUpdateData = this._lastDatum;
    247 
    248         if (isOverlaySelected()) {
    249             await this.#createOverlayChart(region, time, yLevel, data)
    250         }
    251         else {
    252             await this.#createNormalChart(region, time, yLevel, data)
    253         }
    254 
    255         setOverlayLabelTime();
    256 
    257         updateHighVal(this.highDatum);
    258         updateLowVal(this.lowDatum);
    259 
    260         if (this._lateUpdate) {
    261             if (this._lastDatum.getPrice() !== lateUpdateData.getPrice() &&
    262                 this._lastDatum.getTime() < lateUpdateData.getTime()) {
    263                 await this.addDataToChart(lateUpdateData);
    264             }
    265             this._lateUpdate = false
    266         }
    267 
    268         this._chartActive = true;
    269     }
    270 
    271     async destroyChart() {
    272         await this._chart.destroy();
    273         this._chartActive = false;
    274         this._lastDatum = null;
    275         this._highDatum = null;
    276         this._lowDatum = null;
    277         this._lateUpdate = false;
    278     }
    279 
    280     async lateUpdate(datum){
    281         this._lastDatum = datum;
    282         this._lateUpdate = true;
    283     }
    284 
    285     async addDataToChart(datum) {
    286         this._lastDatum = datum;
    287         if (datum.getPrice() > this._highDatum.getPrice()) {
    288             this._highDatum = datum;
    289             updateHighVal(this.highDatum);
    290         }
    291         else if (datum.getPrice() < this._lowDatum.getPrice()) {
    292             this._lowDatum = datum;
    293             updateLowVal(this.lowDatum);
    294         }
    295         this._chart.data.datasets[0].data.push({
    296             x: datum.getX(),
    297             y: datum.getY(),
    298         });
    299         this._chart.update();
    300     }
    301 
    302     active() {
    303         return this._chartActive;
    304     }
    305 
    306     toggleYStart(startYAtZero) {
    307         this._chart.options.scales.y.beginAtZero = startYAtZero;
    308         this._chart.update();
    309     }
    310 
    311 }