Skip to content

Commit

Permalink
Close #48: make revenue module more flexible, introduce new config fo…
Browse files Browse the repository at this point in the history
…rmat
  • Loading branch information
selaux committed Jun 13, 2014
1 parent 297152e commit ff3fd37
Show file tree
Hide file tree
Showing 4 changed files with 313 additions and 96 deletions.
113 changes: 74 additions & 39 deletions lib/modules/revenue/solo.js
Expand Up @@ -10,66 +10,101 @@ module.exports = Module.extend({
viewId: 'revenue',

defaults: {
miners: [],
chartTimespan: 14 * 24 * 60 * 60 * 1000,
chartPrecision: 60 * 60 * 1000
},

initialize: function () {
var self = this,
miner = self.config.miner;
attributesToSave = _.pluck(self.config.miners, function (revConfig) {
return 'revenue.' + revConfig.miner;
});

this.title = this.config.title || 'Revenue';
self.set = setWithHistoricalData(attributesToSave, Module.prototype.set);

self.config.miner = _.isArray(miner) ? miner : [ miner ];
self.title = self.config.title || 'Revenue';
self.minerData = {};

self.app.on('update:data:' + self.config.technical, function (data) {
self.technicalData = data;
self.calculateRevenue();
});

if (self.config.market) {
self.app.on('update:data:' + self.config.market, function (data) {
self.marketData = data;
self.calculateRevenue();
if (self.config.miner) {
self.app.logger.warn('%s - The configuration format you are using for solo revenue is deprecated and will be removed soon. Please take a look at the documentation for the new format.', self.id);
self.config.miners = _.map(_.isArray(self.config.miner) ? self.config.miner : [ self.config.miner ], function (minerId) {
return {
miner: minerId,
technical: self.config.technical,
market: self.config.market
};
});
delete self.config.miner;
delete self.config.technical;
delete self.config.market;
}

self.config.miner.forEach(function (miner) {
self.app.on('update:data:' + miner, function (data) {
self.minerData[miner] = data;
self.config.miners.forEach(function (miner) {
self.minerData[miner.miner] = {};

self.app.on('update:data:' + miner.miner, function (data) {
self.minerData[miner.miner].averageHashrate = data.averageHashrate || 0;
self.calculateRevenue();
});
self.app.on('update:data:' + miner.technical, function (data) {
self.minerData[miner.miner].probability = data.probability;
self.minerData[miner.miner].blockReward = data.blockReward;
self.minerData[miner.miner].coin = data.coin;
self.calculateRevenue();
});
if (miner.market) {
self.app.on('update:data:' + miner.market, function (data) {
self.minerData[miner.miner].price = data.close;
self.minerData[miner.miner].currency = data.currency;
self.calculateRevenue();
});
}
});
},

calculateRevenue: function () {
var self = this,
currency,
close,
totalHashrate;

if (!this.technicalData) {
return;
}
if (this.config.market && !this.marketData) {
return;
}
if (_.any(this.config.miner, function (miner) { return !_.has(self.minerData, miner); })) {
return;
}

totalHashrate = _.reduce(this.minerData, function (sum, miner) { return sum + (miner.averageHashrate || 0); }, 0);
close = this.config.market ? this.marketData.close : 1;
currency = this.config.market ? this.marketData.currency : this.technicalData.coin;

this.set({
value: this.technicalData.blockReward * (24 * 60 * 60) * totalHashrate * 1e6 * this.technicalData.probability * close,
currency: currency,
interval: 'Day'
minerData = self.minerData,
minerTitles = {},
data = {
value: 0,
interval: 'Day'
};

var allDataAvailable = true;
_.each(self.config.miners, function (minerConfig) {
var minerId = minerConfig.miner,
module = _.find(self.app.modules, function (mod) { return mod.id === minerId; }),
price = minerConfig.market ? minerData[minerId].price : 1,
currency = minerConfig.market ? minerData[minerId].currency : minerData[minerId].coin,
revenue;

minerTitles[minerId] = module ? module.title : minerId;

allDataAvailable = allDataAvailable &&
minerData[minerId].averageHashrate !== undefined &&
minerData[minerId].probability !== undefined &&
(!minerConfig.market || minerData[minerId].price !== undefined);
if (!allDataAvailable) {
return false;
}

if (data.currency !== undefined && currency !== data.currency) {
self.app.logger.warn('%s - Trying to accumulate different currencies for solo revenue: %s vs %s', self.id, currency, data.currency);
} else {
data.currency = currency;
}
revenue = minerData[minerId].blockReward * (24 * 60 * 60) * minerData[minerId].averageHashrate * 1e6 * minerData[minerId].probability * price;

data['revenue.' + minerId] = revenue;
data.value += revenue;
});
},

set: setWithHistoricalData([ 'value' ], Module.prototype.set)
data.minerTitles = minerTitles;
if (allDataAvailable) {
this.set(data);
}
}

});
8 changes: 5 additions & 3 deletions lib/views/mixins/renderHistoricalDataGraph.js
Expand Up @@ -81,10 +81,12 @@ module.exports = function (attributes, element, graphOptions, hoverOptions) {
},

updateGraph: function () {
var series = this.getSeries();
var series = this.getSeries(),
min = this.graph.config.stack ? 0 : _.min(getValueRange(series, this.graph.config.stack)),
max = _.max(getValueRange(series, this.graph.config.stack));

this.graph.min = (this.graph.config.stack ? 0 : _.min(getValueRange(series, this.graph.config.stack))) *0.99;
this.graph.max = _.max(getValueRange(series, this.graph.config.stack)) * 1.01;
this.graph.min = min * 0.99;
this.graph.max = max * (this.graph.config.stack ? 1.1 : 1.01);
_.each(this.graph.series, function (graphSeries, index) {
graphSeries.data = series[index].data;
});
Expand Down
54 changes: 43 additions & 11 deletions lib/views/revenue.js
@@ -1,17 +1,49 @@
'use strict';

var renderHistoricalDataGraph = require('./mixins/renderHistoricalDataGraph'),
var _ = require('lodash'),
numberHelper = require('../handlebars/helpers/number'),
renderHistoricalDataGraph = require('./mixins/renderHistoricalDataGraph'),

View = require('../View'),
graphMixin = renderHistoricalDataGraph([ {
attr: 'value',
name: 'Revenue'
} ], '.graph', {}, {
yFormatter: function (value) {
return value.toFixed(5) + ' ' + this.module.get('currency');
}
});
View = require('../View');

module.exports = View.extend({
postRender: function () {
var self = this,
colors = [ '#cae2f7', '#a7d2f7' ],
series,
graphMixin;

if (self.graph === undefined) {
series = _(self.module.get('historicalData'))
.map(function (val) {
return _(val)
.keys()
.filter(function (key) { return key.split('.')[0] === 'revenue'; })
.map(function (key) { return key.split('.')[1]; })
.value();
})
.flatten()
.unique()
.map(function (minerId, it) {
return {
attr: 'revenue.' + minerId,
name: self.module.get('minerTitles')[minerId],
color: colors[it % colors.length]
};
})
.value();
graphMixin = renderHistoricalDataGraph(series, '.graph', {
stack: true
}, {
yFormatter: function (value) {
return numberHelper(value);
}
});

_.extend(this, graphMixin);
this.postRender();
}
},

template: 'revenue'
}).extend(graphMixin);
});

0 comments on commit ff3fd37

Please sign in to comment.