From ea096512fe36d87481922840be726de73ca7a2fc Mon Sep 17 00:00:00 2001 From: Stefan Lau Date: Sun, 6 Apr 2014 16:08:19 +0200 Subject: [PATCH] add charts to revenue modules --- frontend/stylesheets/style.styl | 27 ++++--- lib/modules/revenue/solo.js | 10 ++- lib/modules/revenue/triplemining.js | 9 ++- lib/views/revenue.js | 79 ++++++++++++++++++- templates/revenue.hbs | 12 ++- test/specs/lib/modules/revenue/soloSpec.js | 21 +++-- .../lib/modules/revenue/tripleminingSpec.js | 19 ++++- 7 files changed, 149 insertions(+), 28 deletions(-) diff --git a/frontend/stylesheets/style.styl b/frontend/stylesheets/style.styl index f364c18..ea85228 100644 --- a/frontend/stylesheets/style.styl +++ b/frontend/stylesheets/style.styl @@ -17,6 +17,19 @@ a dt font-weight: normal +.graph-element + position: relative + .graph + height: 120px + margin-bottom: 20px + strong + position: absolute + left: 20px + top: 5px + opacity: 1 + &:hover strong + opacity: 0 + #modules section position: relative @@ -39,16 +52,7 @@ dt font-size: 10px .miner .hashrate - position: relative - .graph - height: 120px - strong - position: absolute - left: 20px - top: 5px - opacity: 1 - &:hover strong - opacity: 0 + @extend .graph-element .devices margin-bottom: 20px table @@ -60,3 +64,6 @@ dt width: 10% &:nth-child(3) width: 30% + .revenue + .value + @extend .graph-element diff --git a/lib/modules/revenue/solo.js b/lib/modules/revenue/solo.js index b47b47f..08d09bd 100644 --- a/lib/modules/revenue/solo.js +++ b/lib/modules/revenue/solo.js @@ -2,12 +2,18 @@ var _ = require('lodash'), + setWithHistoricalData = require('../../utils/setWithHistoricalData'), Module = require('../../Module'); module.exports = Module.extend({ viewId: 'revenue', + defaults: { + chartTimespan: 14 * 24 * 60 * 60 * 1000, + chartPrecision: 60 * 60 * 1000 + }, + initialize: function () { var self = this, miner = self.config.miner; @@ -62,6 +68,8 @@ module.exports = Module.extend({ currency: currency, interval: 'Day' }); - } + }, + + set: setWithHistoricalData([ 'value' ], Module.prototype.set) }); \ No newline at end of file diff --git a/lib/modules/revenue/triplemining.js b/lib/modules/revenue/triplemining.js index 4e663a9..d0ee98b 100644 --- a/lib/modules/revenue/triplemining.js +++ b/lib/modules/revenue/triplemining.js @@ -4,6 +4,7 @@ var async = require('async'), request = require('request'), _ = require('lodash'), + setWithHistoricalData = require('../../utils/setWithHistoricalData'), Module = require('../../Module'); module.exports = Module.extend({ @@ -11,7 +12,9 @@ module.exports = Module.extend({ viewId: 'revenue', defaults: { - interval: 3600000 + interval: 3600000, + chartTimespan: 14 * 24 * 60 * 60 * 1000, + chartPrecision: 60 * 60 * 1000 }, initialize: function () { @@ -99,6 +102,8 @@ module.exports = Module.extend({ value: this.tripleminingData.hashrate * 1e6 * this.technicalData.probability * this.tripleminingData.estimatedPayout * bid * 24 * 3600, interval: 'Day' }); - } + }, + + set: setWithHistoricalData([ 'value' ], Module.prototype.set) }); \ No newline at end of file diff --git a/lib/views/revenue.js b/lib/views/revenue.js index 8a955ec..0f5857a 100644 --- a/lib/views/revenue.js +++ b/lib/views/revenue.js @@ -1,7 +1,82 @@ 'use strict'; -var View = require('../View'); +var Rickshaw = require('rickshaw'), + _ = require('lodash'), + timeHelper = require('../handlebars/helpers/time'), + + View = require('../View'); module.exports = View.extend({ - template: 'revenue' + template: 'revenue', + + graph: null, + + getChartData: function () { + return this.module.get('historicalData').map(function (measurement) { + return { + x: (measurement.timestamp / 1000), + y: measurement.value + }; + }); + }, + + initializeGraph: function () { + var module = this.module; + + this.graph = new Rickshaw.Graph({ + element: this.$('.graph')[0], + height: 120, + renderer: 'area', + interpolation: 'linear', + stroke: true, + series: [ + { + color: '#cae2f7', + name: 'Revenue', + data: this.getChartData() + } + ] + }); + this.detail = new Rickshaw.Graph.HoverDetail({ + graph: this.graph, + yFormatter: function (value) { + return value.toFixed(5) + ' ' + module.get('currency'); + }, + xFormatter: function (value) { + return timeHelper(value * 1000); + } + }); + this.xAxis = new Rickshaw.Graph.Axis.Time({ + graph: this.graph + }); + this.yAxis = new Rickshaw.Graph.Axis.Y({ + graph: this.graph + }); + }, + + updateGraph: function () { + var chartData = this.getChartData(); + + this.graph.min = _(chartData).pluck('y').min().value() * 0.99; + this.graph.max = _(chartData).pluck('y').max().value() * 1.01; + this.graph.series[0].data = this.getChartData(); + + this.xAxis.render(); + this.yAxis.render(); + this.graph.update(); + }, + + postRender: function () { + var graphElement = this.$('.graph'), + graphShouldBeRendered = graphElement.length > 0 && this.module.get('historicalData'); + + if (graphShouldBeRendered) { + if (this.graph) { + graphElement.replaceWith(this.graph.element); + } else { + this.initializeGraph(); + } + this.updateGraph(); + } + } }); \ No newline at end of file diff --git a/templates/revenue.hbs b/templates/revenue.hbs index f17f477..50e6e84 100644 --- a/templates/revenue.hbs +++ b/templates/revenue.hbs @@ -3,8 +3,12 @@

