monetaryMass2.ts 9.58 KB
Newer Older
1
import {DataFinder} from "../lib/DataFinder";
2
import {MonitConstants} from "../lib/constants2";
3

Thomas Di Grégorio's avatar
Thomas Di Grégorio committed
4
const co = require('co')
5
const timestampToDatetime = require(__dirname + '/../lib/timestampToDatetime')
6
const getLang = require(__dirname + '/../lib/getLang')
Thomas Di Grégorio's avatar
Thomas Di Grégorio committed
7

8
module.exports = async (req:any, res:any, next:any) => {
Thomas Di Grégorio's avatar
Thomas Di Grégorio committed
9
  
Éloïs's avatar
Éloïs committed
10
  var { duniterServer  } = req.app.locals
11
12

  const dataFinder = new DataFinder(duniterServer)
Thomas Di Grégorio's avatar
Thomas Di Grégorio committed
13
14
15
  
  try {
    // get GET parameters
16
17
18
    var begin = req.query.begin >= 2 && req.query.begin || 2; // Default Value
    var end = req.query.end || -1; // Default Value is current timestamp
    var unit = req.query.unit || 'relative';
19
    var format = req.query.format || 'HTML';
20

21
    // get lg file
22
    const LANG = getLang(`${__dirname}/../lg/monetaryMass_${req.query.lg||MonitConstants.DEFAULT_LANGUAGE}.txt`);
23
24

    // calculate meanMonetaryMassAtFullCurrency
25
    const meanMonetaryMassAtFullCurrency = Math.ceil((1/duniterServer.conf.c)*(duniterServer.conf.dtReeval / duniterServer.conf.dt));
Thomas Di Grégorio's avatar
Thomas Di Grégorio committed
26
27
    
    // get beginBlock and endBlock
28
    var beginBlock = [await dataFinder.getBlock(begin)];
29
    var endBlock: any = null;
30
31
    if (end > 0)
    {
32
      endBlock = [await dataFinder.getBlock(end)];
33
34
      if ( typeof(endBlock[0]) == 'undefined')
      {
35
	endBlock = [await dataFinder.getCurrentBlockOrNull()];
36
37
38
39
40
	end = endBlock[0].number;
      }
    }
    else
    {
41
      endBlock = [await dataFinder.getCurrentBlockOrNull()];
42
    }
Thomas Di Grégorio's avatar
Thomas Di Grégorio committed
43
44
45
46
    
    // get blockchain
    if (end >= begin && begin >= 1)
    {
47
      var blockchain = await dataFinder.getBlockWhereMedianTimeLteAndGteNoLimit(endBlock[0].medianTime, (beginBlock[0] as any).medianTime);
Thomas Di Grégorio's avatar
Thomas Di Grégorio committed
48
49
50
    }
    else
    {
51
      var blockchain = await dataFinder.getBlockWhereMedianTimeGtNoLimit((beginBlock[0] as any).medianTime);
Thomas Di Grégorio's avatar
Thomas Di Grégorio committed
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
    }
    
    // get blockchain timestamp
    const currentBlockNumber = begin+blockchain.length-1;
    const currentBlockchainTimestamp = blockchain[blockchain.length-1].medianTime;
    if (end == -1) { end = begin+blockchain.length-1; }
    
    // create and fill tabMembersCount, tabMonetaryMass, tabCurrency and currentDividend
    var tabCurrency = [];
    var currentDividend = 0;
    let previousMonetaryMass = 0;
    for (let b=0;b<blockchain.length;b++)
    {
      if (blockchain[b].monetaryMass != previousMonetaryMass)
      {
        tabCurrency.push({
          blockNumber: blockchain[b].number,
          timestamp: blockchain[b].medianTime,
70
          dateTime: timestampToDatetime(blockchain[b].medianTime, true),
Thomas Di Grégorio's avatar
Thomas Di Grégorio committed
71
          membersCount: blockchain[b].membersCount,
72
          monetaryMass: blockchain[b].monetaryMass / 100,
73
          monetaryMassPerMembers: parseFloat(((blockchain[b].monetaryMass / 100) / blockchain[b].membersCount).toFixed(2)),
74
          derivedChoiceMonetaryMass: 0
Thomas Di Grégorio's avatar
Thomas Di Grégorio committed
75
76
77
78
79
80
81
82
83
84
        });
      
        if ( blockchain[b].dividend > 0 )
        {
          currentDividend = blockchain[b].dividend;
        }
        previousMonetaryMass = blockchain[b].monetaryMass;
      }
    }
    
85
    // calculate choiceMonetaryMass and derivedChoiceMonetaryMass
Thomas Di Grégorio's avatar
Thomas Di Grégorio committed
86
87
    for (let i=0;i<tabCurrency.length;i++)
    {
88
89
90
91
92
93
94
95
96
97
98
      if (unit == "relative")
      {
        tabCurrency[i].monetaryMass = parseFloat(((tabCurrency[i].monetaryMass / currentDividend) * 100).toFixed(2));
        tabCurrency[i].monetaryMassPerMembers = parseFloat(((tabCurrency[i].monetaryMassPerMembers / currentDividend) * 100).toFixed(2));
      }
      else if  (unit == "percentOfFullCurrency")
      {
        tabCurrency[i].monetaryMass = parseFloat((((tabCurrency[i].monetaryMassPerMembers / currentDividend) / meanMonetaryMassAtFullCurrency) * 10000).toFixed(2));
        tabCurrency[i].monetaryMassPerMembers = tabCurrency[i].monetaryMass;
      }
      if (i>0) { tabCurrency[i].derivedChoiceMonetaryMass = parseFloat((((tabCurrency[i].monetaryMass / tabCurrency[i-1].monetaryMass) - 1.0) * 100).toFixed(2)); }
Thomas Di Grégorio's avatar
Thomas Di Grégorio committed
99
100
    }
    
101
    // Si le client demande la réponse au format JSON, le faire
Thomas Di Grégorio's avatar
Thomas Di Grégorio committed
102
103
104
105
106
    if (format == 'JSON')
      res.status(200).jsonp( tabCurrency )
    else
    {
      // GET parameters
107
108
109
110
      var massByMembers = req.query.massByMembers == 'no' && unit != "percentOfFullCurrency" ? 'no' : 'yes';
      var type = req.query.type || 'logarithmic';
      if (unit == "percentOfFullCurrency") { type = 'linear'; }
      if (type != 'linear') { type = 'logarithmic'; }
111
112
    
      // Define full currency description
113
114
115
116
      var fullCurrency = LANG['DESC1']+" <b>"+meanMonetaryMassAtFullCurrency
	  +" "+LANG['UD']+"</b> ("+LANG['FULL_CURRENCY_FORMULA']+" = <b>"+meanMonetaryMassAtFullCurrency+" "+LANG['UD']+"</b>)<br>"
	  +LANG['CURRENTLY']+", 1 "+LANG['UD']+"<sub>"+duniterServer.conf.currency+"</sub> = <b>"+(currentDividend/100)+"</b> "+duniterServer.conf.currency+" "+LANG['AND_WE_HAVE']+" <b>"
	  +endBlock[0].membersCount+"</b> "+LANG['DESC2']+" <b>"
117
	  +(meanMonetaryMassAtFullCurrency*currentDividend*endBlock[0].membersCount/100)+"</b> "+duniterServer.conf.currency
118
	  +" (<b>"+(meanMonetaryMassAtFullCurrency*currentDividend/100)+"</b> "+duniterServer.conf.currency+"/"+LANG['MEMBER']+")." ;
Éloïs's avatar
Éloïs committed
119
120
121
	  
      // Define max yAxes
      var maxYAxes = meanMonetaryMassAtFullCurrency;
122
      let indexEnd = tabCurrency.length-1;
Éloïs's avatar
Éloïs committed
123
      if (unit == "quantitative") { maxYAxes = maxYAxes*currentDividend/100; }
124
125
      if (unit == "percentOfFullCurrency") { maxYAxes = 100; }
      else if (massByMembers == "no") { maxYAxes = maxYAxes*endBlock[0].membersCount; }
Thomas Di Grégorio's avatar
Thomas Di Grégorio committed
126
127
      
      res.locals = {
128
129
130
131
132
133
134
135
	      host: req.headers.host.toString(),
        tabCurrency,
	      currentDividend,
        begin, 
        end,
        unit,
        massByMembers,
	      type,
136
137
138
139
        form: `${LANG['BEGIN']} #<input type="number" name="begin" value="${begin}"> - ${LANG['END']} #<input type="number" name="end" value="${end}"> <select name="unit">
            <option name="unit" value ="quantitative">${LANG['QUANTITATIVE']}
            <option name="unit" value ="relative" ${unit == 'relative' ? 'selected' : ''}>${LANG['RELATIVE']}
            <option name="unit" value ="percentOfFullCurrency" ${unit == 'percentOfFullCurrency' ? 'selected' : ''}>${LANG['PERCENT_OF_FULL_CURRENCY']}
140
          </select> <select name="massByMembers">
141
142
            <option name="massByMembers" value ="yes">${LANG['MASS_BY_MEMBERS']}
            <option name="massByMembers" value ="no" ${massByMembers == 'no' ? 'selected' : ''}>${LANG['TOTAL_MASS']}
143
          </select> <select name="type">
144
145
            <option name="type" value ="logarithmic">${LANG['LOGARITHMIC']}
            <option name="type" value ="linear" ${type == 'linear' ? 'selected' : ''}>${LANG['LINEAR']}
146
147
          </select>`,
	      description: `${fullCurrency}`,
Thomas Di Grégorio's avatar
Thomas Di Grégorio committed
148
149
150
151
        chart: {
          type: 'bar',
          data: {
            labels: tabCurrency.map( item=> item.dateTime ),
152
            //yLabels: tabCurrency.map( item=> item.monetaryMass, item=>derivedChoiceMonetaryMass),
Thomas Di Grégorio's avatar
Thomas Di Grégorio committed
153
            datasets: [{
154
              //yAxisID: 1,
155
              label: `${unit == "percentOfFullCurrency" ? `${LANG['MONETARY_MASS']} (${LANG['IN_PERCENT_OF_FULL_CURRENCY']})`:`#${unit == "relative" ? LANG['UD']+"ğ1" : 'Ğ1'}${massByMembers == "yes" ? '/'+LANG['MEMBER'] : ''}`}`,
156
              data: tabCurrency.map( item=>
Thomas Di Grégorio's avatar
Thomas Di Grégorio committed
157
158
                    massByMembers == "no" 
                    ? item.monetaryMass 
159
                    : item.monetaryMassPerMembers),
Thomas Di Grégorio's avatar
Thomas Di Grégorio committed
160
161
162
              backgroundColor: 'rgba(54, 162, 235, 0.5)',
              borderColor: 'rgba(54, 162, 235, 1)',
              borderWidth: 1
163
164
165
            },
            {
              //yAxisID: 2,
166
              label: LANG['PERCENT_VARIATION_MONETARY_MASS'],
167
168
169
170
171
172
              data: tabCurrency.map( item=> item.derivedChoiceMonetaryMass),
              backgroundColor: 'rgba(0, 162, 0, 0.5)',
              borderColor: 'rgba(0, 162, 0, 1)',
              borderWidth: 1,
              type: 'line',
              fill: false
Thomas Di Grégorio's avatar
Thomas Di Grégorio committed
173
174
175
176
177
178
179
180
181
182
183
            }]
          },
          options: {
            // plugins: {
            //   afterDraw: function (chart, easing) {
            //     var self = chart.config;    /* Configuration object containing type, data, options */
            //     var ctx = chart.chart.ctx;  /* Canvas context used to draw with */
            //   }
            // },
            title: {
              display: true,
184
              text: `${unit == "percentOfFullCurrency" ? LANG['MONETARY_MASS']+' '+LANG['IN_PERCENT_OF_FULL_CURRENCY']:`${unit == "relative" ? LANG['UD']+"ğ1 " : 'Ğ1 '} ${massByMembers == "yes" ? LANG['BY_MEMBER']: ''}`} ${LANG['IN_THE_RANGE']} #${begin}-#${end  }`
Thomas Di Grégorio's avatar
Thomas Di Grégorio committed
185
186
            },
            legend: {
187
              display: true
Thomas Di Grégorio's avatar
Thomas Di Grégorio committed
188
189
190
            },
            scales: {
              yAxes: [{
191
192
                //yAxisID: 1,
		            type: type,
193
                position: 'left',
Thomas Di Grégorio's avatar
Thomas Di Grégorio committed
194
                ticks: {
195
                    callback: function(value:any, index:any, values:any) {//needed to change the scientific notation results from using logarithmic scale
196
197
198
199
200
201
202
203
204
205
206
207
208
                            return Number(value.toString()); //pass tick values as a string into Number function
                    },
                    max: maxYAxes,
                }
              }/*,
              {
                //yAxisID: 2,
		            type: type,
                position: 'right',
                ticks: {
                    callback: function(value, index, values) {//needed to change the scientific notation results from using logarithmic scale
                            return Number(value.toString()); //pass tick values as a string into Number function
                    }
Thomas Di Grégorio's avatar
Thomas Di Grégorio committed
209
                }
210
              }*/]
Thomas Di Grégorio's avatar
Thomas Di Grégorio committed
211
212
213
214
215
216
217
218
219
220
221
            }
          }
        }
      }
      next()
    }
    
  } catch (e) {
    // En cas d'exception, afficher le message
    res.status(500).send(`<pre>${e.stack || e.message}</pre>`);
  }
222
}