Merge pull request #92 from cubedro/develop

Improvements & fixes
This commit is contained in:
Marian OANCΞA 2015-04-24 03:09:12 +03:00
commit 4aa1eef586
7 changed files with 64 additions and 31 deletions

View File

@ -1,4 +1,5 @@
var _ = require('lodash'); var _ = require('lodash');
var d3 = require('d3');
var MAX_HISTORY = 1008; var MAX_HISTORY = 1008;
var MAX_PEER_PROPAGATION = 36; var MAX_PEER_PROPAGATION = 36;
@ -128,11 +129,7 @@ History.prototype.getBlockPropagation = function()
{ {
var propagation = []; var propagation = [];
var sorted = _(this._items) _.forEach(this._items, function(n, key)
.sortByOrder('height', false)
.slice(0, MAX_BLOCK_PROPAGATION)
.reverse()
.forEach(function(n, key)
{ {
_.forEach(n.propagTimes, function(p, i) _.forEach(n.propagTimes, function(p, i)
{ {
@ -141,10 +138,25 @@ History.prototype.getBlockPropagation = function()
if(prop >= 0) if(prop >= 0)
propagation.push(prop); propagation.push(prop);
}); });
}) });
.value();
return propagation; var x = d3.scale.linear()
.domain([0, 20000])
.interpolate(d3.interpolateRound);
var data = d3.layout.histogram()
.frequency(false)
.bins(x.ticks(MAX_BINS))
(propagation);
var freqCum = 0;
var histo = data.map(function(val) {
freqCum += val.length;
var cumPercent = (freqCum / Math.max(1, propagation.length));
return {x: val.x, dx: val.dx, y: val.y, frequency: val.length, cumulative: freqCum, cumpercent: cumPercent};
});
return histo;
} }
History.prototype.history = function() History.prototype.history = function()

View File