{{ title }}

-
-
Revenue:
-
{{number value}} {{currency}}/{{interval}}
-
+
+
+
+
+ Current Revenue: {{number value}} {{currency}}/{{interval}} +
+
+
\ No newline at end of file diff --git a/test/specs/lib/modules/revenue/soloSpec.js b/test/specs/lib/modules/revenue/soloSpec.js index 9b429f1..d79b333 100644 --- a/test/specs/lib/modules/revenue/soloSpec.js +++ b/test/specs/lib/modules/revenue/soloSpec.js @@ -4,6 +4,7 @@ var EventEmitter = require('events').EventEmitter, chai = require('chai'), expect = chai.expect, + _ = require('lodash'), Solo = require('../../../../../lib/modules/revenue/solo'); @@ -33,7 +34,7 @@ describe('modules/revenue/solo', function () { solo.technicalData = { btcPerBlock: 10, probability: 0.0001 }; solo.on('change', function () { - expect(solo.toJSON()).to.deep.equal({ + expect(_.omit(solo.toJSON(), 'historicalData')).to.deep.equal({ value: 8640, currency: 'NMC', interval: 'Day' @@ -51,7 +52,7 @@ describe('modules/revenue/solo', function () { solo.technicalData = { btcPerBlock: 10, probability: 0.0001 }; solo.on('change', function () { - expect(solo.toJSON()).to.deep.equal({ + expect(_.omit(solo.toJSON(), 'historicalData')).to.deep.equal({ value: 0, currency: 'NMC', interval: 'Day' @@ -69,7 +70,7 @@ describe('modules/revenue/solo', function () { solo.technicalData = { btcPerBlock: 10, probability: 0.0001 }; solo.on('change', function () { - expect(solo.toJSON()).to.deep.equal({ + expect(_.omit(solo.toJSON(), 'historicalData')).to.deep.equal({ value: 8640, currency: 'NMC', interval: 'Day' @@ -89,7 +90,7 @@ describe('modules/revenue/solo', function () { solo.technicalData = { btcPerBlock: 10, probability: 0.0001 }; solo.on('change', function () { - expect(solo.toJSON()).to.deep.equal({ + expect(_.omit(solo.toJSON(), 'historicalData')).to.deep.equal({ value: 86.4, currency: 'BTC', interval: 'Day' @@ -107,7 +108,7 @@ describe('modules/revenue/solo', function () { solo.marketData = { ask: 100, currency: 'NMC' }; solo.on('change', function () { - expect(solo.toJSON()).to.deep.equal({ + expect(_.omit(solo.toJSON(), 'historicalData')).to.deep.equal({ value: 8640, currency: 'NMC', interval: 'Day' @@ -130,4 +131,14 @@ describe('modules/revenue/solo', function () { expect(solo.title).to.equal('Some Title'); }); + it('should add the values to historicalData', function () { + var solo = new Solo(this.app, {}), + now = new Date().getTime(); + + solo.set({ currency: 'BTC', value: 123, interval: 'Day' }); + expect(solo.get('historicalData')).to.have.length(1); + expect(solo.get('historicalData')[0].value).to.equal(123); + expect(solo.get('historicalData')[0].timestamp).to.be.within(now-1, now+1); + }); + }); \ No newline at end of file diff --git a/test/specs/lib/modules/revenue/tripleminingSpec.js b/test/specs/lib/modules/revenue/tripleminingSpec.js index e9b494f..5d00dee 100644 --- a/test/specs/lib/modules/revenue/tripleminingSpec.js +++ b/test/specs/lib/modules/revenue/tripleminingSpec.js @@ -54,7 +54,7 @@ describe('modules/revenue/triplemining', function () { triplemining.marketData = marketData; triplemining.on('change', function () { - expect(triplemining.toJSON()).to.deep.equal({ + expect(_.omit(triplemining.toJSON(), 'historicalData')).to.deep.equal({ value: 2073600000 * 1e6, currency: 'NMC', interval: 'Day' @@ -71,7 +71,7 @@ describe('modules/revenue/triplemining', function () { setTimeout(function () { triplemining.on('change', function () { - expect(triplemining.toJSON()).to.deep.equal({ + expect(_.omit(triplemining.toJSON(), 'historicalData')).to.deep.equal({ value: 2073600000 * 1e6, currency: 'NMC', interval: 'Day' @@ -91,7 +91,7 @@ describe('modules/revenue/triplemining', function () { setTimeout(function () { triplemining.on('change', function () { - expect(triplemining.toJSON()).to.deep.equal({ + expect(_.omit(triplemining.toJSON(), 'historicalData')).to.deep.equal({ value: 2073600000 * 1e6, currency: 'NMC', interval: 'Day' @@ -109,7 +109,7 @@ describe('modules/revenue/triplemining', function () { triplemining.technicalData = technicalData; triplemining.on('change', function () { - expect(triplemining.toJSON()).to.deep.equal({ + expect(_.omit(triplemining.toJSON(), 'historicalData')).to.deep.equal({ value: 1036800000 * 1e6, currency: 'BTC', interval: 'Day' @@ -173,4 +173,15 @@ describe('modules/revenue/triplemining', function () { expect(triplemining.title).to.equal('Some Title'); }); + it('should add the values to historicalData', function () { + var app = new EventEmitter(), + triplemining = new Triplemining(app), + now = new Date().getTime(); + + triplemining.set({ currency: 'BTC', value: 123, interval: 'Day' }); + expect(triplemining.get('historicalData')).to.have.length(1); + expect(triplemining.get('historicalData')[0].value).to.equal(123); + expect(triplemining.get('historicalData')[0].timestamp).to.be.within(now-1, now+1); + }); + }); \ No newline at end of file