commit
a0ef3fc03b
2
app.js
2
app.js
@ -103,7 +103,7 @@ client.on('connection', function(spark) {
|
|||||||
// view engine setup
|
// view engine setup
|
||||||
app.set('views', path.join(__dirname, 'views'));
|
app.set('views', path.join(__dirname, 'views'));
|
||||||
app.set('view engine', 'jade');
|
app.set('view engine', 'jade');
|
||||||
//app.use(favicon(__dirname + '/public/favicon.ico'));
|
app.use(favicon(path.join(__dirname, '/public/images/favicon.png')));
|
||||||
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, 'public')));
|
app.use(express.static(path.join(__dirname, 'public')));
|
||||||
|
@ -19,7 +19,8 @@ var Node = function Node(data)
|
|||||||
timestamp: 0,
|
timestamp: 0,
|
||||||
arrival: 0,
|
arrival: 0,
|
||||||
propagation: 0,
|
propagation: 0,
|
||||||
received: 0
|
received: 0,
|
||||||
|
transactions: []
|
||||||
},
|
},
|
||||||
blocktimeAvg: 0,
|
blocktimeAvg: 0,
|
||||||
blockTimes: [],
|
blockTimes: [],
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
body {
|
body {
|
||||||
|
min-width: 1920px;
|
||||||
font-smooth: auto;
|
font-smooth: auto;
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
-moz-font-smoothing: antialiased;
|
-moz-font-smoothing: antialiased;
|
||||||
@ -34,6 +35,13 @@ body {
|
|||||||
color: #aaa !important;
|
color: #aaa !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.big-info.chart {
|
||||||
|
padding-left: 14px;
|
||||||
|
padding-right: 14px;
|
||||||
|
-webkit-box-sizing: border-box
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
.big-info span.big-details {
|
.big-info span.big-details {
|
||||||
display: block;
|
display: block;
|
||||||
font-weight: 200;
|
font-weight: 200;
|
||||||
@ -42,6 +50,32 @@ body {
|
|||||||
letter-spacing: -4px;
|
letter-spacing: -4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.big-info.chart span.big-details {
|
||||||
|
padding-top: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.jqstooltip {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.jqsfield {
|
||||||
|
position: relative;
|
||||||
|
padding: 5px 0;
|
||||||
|
width: auto;
|
||||||
|
left: -50%;
|
||||||
|
word-wrap: wrap;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.jqsfield .tooltip-arrow {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 50%;
|
||||||
|
margin-left: -5px;
|
||||||
|
border-width: 5px 5px 0;
|
||||||
|
border-top-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
table i {
|
table i {
|
||||||
-webkit-font-smoothing: subpixel-antialiased;
|
-webkit-font-smoothing: subpixel-antialiased;
|
||||||
-moz-font-smoothing: subpixel-antialiased;
|
-moz-font-smoothing: subpixel-antialiased;
|
||||||
@ -84,7 +118,7 @@ table td i {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (max-width: 639px) {
|
@media only screen and (max-width: 639px) {
|
||||||
.big-info {
|
/*.big-info {
|
||||||
padding-bottom: 15px;
|
padding-bottom: 15px;
|
||||||
padding-top: 15px;
|
padding-top: 15px;
|
||||||
border: 1px solid rgba(255,255,255,0.05);
|
border: 1px solid rgba(255,255,255,0.05);
|
||||||
@ -115,13 +149,13 @@ table td i {
|
|||||||
font-size: 46px;
|
font-size: 46px;
|
||||||
line-height: 50px;
|
line-height: 50px;
|
||||||
letter-spacing: -4px;
|
letter-spacing: -4px;
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (max-width: 479px) {
|
@media only screen and (max-width: 479px) {
|
||||||
.stat-holder {
|
/*.stat-holder {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
.ng-cloak {
|
.ng-cloak {
|
||||||
|
BIN
public/images/favicon.png
Normal file
BIN
public/images/favicon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 574 B |
@ -15,6 +15,11 @@ function StatsCtrl($scope, $filter, socket, _, toastr) {
|
|||||||
$scope.upTimeTotal = 0;
|
$scope.upTimeTotal = 0;
|
||||||
$scope.avgBlockTime = 0;
|
$scope.avgBlockTime = 0;
|
||||||
|
|
||||||
|
$scope.lastBlocksTime = [];
|
||||||
|
$scope.difficultyChange = [];
|
||||||
|
$scope.transactionDensity = [];
|
||||||
|
$scope.gasSpending = [];
|
||||||
|
|
||||||
$scope.nodes = [];
|
$scope.nodes = [];
|
||||||
$scope.map = [];
|
$scope.map = [];
|
||||||
|
|
||||||
@ -135,6 +140,30 @@ function StatsCtrl($scope, $filter, socket, _, toastr) {
|
|||||||
return total + node.stats.uptime;
|
return total + node.stats.uptime;
|
||||||
}, 0) / $scope.nodes.length;
|
}, 0) / $scope.nodes.length;
|
||||||
|
|
||||||
|
$scope.lastBlocksTime = _.max($scope.nodes, function(node) {
|
||||||
|
return parseInt(node.stats.block.number);
|
||||||
|
}).stats.blockTimes;
|
||||||
|
|
||||||
|
jQuery('.spark-blocktimes').sparkline($scope.lastBlocksTime, {type: 'bar', tooltipSuffix: 's'});
|
||||||
|
|
||||||
|
$scope.difficultyChange = _.max($scope.nodes, function(node) {
|
||||||
|
return parseInt(node.stats.block.number);
|
||||||
|
}).stats.difficulty;
|
||||||
|
|
||||||
|
jQuery('.spark-difficulty').sparkline($scope.difficultyChange, {type: 'bar'});
|
||||||
|
|
||||||
|
$scope.transactionDensity = _.max($scope.nodes, function(node) {
|
||||||
|
return parseInt(node.stats.block.number);
|
||||||
|
}).stats.txDensity;
|
||||||
|
|
||||||
|
jQuery('.spark-transactions').sparkline($scope.transactionDensity, {type: 'bar'});
|
||||||
|
|
||||||
|
$scope.gasSpending = _.max($scope.nodes, function(node) {
|
||||||
|
return parseInt(node.stats.block.number);
|
||||||
|
}).stats.gasSpending;
|
||||||
|
|
||||||
|
jQuery('.spark-gasspending').sparkline($scope.gasSpending, {type: 'bar'});
|
||||||
|
|
||||||
$scope.map = _.map($scope.nodes, function(node) {
|
$scope.map = _.map($scope.nodes, function(node) {
|
||||||
if(node.geo != null)
|
if(node.geo != null)
|
||||||
return {
|
return {
|
||||||
@ -151,7 +180,7 @@ function StatsCtrl($scope, $filter, socket, _, toastr) {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log($scope.map);
|
// console.log($scope.map);
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.$apply();
|
$scope.$apply();
|
||||||
|
@ -41,12 +41,16 @@ angular.module('netStatsApp.filters', [])
|
|||||||
})
|
})
|
||||||
.filter('nodeVersion', function($sce) {
|
.filter('nodeVersion', function($sce) {
|
||||||
return function(version) {
|
return function(version) {
|
||||||
|
if(typeof version !== 'undefined') {
|
||||||
version = version.replace('eth version ', 'v')
|
version = version.replace('eth version ', 'v')
|
||||||
.replace("\n" + 'Network protocol version: ', ' (')
|
.replace("\n" + 'Network protocol version: ', ' (')
|
||||||
.replace("\n" + 'Client database version: ', ',')
|
.replace("\n" + 'Client database version: ', ',')
|
||||||
.replace("\n" + 'Build: ', ') - ')
|
.replace("\n" + 'Build: ', ') - ')
|
||||||
.replace('/Debug', '')
|
.replace('/Debug', '')
|
||||||
.replace('/.', '');
|
.replace('/.', '');
|
||||||
|
} else
|
||||||
|
return '';
|
||||||
|
|
||||||
return $sce.trustAsHtml(version);
|
return $sce.trustAsHtml(version);
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
|
2
public/js/lib/jquery.sparkline.min.js
vendored
2
public/js/lib/jquery.sparkline.min.js
vendored
File diff suppressed because one or more lines are too long
@ -5,9 +5,23 @@
|
|||||||
$(this).tooltip('hide');
|
$(this).tooltip('hide');
|
||||||
});
|
});
|
||||||
|
|
||||||
moment.relativeTimeTreshold('s', 60);
|
$.fn.sparkline.defaults.bar.height = 50;
|
||||||
moment.relativeTimeTreshold('m', 60);
|
$.fn.sparkline.defaults.bar.barWidth = 6;
|
||||||
moment.relativeTimeTreshold('h', 24);
|
$.fn.sparkline.defaults.bar.barSpacing = 2;
|
||||||
moment.relativeTimeTreshold('d', 28);
|
$.fn.sparkline.defaults.bar.tooltipClassname = 'jqstooltip';
|
||||||
moment.relativeTimeTreshold('M', 12);
|
$.fn.sparkline.defaults.bar.tooltipOffsetX = 0;
|
||||||
|
// $.fn.sparkline.defaults.bar.tooltipFormat = $.spformat('<div class="tooltip-arrow" style="left: 50%;"></div><div class="tooltip-inner"><span style="color: {{color}}">●</span><br>{{prefix}}{{value}}{{suffix}}</div>');
|
||||||
|
$.fn.sparkline.defaults.bar.tooltipFormat = $.spformat('<div class="tooltip-arrow" style="left: 50%;"></div><div class="tooltip-inner">{{prefix}}{{value}}{{suffix}}</div>');
|
||||||
|
$.fn.sparkline.defaults.bar.colorMap = $.range_map({
|
||||||
|
'1:12': '#7bcc3a',
|
||||||
|
'12:19': '#10a0de',
|
||||||
|
'20:29': '#FFD162',
|
||||||
|
'30:': '#F74B4B'
|
||||||
|
});
|
||||||
|
|
||||||
|
moment.relativeTimeThreshold('s', 60);
|
||||||
|
moment.relativeTimeThreshold('m', 60);
|
||||||
|
moment.relativeTimeThreshold('h', 24);
|
||||||
|
moment.relativeTimeThreshold('d', 28);
|
||||||
|
moment.relativeTimeThreshold('M', 12);
|
||||||
})();
|
})();
|
@ -3,7 +3,7 @@ extends layout
|
|||||||
block content
|
block content
|
||||||
div.container-fluid(ng-controller='StatsCtrl')
|
div.container-fluid(ng-controller='StatsCtrl')
|
||||||
div.row(ng-cloak)
|
div.row(ng-cloak)
|
||||||
div.col-lg-12
|
div.col-xs-12
|
||||||
//- div.col-sm-12
|
//- div.col-sm-12
|
||||||
//- h1= title
|
//- h1= title
|
||||||
//- p Welcome to #{title}
|
//- p Welcome to #{title}
|
||||||
@ -61,26 +61,38 @@ block content
|
|||||||
|
|
||||||
div.clearfix
|
div.clearfix
|
||||||
|
|
||||||
div.col-xs.12
|
div.col-xs-12
|
||||||
div.col-lg-8(style="padding-top: 30px;")
|
div.row
|
||||||
//- div.col-xs-3.stat-holder
|
div.col-xs-8(style="padding-top: 30px;")
|
||||||
//- div.row.big-info.nodesactive(class="{{ nodesActive | nodesActiveClass : nodesTotal }}")
|
div.col-xs-3.stat-holder
|
||||||
//- div.pull-left.icon-full-width
|
div.row.big-info.chart
|
||||||
//- i.icon-node
|
span.small-title block time
|
||||||
//- div.pull-left
|
span.big-details.spark-blocktimes {{ lastBlocksTime.join(',') }}
|
||||||
//- span.small-title active nodes
|
|
||||||
//- span.big-details {{nodesActive}}/{{nodesTotal}}
|
div.col-xs-3.stat-holder
|
||||||
|
div.row.big-info.chart
|
||||||
|
span.small-title difficulty
|
||||||
|
span.big-details.spark-difficulty {{ difficultyChange.join(',') }}
|
||||||
|
|
||||||
|
div.col-xs-3.stat-holder
|
||||||
|
div.row.big-info.chart
|
||||||
|
span.small-title transactions
|
||||||
|
span.big-details.spark-transactions {{ transactionDensity.join(',') }}
|
||||||
|
|
||||||
|
div.col-xs-3.stat-holder
|
||||||
|
div.row.big-info.chart
|
||||||
|
span.small-title gas spending
|
||||||
|
span.big-details.spark-gasspending {{ gasSpending.join(',') }}
|
||||||
|
|
||||||
//- div.clearfix
|
//- div.clearfix
|
||||||
|
|
||||||
div.clearfix
|
div.col-xs-4
|
||||||
|
|
||||||
div.col-lg-4
|
|
||||||
div.col-xs-12
|
div.col-xs-12
|
||||||
nodemap#mapHolder(data="map")
|
nodemap#mapHolder(data="map")
|
||||||
|
|
||||||
div.clearfix
|
div.clearfix
|
||||||
|
|
||||||
div.col-sm-12
|
div.col-xs-12
|
||||||
//- h1 Nodes in detail
|
//- h1 Nodes in detail
|
||||||
|
|
||||||
table.table.table-striped
|
table.table.table-striped
|
||||||
@ -126,7 +138,7 @@ block content
|
|||||||
td(class="{{ node.stats.block.number | blockClass : bestBlock }}").hidden-sm.hidden-xs
|
td(class="{{ node.stats.block.number | blockClass : bestBlock }}").hidden-sm.hidden-xs
|
||||||
span.small {{node.stats.block.hash | hashFilter}}
|
span.small {{node.stats.block.hash | hashFilter}}
|
||||||
//- div.small Difficulty: {{node.stats.block.difficulty | gasFilter}} | Gas used: {{node.stats.block.gasUsed | gasFilter}} | Min gas price: {{node.stats.block.minGasPrice | gasFilter}} | Gas limit: {{node.stats.block.gasLimit | gasFilter}}
|
//- div.small Difficulty: {{node.stats.block.difficulty | gasFilter}} | Gas used: {{node.stats.block.gasUsed | gasFilter}} | Min gas price: {{node.stats.block.minGasPrice | gasFilter}} | Gas limit: {{node.stats.block.gasLimit | gasFilter}}
|
||||||
td(style="padding-left: 18px;") {{node.stats.block.txCount}}
|
td(style="padding-left: 18px;") {{node.stats.block.transactions.length || 0}}
|
||||||
td(class="{{ node.stats.block.timestamp | timeClass }}") {{node.stats.block.timestamp | blockTimeFilter }}
|
td(class="{{ node.stats.block.timestamp | timeClass }}") {{node.stats.block.timestamp | blockTimeFilter }}
|
||||||
td(class="{{ node.stats.block.received | propagationTimeClass }}") {{node.stats.block.received | blockPropagationFilter}}
|
td(class="{{ node.stats.block.propagation | propagationTimeClass }}") {{node.stats.block.propagation | blockPropagationFilter}}
|
||||||
td(class="{{ node.stats.uptime | upTimeClass }}") {{ node.stats.uptime | upTimeFilter }}
|
td(class="{{ node.stats.uptime | upTimeClass }}") {{ node.stats.uptime | upTimeFilter }}
|
||||||
|
@ -21,6 +21,7 @@ html(ng-app="netStatsApp")
|
|||||||
script(src="/js/lib/datamaps.min.js")
|
script(src="/js/lib/datamaps.min.js")
|
||||||
script(src="/js/lib/moment.min.js")
|
script(src="/js/lib/moment.min.js")
|
||||||
script(src="/js/lib/toastr.min.js")
|
script(src="/js/lib/toastr.min.js")
|
||||||
|
script(src="/js/lib/jquery.sparkline.min.js")
|
||||||
script(src="/js/lib/locale/en-gb.js")
|
script(src="/js/lib/locale/en-gb.js")
|
||||||
script(src="/js/lib/angular-moment.min.js")
|
script(src="/js/lib/angular-moment.min.js")
|
||||||
script(src="/js/lib/bootstrap.min.js")
|
script(src="/js/lib/bootstrap.min.js")
|
||||||
|
Loading…
Reference in New Issue
Block a user