@ -12,6 +12,7 @@
}, },
"dependencies": { "dependencies": {
"body-parser": "1.12.3", "body-parser": "1.12.3",
"d3": "^3.5.5",
"debug": "2.1.3", "debug": "2.1.3",
"express": "4.12.3", "express": "4.12.3",
"geoip-lite": "1.1.6", "geoip-lite": "1.1.6",

View File

@ -184,7 +184,7 @@ div.small-title-miner {
.page-latency { .page-latency {
position: absolute; position: absolute;
top: 400px; top: 395px;
left: 15px; left: 15px;
} }
@ -239,7 +239,7 @@ table td.peerPropagationChart {
} }
.th-nodetype { .th-nodetype {
width: 200px; width: 220px;
} }
.th-latency { .th-latency {
@ -302,8 +302,7 @@ table td.peerPropagationChart {
padding: 5px 0; padding: 5px 0;
} }
.jqsfield .tooltip-arrow, .jqsfield .tooltip-arrow {
.d3-tip .tooltip-arrow {
position: absolute; position: absolute;
bottom: 0; bottom: 0;
left: 50%; left: 50%;
@ -312,7 +311,8 @@ table td.peerPropagationChart {
border-top-color: #fff; border-top-color: #fff;
} }
.datamaps-hoverover .tooltip-arrow { .datamaps-hoverover .tooltip-arrow,
.d3-tip .tooltip-arrow {
position: absolute; position: absolute;
top: -5px; top: -5px;
left: 0px; left: 0px;
@ -321,6 +321,11 @@ table td.peerPropagationChart {
border-bottom-color: #fff; border-bottom-color: #fff;
} }
.d3-tip .tooltip-arrow {
top: 0px;
left: 50%;
}
.hoverinfo { .hoverinfo {
position: relative; position: relative;
width: auto; width: auto;

View File

@ -33,7 +33,7 @@ function StatsCtrl($scope, $filter, socket, _, toastr) {
$scope.orderTable = function(predicate, reverse) $scope.orderTable = function(predicate, reverse)
{ {
if(predicate != $scope.predicate) if(!_.isEqual(predicate, $scope.predicate))
{ {
$scope.reverse = reverse; $scope.reverse = reverse;
$scope.predicate = predicate; $scope.predicate = predicate;

View File

@ -121,18 +121,15 @@ angular.module('netStatsApp.directives', []).
var tip = d3.tip() var tip = d3.tip()
.attr('class', 'd3-tip') .attr('class', 'd3-tip')
.offset([-10, 0]) .offset([10, 0])
.direction('s')
.html(function(d) { .html(function(d) {
return '<div class="tooltip-arrow"></div><div class="tooltip-inner"><b>' + (d.x/1000) + 's - ' + ((d.x + d.dx)/1000) + 's</b>: ' + Math.round(d.y * 100) + "%" + "</div>"; return '<div class="tooltip-arrow"></div><div class="tooltip-inner"><b>' + (d.x/1000) + 's - ' + ((d.x + d.dx)/1000) + 's</b><div class="small">Percent: <b>' + Math.round(d.y * 100) + '%</b>' + '<br>Frequency: <b>' + d.frequency + '</b><br>Cumulative: <b>' + Math.floor(d.cumpercent*100) + '%</b></div></div>';
}) })
scope.init = function() scope.init = function()
{ {
// Init data var data = scope.data;
var data = d3.layout.histogram()
.frequency(false)
.bins(x.ticks(TICKS))
(scope.data);
// Adjust y axis // Adjust y axis
y.domain([0, d3.max(data, function(d) { return d.y; })]); y.domain([0, d3.max(data, function(d) { return d.y; })]);
@ -198,8 +195,6 @@ angular.module('netStatsApp.directives', []).
.attr("d", line(data)); .attr("d", line(data));
} }
scope.init();
scope.$watch('data', function() { scope.$watch('data', function() {
scope.init(); scope.init();
}, true); }, true);

View File

@ -42,6 +42,22 @@ angular.module('netStatsApp.filters', [])
return (! mining ? 'icon-cancel' : 'icon-check'); return (! mining ? 'icon-cancel' : 'icon-check');
}; };
}) })
.filter('hashpowerClass', function() {
return function(mining) {
if(! mining)
return 'text-gray';
return 'text-success';
};
})
.filter('hashrateFilter', function() {
return function(hashrate) {
if(typeof hashrate === 'undefined' || !hashrate)
return 0;
return hashrate/1000;
}
})
.filter('nodeVersion', function($sce) { .filter('nodeVersion', function($sce) {
return function(version) { return function(version) {
if(typeof version !== 'undefined') if(typeof version !== 'undefined')

View File

@ -116,6 +116,8 @@ block content
i.icon-clock(data-toggle="tooltip", data-placement="top", title="Node latency", ng-click="orderTable(['-stats.active', 'stats.latency'], false)") i.icon-clock(data-toggle="tooltip", data-placement="top", title="Node latency", ng-click="orderTable(['-stats.active', 'stats.latency'], false)")
th th
i.icon-mining(data-toggle="tooltip", data-placement="top", title="Is mining", ng-click="orderTable(['-stats.active', '-stats.mining'], false)") i.icon-mining(data-toggle="tooltip", data-placement="top", title="Is mining", ng-click="orderTable(['-stats.active', '-stats.mining'], false)")
th
i.icon-mining(data-toggle="tooltip", data-placement="top", title="Hashrate", ng-click="orderTable(['-stats.active', '-stats.mining', '-stats.hashrate'], false)")
th th
i.icon-group(data-toggle="tooltip", data-placement="top", title="Peers", ng-click="orderTable(['-stats.active', '-stats.peers'], false)") i.icon-group(data-toggle="tooltip", data-placement="top", title="Peers", ng-click="orderTable(['-stats.active', '-stats.peers'], false)")
th th
@ -139,10 +141,12 @@ block content
span.small #[&nbsp;]({{node.info.ip}}) span.small #[&nbsp;]({{node.info.ip}})
td td
div.small(ng-bind-html="node.info.node | nodeVersion") div.small(ng-bind-html="node.info.node | nodeVersion")
//- div.small {{node.info.os}}, {{node.info.os_v}} td(class="{{ node.stats | latencyClass }}")
td.small(class="{{ node.stats | latencyClass }}") {{node.stats | latencyFilter}} span.small {{node.stats | latencyFilter}}
td(class="{{ node.stats.mining | miningClass : node.stats.active }}") td(class="{{ node.stats.mining | miningClass : node.stats.active }}")
i(class="{{ node.stats.mining | miningIconClass }}") i(class="{{ node.stats.mining | miningIconClass }}")
td(class="{{ node.stats.mining | hashpowerClass }}")
span.small {{node.stats.hashrate | hashrateFilter}} kH/s
td(class="{{ node.stats.peers | peerClass : node.stats.active }}", style="padding-left: 11px;") {{node.stats.peers}} td(class="{{ node.stats.peers | peerClass : node.stats.active }}", style="padding-left: 11px;") {{node.stats.peers}}
td(style="padding-left: 15px;") {{node.stats.pending}} td(style="padding-left: 15px;") {{node.stats.pending}}
td(class="{{ node.stats | blockClass : bestBlock }}") {{'#'}}{{ node.stats.block.number | number }} td(class="{{ node.stats | blockClass : bestBlock }}") {{'#'}}{{ node.stats.block.number | number }}