This commit is contained in:
Jonathan Brown
2018-10-29 17:09:30 +07:00
290 changed files with 1810 additions and 178635 deletions

View File

@@ -4,7 +4,6 @@ html {
body {
width: 100%;
min-width: 1900px;
font-smooth: auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
@@ -183,9 +182,9 @@ span.small-title span.small {
}
.big-info.chart .big-details {
display: block;
position: absolute;
display: table;
top: 40px;
margin: 0 auto;
}
.big-info.chart {
@@ -202,6 +201,8 @@ span.small-title span.small {
width: 288px;
padding-top: 6px;
margin-left: -2px;
display: table;
margin: 0 auto;
}
.blocks-holder {
@@ -502,3 +503,51 @@ svg .axis text {
svg .y.axis .tick:first-child text {
opacity: 0;
}
@media (max-width: 768px) {
.container-fluid {
padding-left: 5px;
padding-right: 5px;
}
.big-info .icon-full-width i {
width: 75px;
height: 67px;
font-size: 67px;
margin-left: -25px;
}
.big-info .big-details-holder {
left: 75px;
}
.big-info .big-details {
font-size: 35px;
}
.blocks-holder div.small-title-miner {
font-family: inherit;
font-size: 11px;
letter-spacing: -.5px;
}
.blocks-holder {
width: 100%;
}
.big-info.chart i, .second-row .box i {
font-size: 18px;
margin-right: 0px;
}
.second-row .box {
height: 100%; /* BUG XXX */
}
}
@media (max-width: 600px) {
.blocks-holder div.small-title-miner {
font-size: 10px;
}
}

View File

@@ -100,6 +100,24 @@ angular.module('netStatsApp.directives', [])
{
tElement.replaceWith('<span>' + tAttrs.data + "</span>");
// register resize watcher
var timeout;
var width;
$(window).on('resize', function(e) {
if( $('body').width() < 600 )
width = 4;
else if( $('body').width() < 1200 )
width = 5;
else
width = 6;
if(timeout)
clearTimeout(timeout);
timeout = setTimeout(function() {
$.fn.sparkline.defaults.bar.barWidth = width;
}, 200);
});
return function(scope, element, attrs)
{
attrs.$observe("data", function (newValue)
@@ -302,6 +320,12 @@ angular.module('netStatsApp.directives', [])
var width = 280 - margin.left - margin.right,
height = 63 - margin.top - margin.bottom;
// fix for mobile devices
if( $('body').width() < 600 )
width = 200 - margin.left - margin.right;
else( $('body').width() < 1200 )
width = 240 - margin.left - margin.right;
var TICKS = 40;
var x = d3.scale.linear()
@@ -342,10 +366,26 @@ angular.module('netStatsApp.directives', [])
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()
scope.init = function(width)
{
var data = scope.data;
var x = d3.scale.linear()
.domain([0, 10000])
.rangeRound([0, width])
.interpolate(d3.interpolateRound);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(4, ",.1s")
.tickFormat(function(t){ return t/1000 + "s"});
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');
// Adjust y axis
y.domain([0, d3.max(data, function(d) { return d.y; })]);
@@ -414,9 +454,24 @@ angular.module('netStatsApp.directives', [])
scope.$watch('data', function() {
if(scope.data.length > 0) {
scope.init();
scope.init(width);
}
}, true);
var timeout;
$(window).on('resize', function(e) {
var width = 280 - margin.left - margin.right;
if( $('body').width() < 768 )
width = 200 - margin.left - margin.right;
if(timeout)
clearTimeout(timeout);
timeout = setTimeout(function() {
// redraw
scope.init(width);
}, 200);
});
}
};
}]);

View File

@@ -59,35 +59,17 @@ angular.module('netStatsApp.filters', [])
})
.filter('hashrateFilter', ['$sce', '$filter', function($sce, filter) {
return function(hashes, isMining) {
var result = 0;
var unit = 'K';
if( !isMining )
return $sce.trustAsHtml('<i class="icon-cancel"></i>');
if(hashes !== 0 && hashes < 1000) {
result = hashes;
unit = '';
}
var result = hashes;
var units = ['', 'K', 'M', 'G', 'T', 'P', 'E'];
var unit = 'K';
if(hashes >= 1000 && hashes < Math.pow(1000, 2)) {
result = hashes / 1000;
unit = 'K';
}
if(hashes >= Math.pow(1000, 2) && hashes < Math.pow(1000, 3)) {
result = hashes / Math.pow(1000, 2);
unit = 'M';
}
if(hashes >= Math.pow(1000, 3) && hashes < Math.pow(1000, 4)) {
result = hashes / Math.pow(1000, 3);
unit = 'G';
}
if(hashes >= Math.pow(1000, 4) && hashes < Math.pow(1000, 5)) {
result = hashes / Math.pow(1000, 4);
unit = 'T';
for(var i = 1; result > 1000; i++)
{
result /= 1000;
unit = units[i];
}
return $sce.trustAsHtml('<span class="small">' + filter('number')(result.toFixed(1)) + ' <span class="small-hash">' + unit + 'H/s</span></span>');
@@ -95,32 +77,14 @@ angular.module('netStatsApp.filters', [])
}])
.filter('totalDifficultyFilter', function() {
return function(hashes) {
var result = 0;
var result = hashes;
var units = ['', 'K', 'M', 'G', 'T', 'P', 'E'];
var unit = '';
if(hashes !== 0 && hashes < 1000) {
result = hashes;
unit = '';
}
if(hashes >= 1000 && hashes < Math.pow(1000, 2)) {
result = hashes / 1000;
unit = 'K';
}
if(hashes >= Math.pow(1000, 2) && hashes < Math.pow(1000, 3)) {
result = hashes / Math.pow(1000, 2);
unit = 'M';
}
if(hashes >= Math.pow(1000, 3) && hashes < Math.pow(1000, 4)) {
result = hashes / Math.pow(1000, 3);
unit = 'G';
}
if(hashes >= Math.pow(1000, 4) && hashes < Math.pow(1000, 5)) {
result = hashes / Math.pow(1000, 4);
unit = 'T';
for(var i = 1; result > 1000; i++)
{
result /= 1000;
unit = units[i];
}
return result.toFixed(2) + ' ' + unit + 'H';
@@ -327,32 +291,14 @@ angular.module('netStatsApp.filters', [])
if(hashes === null)
hashes = 0;
var result = 0;
var result = hashes;
var units = ['', 'K', 'M', 'G', 'T', 'P'];
var unit = 'K';
if(hashes !== 0 && hashes < 1000) {
result = hashes;
unit = '';
}
if(hashes >= 1000 && hashes < Math.pow(1000, 2)) {
result = hashes / 1000;
unit = 'K';
}
if(hashes >= Math.pow(1000, 2) && hashes < Math.pow(1000, 3)) {
result = hashes / Math.pow(1000, 2);
unit = 'M';
}
if(hashes >= Math.pow(1000, 3) && hashes < Math.pow(1000, 4)) {
result = hashes / Math.pow(1000, 3);
unit = 'G';
}
if(hashes >= Math.pow(1000, 4) && hashes < Math.pow(1000, 5)) {
result = hashes / Math.pow(1000, 4);
unit = 'T';
for(var i = 1; result > 1000; i++)
{
result /= 1000;
unit = units[i];
}
if( !isMining )

View File

@@ -7,6 +7,11 @@
$.fn.sparkline.defaults.bar.height = 63;
$.fn.sparkline.defaults.bar.barWidth = 6;
if( $('body').width() < 600 )
$.fn.sparkline.defaults.bar.barWidth = 4;
else if( $('body').width() < 1200 )
$.fn.sparkline.defaults.bar.barWidth = 5;
$.fn.sparkline.defaults.bar.barSpacing = 1;
$.fn.sparkline.defaults.bar.tooltipClassname = 'jqstooltip';
$.fn.sparkline.defaults.bar.tooltipOffsetX = 0;

3
src/robots.txt Normal file
View File

@@ -0,0 +1,3 @@
# http://www.robotstxt.org
User-agent: *
Disallow:

View File

@@ -4,7 +4,7 @@ extends ./layout.jade
block content
div.container-fluid(ng-controller='StatsCtrl')
div.row(ng-cloak)
div.col-xs-2.stat-holder
div.col-xs-6.col-sm-6.col-md-6.col-lg-2.stat-holder
div.big-info.bestblock.text-info
div.pull-left.icon-full-width
i.icon-block
@@ -12,16 +12,16 @@ block content
span.small-title best block
span.big-details {{'#'}}{{ bestBlock | number}}
div.clearfix
div.col-xs-2.stat-holder
div.col-xs-6.col-sm-6.col-md-6.col-lg-2.stat-holder
div.big-info.uncleCount.text-info
div.pull-left.icon-full-width
i.icon-uncle
div.big-details-holder
span.small-title uncles&nbsp;
span.small (current / last 50)
span.small.hidden-xs (current / last 50)
span.big-details {{ bestStats.block.uncles.length }}/{{ uncleCount }}
div.clearfix
div.col-xs-2.stat-holder
div.col-xs-6.col-sm-6.col-md-6.col-lg-2.stat-holder
div.big-info.blocktime(class="{{ lastBlock | timeClass : true }}")
div.pull-left.icon-full-width
i.icon-time
@@ -30,7 +30,7 @@ block content
span.big-details {{ lastBlock | blockTimeFilter }}
//- span.big-details(time-ago="lastBlock")
div.clearfix
div.col-xs-2.stat-holder
div.col-xs-6.col-sm-6.col-md-6.col-lg-2.stat-holder
div.big-info.avgblocktime(class="{{ avgBlockTime | avgTimeClass }}")
div.pull-left.icon-full-width
i.icon-gas
@@ -38,15 +38,18 @@ block content
span.small-title avg block time
span.big-details {{ avgBlockTime | avgTimeFilter }}
div.clearfix
div.col-xs-2.stat-holder
div.col-xs-6.col-sm-6.col-md-6.col-lg-2.stat-holder
div.big-info.difficulty.text-orange
div.pull-left.icon-full-width
i.icon-hashrate
div.big-details-holder
span.small-title avg network hashrate
span.small-title
span.hidden-xs avg&nbsp;
| network hash
span.hidden-xs rate
span.big-details(ng-bind-html="avgHashrate | networkHashrateFilter")
div.clearfix
div.col-xs-2.stat-holder
div.col-xs-6.col-sm-6.col-md-6.col-lg-2.stat-holder
div.big-info.difficulty.text-danger
div.pull-left.icon-full-width
i.icon-difficulty
@@ -62,88 +65,88 @@ block content
div.row(ng-cloak)
div.col-xs-12.stats-boxes(style="padding-top: 0px;")
div.row.second-row
div.col-xs-2.stat-holder.box
div.col-xs-6.col-sm-6.col-md-6.col-lg-2.stat-holder.box
div.active-nodes(class="{{ nodesActive | nodesActiveClass : nodesTotal }}")
i.icon-node
span.small-title active nodes
span.small-value {{nodesActive}}/{{nodesTotal}}
div.col-xs-2.stat-holder.box
div.col-xs-6.col-sm-6.col-md-6.col-lg-2.stat-holder.box
div.gasprice.text-info
i.icon-gasprice
span.small-title gas price
span.small-value {{ bestStats.gasPrice.toString() | gasPriceFilter }}
div.col-xs-2.stat-holder.box
div.col-xs-6.col-sm-6.col-md-6.col-lg-2.stat-holder.box
div.gasprice.text-info
i.icon-gasprice
span.small-title gas limit
span.small-value {{ bestStats.block.gasLimit }} gas
div.col-xs-2.stat-holder.box
span.small-value {{ bestStats.block.gasLimit | number }} gas
div.col-xs-6.col-sm-6.col-md-6.col-lg-2.stat-holder.box
div.page-latency(class="{{ {active: true, latency: latency} | latencyClass }}")
i.icon-clock
span.small-title page latency
span.small-value {{latency}} ms
div.col-xs-2.stat-holder.box
div.col-xs-6.col-sm-6.col-md-6.col-lg-2.stat-holder.box
div.uptime(class="{{ upTimeTotal | upTimeClass : true }}")
i.icon-bulb
span.small-title uptime
span.small-value {{ upTimeTotal | upTimeFilter }}
div.col-xs-2.stat-holder.box
div.col-xs-6.col-sm-6.col-md-6.col-lg-2.stat-holder.box
div.row
div.col-xs-8
div.col-xs-12.col-sm-12.col-md-12.col-lg-8
div.row
div.col-xs-3.stat-holder
div.col-xs-6.col-sm-4.col-md-3.stat-holder
div.big-info.chart(class="{{ avgBlockTime | avgTimeClass }}")
//- i.icon-time
span.small-title block time
//- span.small-value {{ avgBlockTime | avgTimeFilter }}
sparkchart.big-details.spark-blocktimes(data="{{lastBlocksTime.join(',')}}", tooltipsuffix="s")
div.col-xs-3.stat-holder
div.col-xs-6.col-sm-4.col-md-3.stat-holder
div.big-info.chart.text-info
//- i.icon-difficulty
span.small-title difficulty
//- span.small-value {{ lastDifficulty | number }}
sparkchart.big-details.spark-difficulty(data="{{difficultyChart.join(',')}}")
div.col-xs-3.stat-holder.xpull-right
div.col-xs-6.col-sm-4.col-md-3.stat-holder.xpull-right
div.big-info.chart.xdouble-chart(class="{{ blockPropagationAvg | propagationAvgTimeClass : true }}")
//- i.icon-gas
span.small-title block propagation
//- span.small-value {{ blockPropagationAvg | blockPropagationFilter : '' }}
histogram.big-details.d3-blockpropagation(data="blockPropagationChart")
div.col-xs-3.stat-holder.xpull-right
div.col-xs-6.col-sm-4.col-md-3.stat-holder.xpull-right
div.big-info.chart.xdouble-chart
span.small-title last blocks miners
div.blocks-holder(ng-repeat='miner in miners track by miner.miner', data-toggle="tooltip", data-placement="right", data-original-title="{{miner.blocks}}")
div.block-count(class="{{miner.blocks | minerBlocksClass : 'text-'}}") {{miner.blocks}}
//- div.small-title-miner {{miner.miner | minerNameFilter : miner.name}}
div.small-title-miner {{miner.miner}}
div.block-count(class="{{miner.blocks | minerBlocksClass : 'text-'}}") {{miner.blocks}}
minerblock(blocks="{{miner.blocks}}")
div.clearfix
div.col-xs-3.stat-holder
div.col-xs-6.col-sm-4.col-md-3.stat-holder
div.big-info.chart.text-info
//- i.icon-uncle
span.small-title uncle count&nbsp;
span.small (25 blocks per bar)
span.small.hidden-xs (25 blocks per bar)
//- span.small-value {{ bestStats.block.uncles.length }}/{{ uncleCount }}
sparkchart.big-details.spark-uncles(data="{{uncleCountChart.join(',')}}")
div.col-xs-3.stat-holder
div.col-xs-6.col-sm-4.col-md-3.stat-holder
div.big-info.chart.text-info
//- i.icon-uncle
span.small-title transactions
sparkchart.big-details.spark-transactions(data="{{transactionDensity.join(',')}}")
div.col-xs-3.stat-holder
div.col-xs-6.col-sm-4.col-md-3.stat-holder
div.big-info.chart.text-info
//- i.icon-gasprice
span.small-title gas spending
sparkchart.big-details.spark-gasspending(data="{{gasSpending.join(',')}}")
div.col-xs-3.stat-holder
div.col-xs-6.col-sm-4.col-md-3.stat-holder
div.big-info.chart.text-info
//- i.icon-difficulty
span.small-title gas limit
@@ -152,28 +155,13 @@ block content
div.col-xs-4.stat-holder.map-holder
div.col-xs-12.col-sm-12.col-md-12.col-lg-4.stat-holder.map-holder
//- div.col-xs-12
nodemap#mapHolder(data="map")
div.row
div.row.hidden-xs
div.col-xs-12.stats-boxes
div.row.second-row
div.col-xs-12.stat-holder.box
div.active-nodes.text-warning
i.icon-warning-o
span.small-title ATTENTION!
span.small-value This page does not represent the entire state of the MIX network - listing a node on this page is a voluntary process.
//- div.col-xs-12.stat-holder.box
//- div.active-nodes.text-danger
//- i.icon-hashrate
//- span.small-title SECURITY ALERT
//- span.small-value
//- a(href="https://blog.ethereum.org/2015/09/10/security-alert-previous-security-patch-can-lead-to-invalid-state-root-on-go-clients-with-a-specific-transaction-sequence-fixed-please-update/", target="_blank", class="text-danger") Read the blog post
//- div.clearfix
div.row(ng-cloak, style="padding-top: 10px")
table.table.table-striped
thead
@@ -182,31 +170,31 @@ block content
i.icon-check-o(data-toggle="tooltip", data-placement="top", title="Pin nodes to display first", ng-click="orderTable(['-stats.block.number', 'stats.block.propagation'], false)")
th.th-nodename
i.icon-node(data-toggle="tooltip", data-placement="top", title="Node name", ng-click="orderTable(['info.name'], false)")
th.th-nodetype
th.th-nodetype.hidden-xs
i.icon-laptop(data-toggle="tooltip", data-placement="top", title="Node type", ng-click="orderTable(['info.node'], false)")
th.th-latency
th.th-latency.hidden-xs
i.icon-clock(data-toggle="tooltip", data-placement="top", title="Node latency", ng-click="orderTable(['stats.latency'], false)")
th
th.hidden-xs
i.icon-mining(data-toggle="tooltip", data-placement="top", title="Is mining", ng-click="orderTable(['-stats.hashrate'], false)")
th
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.hidden-xs
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
th.th-blockhash.hidden-xs.hidden-sm.hidden-md &nbsp;
th.th-blockhash.hidden-xs.hidden-sm.hidden-md
i.icon-difficulty(data-toggle="tooltip", data-placement="top", title="Total difficulty", ng-click="orderTable(['-stats.block.totalDifficulty'], false)")
th
th.hidden-xs
i.icon-check-o(data-toggle="tooltip", data-placement="top", title="Block transactions", ng-click="orderTable(['-stats.block.transactions.length'], false)")
th
th.hidden-xs
i.icon-uncle(data-toggle="tooltip", data-placement="top", title="Uncles", ng-click="orderTable(['-stats.block.uncles.length'], false)")
th.th-blocktime
i.icon-time(data-toggle="tooltip", data-placement="top", title="Last block time", ng-click="orderTable(['-stats.block.received'], false)")
th.th-peerPropagationTime
i.icon-gas(data-toggle="tooltip", data-placement="top", title="Propagation time", ng-click="orderTable(['-stats.block.number', 'stats.block.propagation'], false)")
th.th-peerPropagationChart
th.th-peerPropagationAvg
th.th-peerPropagationAvg.hidden-xs
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)")
@@ -219,28 +207,28 @@ block content
//- span.small &nbsp;({{node.info.ip}})
a.small(href="https://github.com/ethereum/wiki/wiki/Network-Status#updating", target="_blank", data-toggle="tooltip", data-placement="top", data-html="true", data-original-title="Netstats client needs update.<br>Click this icon for instructions.", class="{{ node.info | nodeClientClass : currentApiVersion }}")
i.icon-warning-o
td
td.hidden-xs
div.small(ng-bind-html="node.info.node | nodeVersion")
td(class="{{ node.readable.latencyClass }}")
td(class="{{ node.readable.latencyClass }}").hidden-xs
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.mining | hashrateClass : node.stats.active }}", ng-bind-html="node.stats.hashrate | hashrateFilter : node.stats.mining").hidden-xs
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 }}").hidden-xs
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 }}")
i.icon-warning-o
td(class="{{ node.stats | blockClass : bestBlock }}")
td(class="{{ node.stats | blockClass : bestBlock }}").hidden-xs.hidden-sm.hidden-md
span.small {{node.stats.block.hash | hashFilter}}
td(class="{{ node.stats | blockClass : bestBlock }}")
td(class="{{ node.stats | blockClass : bestBlock }}").hidden-xs.hidden-sm.hidden-md
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(style="padding-left: 14px;").hidden-xs {{node.stats.block.transactions.length || 0}}
td(style="padding-left: 14px;").hidden-xs {{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 | propagationTimeClass : bestBlock }}")
div.propagationBox
span {{node.stats.block.propagation | blockPropagationFilter}}
td.peerPropagationChart(class="{{node.id}}")
nodepropagchart(data="{{node.history.join(',')}}")
td(class="{{ node.stats | propagationNodeAvgTimeClass : bestBlock }}") {{ node.stats | blockPropagationAvgFilter : bestBlock }}
td(class="{{ node.stats | propagationNodeAvgTimeClass : bestBlock }}").hidden-xs {{ node.stats | blockPropagationAvgFilter : bestBlock }}
td(class="{{ node.stats.uptime | upTimeClass : node.stats.active }}") {{ node.stats.uptime | upTimeFilter }}

View File

@@ -12,6 +12,8 @@ html(ng-app="netStatsApp")
link(rel='shortcut icon', href='/mix-logo-thick-256.png', sizes='256x256' type='image/png')
link(rel='shortcut icon', href='/mix-logo-thick-128.png', sizes='128x128' type='image/png')
link(rel='shortcut icon', href='/mix-logo-thick-64.png', sizes='64x64' type='image/png')
meta(name='robots', content='index,follow')
meta(name='googlebot', content='index,follow')
body
block content