Merge pull request #223 from cubedro/develop

Fixed broken lite version
This commit is contained in:
Marian OANCΞA 2015-07-29 20:18:04 +03:00
commit f744a7dd09
13 changed files with 19 additions and 546 deletions

View File

@ -37,23 +37,20 @@ var src_lite = 'src-lite/';
var dest_lite = 'dist-lite/'; var dest_lite = 'dist-lite/';
var scripts_lite = [ var scripts_lite = [
'scr-lite/js/app.js', 'src-lite/js/app.js',
'scr-lite/js/controllers.js', 'src-lite/js/controllers.js',
'scr-lite/js/filters.js', 'src-lite/js/filters.js',
'scr-lite/js/directives.js', 'src-lite/js/directives.js',
'scr-lite/js/script.js' 'src-lite/js/script.js'
]; ];
var vendor_lite = [ var vendor_lite = [
'dist-lite/js/lib/jquery-1.11.3.min.js', 'dist-lite/js/lib/jquery-1.11.3.min.js',
'dist-lite/js/lib/bootstrap.min.js', 'dist-lite/js/lib/bootstrap.min.js',
'dist-lite/js/lib/angular.min.js', 'dist-lite/js/lib/angular.min.js',
'dist-lite/js/lib/ngStorage.min.js',
'dist-lite/js/lib/lodash.min.js', 'dist-lite/js/lib/lodash.min.js',
'dist-lite/js/lib/d3.min.js', 'dist-lite/js/lib/d3.min.js',
'dist-lite/js/lib/d3.tip.min.js', 'dist-lite/js/lib/d3.tip.min.js',
'dist-lite/js/lib/topojson.min.js',
'dist-lite/js/lib/datamaps.min.js',
'dist-lite/js/lib/moment.min.js', 'dist-lite/js/lib/moment.min.js',
'dist-lite/js/lib/moment.en.min.js', 'dist-lite/js/lib/moment.en.min.js',
'dist-lite/js/lib/toastr.min.js', 'dist-lite/js/lib/toastr.min.js',

View File

@ -4,14 +4,14 @@ var path = require('path');
var bodyParser = require('body-parser'); var bodyParser = require('body-parser');
// view engine setup // view engine setup
app.set('views', path.join(__dirname, '../src/views')); app.set('views', path.join(__dirname, (process.env.LITE === 'true' ? '../src-lite/views' : '../src/views')));
app.set('view engine', 'jade'); app.set('view engine', 'jade');
app.use(bodyParser.json()); app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, '../dist'))); app.use(express.static(path.join(__dirname, (process.env.LITE === 'true' ? '../dist-lite' : '../dist'))));
app.get('/', function(req, res) { app.get('/', function(req, res) {
res.render((process.env.LITE === true ? 'index-lite' : 'index')); res.render('index');
}); });
// catch 404 and forward to error handler // catch 404 and forward to error handler

View File

@ -23,7 +23,7 @@ History.prototype.add = function(block, id, trusted, addingHistory)
if( !_.isUndefined(block) && !_.isUndefined(block.number) && !_.isUndefined(block.uncles) && !_.isUndefined(block.transactions) && !_.isUndefined(block.difficulty) && block.number > 0 ) if( !_.isUndefined(block) && !_.isUndefined(block.number) && !_.isUndefined(block.uncles) && !_.isUndefined(block.transactions) && !_.isUndefined(block.difficulty) && block.number > 0 )
{ {
trusted = (process.env.LITE === true ? true : trusted); trusted = (process.env.LITE === 'true' ? true : trusted);
var historyBlock = this.search(block.number); var historyBlock = this.search(block.number);
var forkIndex = -1; var forkIndex = -1;

View File

@ -81,7 +81,7 @@ Node.prototype.setInfo = function(data, callback)
if( !_.isUndefined(data.ip) ) if( !_.isUndefined(data.ip) )
{ {
if( trusted.indexOf(data.ip) >= 0 || process.env.LITE === true) if( trusted.indexOf(data.ip) >= 0 || process.env.LITE === 'true')
{ {
this.trusted = true; this.trusted = true;
} }

View File

@ -2,7 +2,7 @@
/* Init Angular App */ /* Init Angular App */
var netStatsApp = angular.module('netStatsApp', ['netStatsApp.filters', 'netStatsApp.directives', 'ngStorage']); var netStatsApp = angular.module('netStatsApp', ['netStatsApp.filters', 'netStatsApp.directives']);
/* Services */ /* Services */

View File

@ -1,7 +1,7 @@
/* Controllers */ /* Controllers */
netStatsApp.controller('StatsCtrl', function($scope, $filter, $localStorage, socket, _, toastr) { netStatsApp.controller('StatsCtrl', function($scope, $filter, socket, _, toastr) {
var MAX_BINS = 40; var MAX_BINS = 40;
@ -37,9 +37,9 @@ netStatsApp.controller('StatsCtrl', function($scope, $filter, $localStorage, soc
$scope.currentApiVersion = "0.0.16"; $scope.currentApiVersion = "0.0.16";
$scope.predicate = $localStorage.predicate || ['-pinned', '-stats.active', '-stats.block.number', 'stats.block.propagation']; $scope.predicate = ['-pinned', '-stats.active', '-stats.block.number', 'stats.block.propagation'];
$scope.reverse = $localStorage.reverse || false; $scope.reverse = false;
$scope.pinned = $localStorage.pinned || []; $scope.pinned = [];
$scope.prefixPredicate = ['-pinned', '-stats.active']; $scope.prefixPredicate = ['-pinned', '-stats.active'];
$scope.originalPredicate = ['-stats.block.number', 'stats.block.propagation']; $scope.originalPredicate = ['-stats.block.number', 'stats.block.propagation'];
@ -64,9 +64,6 @@ netStatsApp.controller('StatsCtrl', function($scope, $filter, $localStorage, soc
$scope.predicate = _.union($scope.prefixPredicate, predicate); $scope.predicate = _.union($scope.prefixPredicate, predicate);
} }
$localStorage.predicate = $scope.predicate;
$localStorage.reverse = $scope.reverse;
} }
$scope.pinNode = function(id) $scope.pinNode = function(id)
@ -86,8 +83,6 @@ netStatsApp.controller('StatsCtrl', function($scope, $filter, $localStorage, soc
$scope.pinned.splice($scope.pinned.indexOf(id), 1); $scope.pinned.splice($scope.pinned.indexOf(id), 1);
} }
} }
$localStorage.pinned = $scope.pinned;
} }
var timeout = setInterval(function () var timeout = setInterval(function ()
@ -329,14 +324,6 @@ netStatsApp.controller('StatsCtrl', function($scope, $filter, $localStorage, soc
if( !_.isEqual($scope.lastBlocksTime, data.blocktime) && data.blocktime.length >= MAX_BINS ) if( !_.isEqual($scope.lastBlocksTime, data.blocktime) && data.blocktime.length >= MAX_BINS )
$scope.lastBlocksTime = data.blocktime; $scope.lastBlocksTime = data.blocktime;
if( !_.isEqual($scope.difficultyChart, data.difficulty) && data.difficulty.length >= MAX_BINS )
$scope.difficultyChart = data.difficulty;
if( !_.isEqual($scope.blockPropagationChart, data.propagation.histogram) ) {
$scope.blockPropagationChart = data.propagation.histogram;
$scope.blockPropagationAvg = data.propagation.avg;
}
data.uncleCount.reverse(); data.uncleCount.reverse();
if( !_.isEqual($scope.uncleCountChart, data.uncleCount) && data.uncleCount.length >= MAX_BINS ) { if( !_.isEqual($scope.uncleCountChart, data.uncleCount) && data.uncleCount.length >= MAX_BINS ) {
@ -344,17 +331,6 @@ netStatsApp.controller('StatsCtrl', function($scope, $filter, $localStorage, soc
$scope.uncleCountChart = data.uncleCount; $scope.uncleCountChart = data.uncleCount;
} }
if( !_.isEqual($scope.transactionDensity, data.transactions) && data.transactions.length >= MAX_BINS )
$scope.transactionDensity = data.transactions;
if( !_.isEqual($scope.gasSpending, data.gasSpending) && data.gasSpending.length >= MAX_BINS )
$scope.gasSpending = data.gasSpending;
if( !_.isEqual($scope.miners, data.miners) ) {
$scope.miners = data.miners;
getMinersNames();
}
break; break;
case "inactive": case "inactive":
@ -399,8 +375,6 @@ netStatsApp.controller('StatsCtrl', function($scope, $filter, $localStorage, soc
break; break;
} }
// $scope.$apply();
} }
function findIndex(search) function findIndex(search)
@ -408,26 +382,6 @@ netStatsApp.controller('StatsCtrl', function($scope, $filter, $localStorage, soc
return _.findIndex($scope.nodes, search); return _.findIndex($scope.nodes, search);
} }
function getMinersNames()
{
if( $scope.miners.length > 0 )
{
_.forIn($scope.miners, function (value, key)
{
if(value.name !== false)
return;
if(value.miner === "0x0000000000000000000000000000000000000000")
return;
var name = _.result(_.find(_.pluck($scope.nodes, 'info'), 'coinbase', value.miner), 'name');
if( !_.isUndefined(name) )
$scope.miners[key].name = name;
});
}
}
function addNewNode(data) function addNewNode(data)
{ {
var index = findIndex({id: data.id}); var index = findIndex({id: data.id});
@ -476,30 +430,6 @@ netStatsApp.controller('StatsCtrl', function($scope, $filter, $localStorage, soc
forkFilter(node); forkFilter(node);
return node.stats.active == true; return node.stats.active == true;
}).length; }).length;
$scope.upTimeTotal = _.reduce($scope.nodes, function (total, node) {
return total + node.stats.uptime;
}, 0) / $scope.nodes.length;
$scope.map = _.map($scope.nodes, function (node) {
var fill = $filter('bubbleClass')(node.stats, $scope.bestBlock);
if(node.geo != null)
return {
radius: 3,
latitude: node.geo.ll[0],
longitude: node.geo.ll[1],
nodeName: node.info.name,
fillClass: "text-" + fill,
fillKey: fill,
};
else
return {
radius: 0,
latitude: 0,
longitude: 0
};
});
} }
function updateBestBlock() function updateBestBlock()

View File

@ -1,4 +1,3 @@
/* Directives */ /* Directives */
angular.module('netStatsApp.directives', []) angular.module('netStatsApp.directives', [])
@ -6,417 +5,4 @@ angular.module('netStatsApp.directives', [])
return function(scope, elm, attrs) { return function(scope, elm, attrs) {
elm.text(version); elm.text(version);
}; };
}]) }]);
// .directive('timeAgo', ['$interval', function($interval) {
// function link (scope, element, attrs)
// {
// var timestamp,
// timeoutId;
// function updateTime() {
// element.text(timeAgo())
// }
// function timeAgo()
// {
// if(timestamp === 0)
// return '∞';
// var time = (new Date()).getTime();
// var diff = Math.floor((time - timestamp)/1000);
// if(diff < 60)
// return Math.round(diff) + ' s ago';
// return moment.duration(Math.round(diff), 's').humanize() + ' ago';
// };
// scope.$watch(attrs.timeAgo, function(value) {
// timestamp = value;
// updateTime();
// });
// element.on('$destroy', function() {
// $interval.cancel(timeoutId);
// });
// timeoutId = $interval(function () {
// updateTime();
// }, 200);
// };
// return {
// link: link
// };
// }])
.directive('minerblock', function ($compile) {
return {
restrict: 'E',
template: '<div></div>',
replace: true,
link: function (scope, element, attrs)
{
var makeClass = function (value)
{
if(value <= 6)
return 'success';
if(value <= 12)
return 'info';
if(value <= 18)
return 'warning';
if(value <= 24)
return 'orange';
return 'danger';
}
attrs.$observe("blocks", function (newValue)
{
var content = '';
var blockClass = 'bg-' + makeClass(newValue);
for(var i = 0; i < newValue; i++)
{
content += '<div class="block ' + blockClass + '"></div>';
}
element.empty();
element.html(content);
});
}
};
})
.directive('sparkchart', function () {
return {
restrict: 'E',
scope: {
data: '@'
},
compile: function (tElement, tAttrs, transclude)
{
tElement.replaceWith('<span>' + tAttrs.data + "</span>");
return function(scope, element, attrs)
{
attrs.$observe("data", function (newValue)
{
element.html(newValue);
element.addClass("big-details");
element.sparkline('html', {
type: 'bar',
tooltipSuffix: (attrs.tooltipsuffix || '')
});
});
};
}
};
})
.directive('nodepropagchart', function() {
return {
restrict: 'E',
scope: {
data: '@'
},
compile: function (tElement, tAttrs, transclude)
{
tElement.replaceWith('<span>' + tAttrs.data + "</span>");
function formatTime (ms) {
var result = 0;
if(ms < 1000) {
return ms + " ms";
}
if(ms < 1000*60) {
result = ms/1000;
return result.toFixed(1) + " s";
}
if(ms < 1000*60*60) {
result = ms/1000/60;
return Math.round(result) + " min";
}
if(ms < 1000*60*60*24) {
result = ms/1000/60/60;
return Math.round(result) + " h";
}
result = ms/1000/60/60/24;
return Math.round(result) + " days";
};
return function(scope, element, attrs)
{
attrs.$observe("data", function (newValue)
{
element.html(newValue);
element.sparkline('html', {
type: 'bar',
negBarColor: '#7f7f7f',
zeroAxis: false,
height: 20,
barWidth : 2,
barSpacing : 1,
tooltipSuffix: '',
chartRangeMax: 8000,
colorMap: jQuery.range_map({
'0:1': '#10a0de',
'1:1000': '#7bcc3a',
'1001:3000': '#FFD162',
'3001:7000': '#ff8a00',
'7001:': '#F74B4B'
}),
tooltipFormatter: function (spark, opt, ms) {
var tooltip = '<div class="tooltip-arrow"></div><div class="tooltip-inner">';
tooltip += formatTime(ms[0].value);
tooltip += '</div>';
return tooltip;
}
});
});
};
}
};
})
.directive('nodemap', ['$compile', function($compile) {
return {
restrict: 'EA',
scope: {
data: '='
},
link: function(scope, element, attrs) {
var bubbleConfig = {
borderWidth: 0,
highlightOnHover: false,
popupOnHover: true,
popupTemplate: function(geo, data) {
return ['<div class="tooltip-arrow"></div>',
'<div class="hoverinfo ' + data.fillClass + '">',
'<div class="propagationBox"></div>',
'<strong>',
data.nodeName,
'</strong>',
'</div>'].join('');
}
};
scope.init = function() {
element.empty();
var width = 628,
height = 244;
scope.map = new Datamap({
element: element[0],
scope: 'world',
width: width,
height: 300,
fills: {
success: '#7BCC3A',
info: '#10A0DE',
warning: '#FFD162',
orange: '#FF8A00',
danger: '#F74B4B',
defaultFill: '#282828'
},
geographyConfig: {
borderWidth: 0,
borderColor: '#000',
highlightOnHover: false,
popupOnHover: false
},
bubblesConfig: {
borderWidth: 0,
highlightOnHover: false,
popupOnHover: true
},
done: function(datamap) {
var ev;
var zoomListener = d3.behavior.zoom()
.size([width, height])
.scaleExtent([1, 3])
.on("zoom", redraw)
.on("zoomend", animadraw);
function redraw() {
datamap.svg.select(".datamaps-subunits").attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
datamap.svg.select(".bubbles").selectAll("circle")
.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")")
.attr("r", 3/d3.event.scale);
ev = d3.event;
}
zoomListener(datamap.svg);
function animadraw() {
var x = Math.min(0, Math.max(ev.translate[0], (-1) * width * (ev.scale-1)));
var y = Math.min(0, Math.max(ev.translate[1], (-1) * height * (ev.scale-1)));
datamap.svg.select(".datamaps-subunits")
.transition()
.delay(150)
.duration(750)
.attr("transform", "translate(" + x + "," + y + ")scale(" + ev.scale + ")");
datamap.svg.select(".bubbles").selectAll("circle")
.transition()
.delay(150)
.duration(750)
.attr("transform", "translate(" + x + "," + y + ")scale(" + ev.scale + ")")
.attr("r", 3/ev.scale);
zoomListener.translate([x,y]);
}
}
});
scope.map.bubbles(scope.data, bubbleConfig);
}
scope.init();
scope.$watch('data', function() {
scope.map.bubbles(scope.data, bubbleConfig);
}, true);
}
};
}])
.directive('histogram', ['$compile', function($compile) {
return {
restrict: 'EA',
scope: {
data: '='
},
link: function(scope, element, attrs)
{
var margin = {top: 0, right: 0, bottom: 0, left: 0};
var width = 280 - margin.left - margin.right,
height = 63 - margin.top - margin.bottom;
var TICKS = 40;
var x = d3.scale.linear()
.domain([0, 10000])
.rangeRound([0, width])
.interpolate(d3.interpolateRound);
var y = d3.scale.linear()
.range([height, 0])
.interpolate(d3.interpolateRound);
var color = d3.scale.linear()
.domain([1000, 3000, 7000, 10000])
.range(["#7bcc3a", "#FFD162", "#ff8a00", "#F74B4B"]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(4, ",.1s")
.tickFormat(function(t){ return t/1000 + "s"});
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(3)
.tickFormat(d3.format("%"));
var line = d3.svg.line()
.x(function(d) { return x(d.x + d.dx/2) - 1; })
.y(function(d) { return y(d.y) - 2; })
.interpolate('basis');
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([10, 0])
.direction('s')
.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><div class="small">Percent: <b>' + Math.round(d.y * 100) + '%</b>' + '<br>Frequency: <b>' + d.frequency + '</b><br>Cumulative: <b>' + Math.round(d.cumpercent*100) + '%</b></div></div>';
})
scope.init = function()
{
var data = scope.data;
// Adjust y axis
y.domain([0, d3.max(data, function(d) { return d.y; })]);
// Delete previous histogram
element.empty();
/* Start drawing */
var svg = d3.select(".d3-blockpropagation").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg.call(tip);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.attr("y", 6);
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + width + ", 0)")
.call(yAxis);
var bar = svg.append("g")
.attr("class", "bars")
.selectAll("g")
.data(data)
.enter().append("g")
.attr("transform", function(d) { return "translate(" + x(d.x) + ",0)"; })
.on('mouseover', function(d) { tip.show(d, d3.select(this).select('.bar').node()); })
.on('mouseout', tip.hide);
bar.insert("rect")
.attr("class", "handle")
.attr("y", 0)
.attr("width", x(data[0].dx + data[0].x) - x(data[0].x))
.attr("height", function(d) { return height; });
bar.insert("rect")
.attr("class", "bar")
.attr("y", function(d) { return y(d.y); })
.attr("rx", 1)
.attr("ry", 1)
.attr("fill", function(d) { return color(d.x); })
.attr("width", x(data[0].dx + data[0].x) - x(data[0].x) - 1)
.attr("height", function(d) { return height - y(d.y) + 1; });
bar.insert("rect")
.attr("class", "highlight")
.attr("y", function(d) { return y(d.y); })
.attr("fill", function(d) { return d3.rgb(color(d.x)).brighter(.7).toString(); })
.attr("rx", 1)
.attr("ry", 1)
.attr("width", x(data[0].dx + data[0].x) - x(data[0].x) - 1)
.attr("height", function(d) { return height - y(d.y) + 1; });
svg.append("path")
.attr("class", "line")
.attr("d", line(data));
}
scope.$watch('data', function() {
if(scope.data.length > 0) {
scope.init();
}
}, true);
}
};
}]);

View File

@ -36,27 +36,6 @@ angular.module('netStatsApp.filters', [])
return peerClass(peers, active); return peerClass(peers, active);
}; };
}) })
.filter('miningClass', function() {
return function(mining, active) {
if(! active)
return 'text-gray';
return (! mining ? 'text-danger' : 'text-success');
};
})
.filter('miningIconClass', function() {
return function(mining) {
return (! mining ? 'icon-cancel' : 'icon-check');
};
})
.filter('hashrateClass', function() {
return function(mining, active) {
if(! mining || ! active)
return 'text-gray';
return 'text-success';
};
})
.filter('hashrateFilter', ['$sce', '$filter', function($sce, filter) { .filter('hashrateFilter', ['$sce', '$filter', function($sce, filter) {
return function(hashes, isMining) { return function(hashes, isMining) {
var result = 0; var result = 0;
@ -544,7 +523,7 @@ angular.module('netStatsApp.filters', [])
.filter('consensusClass', function() { .filter('consensusClass', function() {
return function(nodes, bestBlock) { return function(nodes, bestBlock) {
var status = 'success'; var status = 'success';
var now = _.now(); var now = (new Date()).getTime();
for(var x = 0; x < nodes.length; x++) for(var x = 0; x < nodes.length; x++)
{ {

File diff suppressed because one or more lines are too long

View File

@ -1 +0,0 @@
/*! ngstorage 0.3.4 | Copyright (c) 2015 Gias Kay Lee | MIT License */!function(a,b){"use strict";return"function"==typeof define&&define.amd?void define("ngStorage",["angular"],function(a){return b(a)}):b(a)}("undefined"==typeof angular?null:angular,function(a){"use strict";function b(b){return["$rootScope","$window","$log","$timeout",function(c,d,e,f){function g(a){var b=d[a];if(b&&"localStorage"===a){var c="__"+Math.round(1e7*Math.random());try{localStorage.setItem(c,c),localStorage.removeItem(c)}catch(e){b=!1}}return b}var h,i,j=g(b)||(e.warn("This browser does not support Web Storage!"),{setItem:function(){},getItem:function(){}}),k={$default:function(b){for(var c in b)a.isDefined(k[c])||(k[c]=b[c]);return k},$reset:function(a){for(var b in k)"$"===b[0]||delete k[b];return k.$default(a)}};try{j=d[b],j.length}catch(l){e.warn("This browser does not support Web Storage!"),j={}}for(var m,n=0,o=j.length;o>n;n++)(m=j.key(n))&&"ngStorage-"===m.slice(0,10)&&(k[m.slice(10)]=a.fromJson(j.getItem(m)));return h=a.copy(k),c.$watch(function(){var b;i||(i=f(function(){if(i=null,!a.equals(k,h)){b=a.copy(h),a.forEach(k,function(c,d){a.isDefined(c)&&"$"!==d[0]&&j.setItem("ngStorage-"+d,a.toJson(c)),delete b[d]});for(var c in b)j.removeItem("ngStorage-"+c);h=a.copy(k)}},100,!1))}),"localStorage"===b&&d.addEventListener&&d.addEventListener("storage",function(b){"ngStorage-"===b.key.slice(0,10)&&(b.newValue?k[b.key.slice(10)]=a.fromJson(b.newValue):delete k[b.key.slice(10)],h=a.copy(k),c.$apply())}),k}]}a.module("ngStorage",[]).factory("$localStorage",b("localStorage")).factory("$sessionStorage",b("sessionStorage"))});

File diff suppressed because one or more lines are too long

View File

@ -88,21 +88,13 @@ block content
i.icon-laptop(data-toggle="tooltip", data-placement="top", title="Node type", ng-click="orderTable(['info.node'], false)") i.icon-laptop(data-toggle="tooltip", data-placement="top", title="Node type", ng-click="orderTable(['info.node'], false)")
th.th-latency th.th-latency
i.icon-clock(data-toggle="tooltip", data-placement="top", title="Node latency", ng-click="orderTable(['stats.latency'], false)") i.icon-clock(data-toggle="tooltip", data-placement="top", title="Node latency", ng-click="orderTable(['stats.latency'], false)")
//- th
i.icon-mining(data-toggle="tooltip", data-placement="top", title="Is mining", ng-click="orderTable(['-stats.hashrate'], false)")
//- th //- th
i.icon-group(data-toggle="tooltip", data-placement="top", title="Peers", ng-click="orderTable(['-stats.peers'], false)") i.icon-group(data-toggle="tooltip", data-placement="top", title="Peers", ng-click="orderTable(['-stats.peers'], false)")
//- th
i.icon-network(data-toggle="tooltip", data-placement="top", title="Pending transactions", ng-click="orderTable(['-stats.pending'], false)")
th th
i.icon-block(data-toggle="tooltip", data-placement="top", title="Last block", ng-click="orderTable(['-stats.block.number', 'stats.block.propagation'], false)") i.icon-block(data-toggle="tooltip", data-placement="top", title="Last block", ng-click="orderTable(['-stats.block.number', 'stats.block.propagation'], false)")
th.th-blockhash &nbsp; th.th-blockhash &nbsp;
th.th-blockhash th.th-blockhash
i.icon-difficulty(data-toggle="tooltip", data-placement="top", title="Total difficulty", ng-click="orderTable(['-stats.block.totalDifficulty'], false)") i.icon-difficulty(data-toggle="tooltip", data-placement="top", title="Total difficulty", ng-click="orderTable(['-stats.block.totalDifficulty'], false)")
//- th
i.icon-check-o(data-toggle="tooltip", data-placement="top", title="Block transactions", ng-click="orderTable(['-stats.block.transactions.length'], false)")
//- th
i.icon-uncle(data-toggle="tooltip", data-placement="top", title="Uncles", ng-click="orderTable(['-stats.block.uncles.length'], false)")
th.th-blocktime th.th-blocktime
i.icon-time(data-toggle="tooltip", data-placement="top", title="Last block time", ng-click="orderTable(['-stats.block.received'], false)") i.icon-time(data-toggle="tooltip", data-placement="top", title="Last block time", ng-click="orderTable(['-stats.block.received'], false)")
th.th-peerPropagationTime th.th-peerPropagationTime
@ -110,8 +102,6 @@ block content
//- th.th-peerPropagationChart //- th.th-peerPropagationChart
//- th.th-peerPropagationAvg //- th.th-peerPropagationAvg
i.icon-gas(data-toggle="tooltip", data-placement="top", title="Average propagation time", ng-click="orderTable(['stats.propagationAvg'], false)") i.icon-gas(data-toggle="tooltip", data-placement="top", title="Average propagation time", ng-click="orderTable(['stats.propagationAvg'], false)")
//- th
i.icon-bulb(data-toggle="tooltip", data-placement="top", title="Up-time", ng-click="orderTable(['-stats.uptime'], false)")
tbody(ng-cloak) tbody(ng-cloak)
tr(ng-repeat='node in nodes | orderBy:predicate track by node.id', class="{{ node.stats | mainClass : bestBlock }}", id="node_{{node.id}}") tr(ng-repeat='node in nodes | orderBy:predicate track by node.id', class="{{ node.stats | mainClass : bestBlock }}", id="node_{{node.id}}")
td.td-nodecheck td.td-nodecheck
@ -125,9 +115,7 @@ block content
div.small(ng-bind-html="node.info.node | nodeVersion") div.small(ng-bind-html="node.info.node | nodeVersion")
td(class="{{ node.readable.latencyClass }}") td(class="{{ node.readable.latencyClass }}")
span.small {{ node.readable.latency }} span.small {{ node.readable.latency }}
//- td(class="{{ node.stats.mining | hashrateClass : node.stats.active }}", ng-bind-html="node.stats.hashrate | hashrateFilter : node.stats.mining")
//- 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(class="{{ node.stats | blockClass : bestBlock }}") td(class="{{ node.stats | blockClass : bestBlock }}")
span(class="{{ node.readable.forkMessage ? node.readable.forkClass : '' }}") {{'#'}}{{ node.stats.block.number | number }} span(class="{{ node.readable.forkMessage ? node.readable.forkClass : '' }}") {{'#'}}{{ node.stats.block.number | number }}
a.small(data-toggle="tooltip", data-placement="top", data-html="true", data-original-title="{{ node.readable.forkMessage }}", class="{{ node.readable.forkClass }}") a.small(data-toggle="tooltip", data-placement="top", data-html="true", data-original-title="{{ node.readable.forkMessage }}", class="{{ node.readable.forkClass }}")
@ -136,8 +124,6 @@ block content
span.small {{node.stats.block.hash | hashFilter}} span.small {{node.stats.block.hash | hashFilter}}
td(class="{{ node.stats | blockClass : bestBlock }}") td(class="{{ node.stats | blockClass : bestBlock }}")
span.small {{node.stats.block.totalDifficulty | number}} span.small {{node.stats.block.totalDifficulty | number}}
//- td(style="padding-left: 14px;") {{node.stats.block.transactions.length || 0}}
//- td(style="padding-left: 14px;") {{node.stats.block.uncles.length || 0}}
td(class="{{ node.stats.block.received | timeClass : node.stats.active }}") {{node.stats.block.received | blockTimeFilter }} td(class="{{ node.stats.block.received | timeClass : node.stats.active }}") {{node.stats.block.received | blockTimeFilter }}
td(class="{{ node.stats | propagationTimeClass : bestBlock }}") td(class="{{ node.stats | propagationTimeClass : bestBlock }}")
div.propagationBox div.propagationBox
@ -145,4 +131,3 @@ block content
//- td.peerPropagationChart(class="{{node.id}}") //- td.peerPropagationChart(class="{{node.id}}")
nodepropagchart(data="{{node.history.join(',')}}") nodepropagchart(data="{{node.history.join(',')}}")
//- td(class="{{ node.stats | propagationNodeAvgTimeClass : bestBlock }}") {{ node.stats | blockPropagationAvgFilter : bestBlock }} //- td(class="{{ node.stats | propagationNodeAvgTimeClass : bestBlock }}") {{ node.stats | blockPropagationAvgFilter : bestBlock }}
//- td(class="{{ node.stats.uptime | upTimeClass : node.stats.active }}") {{ node.stats.uptime | upTimeFilter }}

View File

@ -1,13 +1,13 @@
//- layout.jade //- layout.jade
doctype html doctype html
html(ng-app="netStatsApp") html
head head
meta(name="viewport", content="width=device-width, initial-scale=1.0, maximum-scale=1.0") meta(name="viewport", content="width=device-width, initial-scale=1.0, maximum-scale=1.0")
title Ethereum Network Status title Ethereum Network Status
style(type="text/css") [ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak { display: none !important; } style(type="text/css") [ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak { display: none !important; }
link(rel='stylesheet', href='//fonts.googleapis.com/css?family=Source+Sans+Pro:200,300,400,600,700') link(rel='stylesheet', href='//fonts.googleapis.com/css?family=Source+Sans+Pro:200,300,400,600,700')
link(rel='stylesheet', href='/css/netstats.min.css') link(rel='stylesheet', href='/css/netstats.min.css')
body body(ng-app="netStatsApp")
block content block content
script(src="/js/netstats.min.js") script(src="/js/netstats.min.js")