commit
7fc6676dc0
@ -1,12 +1,14 @@
|
|||||||
var _ = require('lodash');
|
var _ = require('lodash');
|
||||||
|
|
||||||
var MAX_HISTORY = 1008;
|
var MAX_HISTORY = 1008;
|
||||||
var MAX_PROPAGATION = 36;
|
var MAX_PEER_PROPAGATION = 36;
|
||||||
var MAX_BLOCK_PROPAGATION = 96;
|
var MAX_BLOCK_PROPAGATION = 96;
|
||||||
|
var MIN_PROPAGATION_RANGE = 1;
|
||||||
|
var MAX_PROPAGATION_RANGE = 20000;
|
||||||
|
var MAX_BINS = 40;
|
||||||
|
|
||||||
var History = function History(data)
|
var History = function History(data)
|
||||||
{
|
{
|
||||||
// this._items = new Array(MAX_HISTORY);
|
|
||||||
this._items = [];
|
this._items = [];
|
||||||
|
|
||||||
var item = {
|
var item = {
|
||||||
@ -24,8 +26,6 @@ var History = function History(data)
|
|||||||
},
|
},
|
||||||
propagTimes: []
|
propagTimes: []
|
||||||
};
|
};
|
||||||
|
|
||||||
// _.fill(this._items, item);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
History.prototype.add = function(block, id)
|
History.prototype.add = function(block, id)
|
||||||
@ -99,18 +99,20 @@ History.prototype.bestBlock = function(obj)
|
|||||||
|
|
||||||
History.prototype.getNodePropagation = function(id)
|
History.prototype.getNodePropagation = function(id)
|
||||||
{
|
{
|
||||||
var propagation = new Array(MAX_PROPAGATION);
|
var propagation = new Array(MAX_PEER_PROPAGATION);
|
||||||
var bestBlock = this.bestBlock().height;
|
var bestBlock = this.bestBlock().height;
|
||||||
|
|
||||||
|
|
||||||
_.fill(propagation, -1);
|
_.fill(propagation, -1);
|
||||||
|
|
||||||
var sorted = _(this._items)
|
var sorted = _(this._items)
|
||||||
.sortByOrder('height', false)
|
.sortByOrder('height', false)
|
||||||
.slice(0, MAX_PROPAGATION)
|
.slice(0, MAX_PEER_PROPAGATION)
|
||||||
.reverse()
|
.reverse()
|
||||||
.forEach(function(n, key)
|
.forEach(function(n, key)
|
||||||
{
|
{
|
||||||
var index = MAX_PROPAGATION - 1 - bestBlock + n.height;
|
var index = MAX_PEER_PROPAGATION - 1 - bestBlock + n.height;
|
||||||
|
|
||||||
|
|
||||||
if(index > 0)
|
if(index > 0)
|
||||||
{
|
{
|
||||||
@ -124,27 +126,21 @@ History.prototype.getNodePropagation = function(id)
|
|||||||
|
|
||||||
History.prototype.getBlockPropagation = function()
|
History.prototype.getBlockPropagation = function()
|
||||||
{
|
{
|
||||||
var propagation = new Array(MAX_BLOCK_PROPAGATION);
|
var propagation = [];
|
||||||
var bestBlock = this.bestBlock().height;
|
|
||||||
var i = 0;
|
|
||||||
|
|
||||||
_.fill(propagation, -1);
|
|
||||||
|
|
||||||
var sorted = _(this._items)
|
var sorted = _(this._items)
|
||||||
.sortByOrder('height', false)
|
.sortByOrder('height', false)
|
||||||
.slice(0, MAX_PROPAGATION)
|
.slice(0, MAX_BLOCK_PROPAGATION)
|
||||||
.reverse()
|
.reverse()
|
||||||
.forEach(function(n, key)
|
.forEach(function(n, key)
|
||||||
{
|
|
||||||
if(i < MAX_BLOCK_PROPAGATION)
|
|
||||||
{
|
{
|
||||||
_.forEach(n.propagTimes, function(p, i)
|
_.forEach(n.propagTimes, function(p, i)
|
||||||
{
|
{
|
||||||
propagation.push({block: n.height, propagation: _.result(p, 'propagation', -1)});
|
var prop = _.result(p, 'propagation', -1);
|
||||||
propagation.shift();
|
|
||||||
i++;
|
if(prop >= 0)
|
||||||
|
propagation.push(prop);
|
||||||
});
|
});
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.value();
|
.value();
|
||||||
|
|
||||||
|
@ -52,8 +52,6 @@ var Node = function Node(data)
|
|||||||
this.info = data.info;
|
this.info = data.info;
|
||||||
|
|
||||||
if(typeof data.ip !== 'undefined'){
|
if(typeof data.ip !== 'undefined'){
|
||||||
if(data.ip === '::ffff:127.0.0.1')
|
|
||||||
data.ip = '84.117.82.122';
|
|
||||||
this.info.ip = data.ip;
|
this.info.ip = data.ip;
|
||||||
this.setGeo(data.ip);
|
this.setGeo(data.ip);
|
||||||
}
|
}
|
||||||
|
@ -114,7 +114,7 @@ div.small-title-miner {
|
|||||||
color: #aaa;
|
color: #aaa;
|
||||||
}
|
}
|
||||||
|
|
||||||
.big-info span.big-details {
|
.big-info .big-details {
|
||||||
display: block;
|
display: block;
|
||||||
font-weight: 200;
|
font-weight: 200;
|
||||||
font-size: 50px;
|
font-size: 50px;
|
||||||
@ -122,7 +122,7 @@ div.small-title-miner {
|
|||||||
letter-spacing: -4px;
|
letter-spacing: -4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.big-info.chart span.big-details {
|
.big-info.chart .big-details {
|
||||||
padding-top: 15px;
|
padding-top: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,7 +157,7 @@ div.small-title-miner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.blocks-holder .block-count {
|
.blocks-holder .block-count {
|
||||||
font-family: 'Lucida Console', monaco, "Courier New", Courier, monospace;
|
font-family: 'Lucida Console', "Courier New", Courier, monospace;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
padding-top: 3px;
|
padding-top: 3px;
|
||||||
@ -230,6 +230,11 @@ table td i:before {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.th-nodename {
|
.th-nodename {
|
||||||
|
width: 300px;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.th-nodetype {
|
||||||
width: 200px;
|
width: 200px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -320,3 +325,48 @@ table td i:before {
|
|||||||
.hoverinfo .propagationBox {
|
.hoverinfo .propagationBox {
|
||||||
top: 3px;
|
top: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
svg {
|
||||||
|
overflow: visible !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
svg .bar {
|
||||||
|
fill: #1f77b4;
|
||||||
|
shape-rendering: crispEdges;
|
||||||
|
}
|
||||||
|
|
||||||
|
svg .bar:hover {
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
svg .line {
|
||||||
|
fill: none;
|
||||||
|
stroke: #ff0000;
|
||||||
|
stroke-width: 2px;
|
||||||
|
shape-rendering: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
svg .bar .a {
|
||||||
|
fill: #aec7e8;
|
||||||
|
}
|
||||||
|
|
||||||
|
svg .bar text {
|
||||||
|
text-anchor: end;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
svg .axis path,
|
||||||
|
svg .axis line {
|
||||||
|
fill: none;
|
||||||
|
stroke: rgba(255,255,255,0.15);
|
||||||
|
shape-rendering: crispEdges;
|
||||||
|
}
|
||||||
|
svg .axis text {
|
||||||
|
fill: #777;
|
||||||
|
font-size: 10px;
|
||||||
|
letter-spacing: 0px;
|
||||||
|
font-family: "Source Sans Pro";
|
||||||
|
font-weight: 700;
|
||||||
|
-webkit-font-smoothing: subpixel-antialiased;
|
||||||
|
-moz-font-smoothing: subpixel-antialiased;
|
||||||
|
}
|
BIN
public/fonts/Simple-Line-Icons.ttf
Executable file
BIN
public/fonts/Simple-Line-Icons.ttf
Executable file
Binary file not shown.
@ -24,6 +24,7 @@ function StatsCtrl($scope, $filter, socket, _, toastr) {
|
|||||||
|
|
||||||
$scope.nodes = [];
|
$scope.nodes = [];
|
||||||
$scope.map = [];
|
$scope.map = [];
|
||||||
|
$scope.blockPropagationChart = [];
|
||||||
|
|
||||||
$scope.latency = 0;
|
$scope.latency = 0;
|
||||||
|
|
||||||
@ -125,7 +126,6 @@ function StatsCtrl($scope, $filter, socket, _, toastr) {
|
|||||||
|
|
||||||
case "blockPropagationChart":
|
case "blockPropagationChart":
|
||||||
$scope.blockPropagationChart = data;
|
$scope.blockPropagationChart = data;
|
||||||
makeBlockPropagationChart();
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -175,31 +175,6 @@ function StatsCtrl($scope, $filter, socket, _, toastr) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeBlockPropagationChart()
|
|
||||||
{
|
|
||||||
jQuery('.spark-blockpropagation').sparkline(_.map($scope.blockPropagationChart, function(history) {
|
|
||||||
if(typeof history.propagation === 'undefined')
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return history.propagation;
|
|
||||||
}), {
|
|
||||||
type: 'bar',
|
|
||||||
negBarColor: '#7f7f7f',
|
|
||||||
zeroAxis: false,
|
|
||||||
barWidth : 2,
|
|
||||||
barSpacing : 1,
|
|
||||||
tooltipSuffix: ' ms',
|
|
||||||
chartRangeMax: 8000,
|
|
||||||
colorMap: jQuery.range_map({
|
|
||||||
'0:1': '#10a0de',
|
|
||||||
'1:1000': '#7bcc3a',
|
|
||||||
'1001:3000': '#FFD162',
|
|
||||||
'3001:7000': '#ff8a00',
|
|
||||||
'7001:': '#F74B4B'
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function addNewNode(data)
|
function addNewNode(data)
|
||||||
{
|
{
|
||||||
var index = findIndex({id: data.id});
|
var index = findIndex({id: data.id});
|
||||||
|
@ -75,4 +75,96 @@ angular.module('netStatsApp.directives', []).
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}]).
|
||||||
|
directive('histogram', ['$compile', function($compile) {
|
||||||
|
return {
|
||||||
|
restrict: 'EA',
|
||||||
|
scope: {
|
||||||
|
data: '='
|
||||||
|
},
|
||||||
|
link: function(scope, element, attrs) {
|
||||||
|
var margin = {top: 0, right: 0, bottom: 0, left: 5};
|
||||||
|
var width = 285 - margin.left - margin.right,
|
||||||
|
height = 173 - margin.top - margin.bottom;
|
||||||
|
|
||||||
|
var TICKS = 40;
|
||||||
|
|
||||||
|
var x = d3.scale.linear()
|
||||||
|
.domain([0, 20000])
|
||||||
|
.rangeRound([0, width])
|
||||||
|
.interpolate(d3.interpolateRound);
|
||||||
|
|
||||||
|
var y = d3.scale.linear()
|
||||||
|
.range([height, 0])
|
||||||
|
.interpolate(d3.interpolateRound);
|
||||||
|
|
||||||
|
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(4);
|
||||||
|
|
||||||
|
var line = d3.svg.line()
|
||||||
|
.x(function(d) { return x(d.x + d.dx); })
|
||||||
|
.y(function(d) { return y(d.y); })
|
||||||
|
.interpolate('basis');
|
||||||
|
|
||||||
|
scope.init = function() {
|
||||||
|
|
||||||
|
var data = d3.layout.histogram()
|
||||||
|
.frequency(true)
|
||||||
|
.bins(x.ticks(TICKS))
|
||||||
|
(scope.data);
|
||||||
|
|
||||||
|
y.domain([0, d3.max(data, function(d) { return d.y; })]);
|
||||||
|
|
||||||
|
element.empty();
|
||||||
|
|
||||||
|
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.append("g")
|
||||||
|
.attr("class", "x axis")
|
||||||
|
.attr("transform", "translate(0," + height + ")")
|
||||||
|
// .attr("transform", "translate(0,0)")
|
||||||
|
.call(xAxis);
|
||||||
|
|
||||||
|
svg.append("g")
|
||||||
|
.attr("class", "y axis")
|
||||||
|
.attr("transform", "translate(0, 0)")
|
||||||
|
// .attr("transform", "translate(" + width + ", 0)")
|
||||||
|
.call(yAxis);
|
||||||
|
|
||||||
|
|
||||||
|
svg.selectAll(".bar")
|
||||||
|
.data(data)
|
||||||
|
.enter().insert("rect", ".axis")
|
||||||
|
.attr("class", "bar")
|
||||||
|
.attr("x", function(d) { return x(d.x) + 1; })
|
||||||
|
.attr("y", function(d) { return y(d.y); })
|
||||||
|
.attr("rx", 1.5)
|
||||||
|
.attr("ry", 1.5)
|
||||||
|
.attr("width", x(data[0].dx + data[0].x) - x(data[0].x) - 1)
|
||||||
|
.attr("height", function(d) { return height - y(d.y); });
|
||||||
|
|
||||||
|
svg.append("path")
|
||||||
|
.attr("class", "line")
|
||||||
|
.attr("d", line(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
scope.init();
|
||||||
|
|
||||||
|
scope.$watch('data', function() {
|
||||||
|
scope.init();
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
};
|
||||||
}]);
|
}]);
|
@ -50,6 +50,11 @@ angular.module('netStatsApp.filters', [])
|
|||||||
|
|
||||||
tmp[0] = tmp[0].replace('Ethereum(++)', 'Eth');
|
tmp[0] = tmp[0].replace('Ethereum(++)', 'Eth');
|
||||||
|
|
||||||
|
if(tmp[0].indexOf('pyethapp') === 0)
|
||||||
|
{
|
||||||
|
tmp[0] = 'pyeth';
|
||||||
|
}
|
||||||
|
|
||||||
if(tmp[1][0] !== 'v' && tmp[1][2] !== '.')
|
if(tmp[1][0] !== 'v' && tmp[1][2] !== '.')
|
||||||
{
|
{
|
||||||
tmp.splice(1,1);
|
tmp.splice(1,1);
|
||||||
|
@ -24,4 +24,52 @@
|
|||||||
moment.relativeTimeThreshold('h', 24);
|
moment.relativeTimeThreshold('h', 24);
|
||||||
moment.relativeTimeThreshold('d', 28);
|
moment.relativeTimeThreshold('d', 28);
|
||||||
moment.relativeTimeThreshold('M', 12);
|
moment.relativeTimeThreshold('M', 12);
|
||||||
|
|
||||||
|
|
||||||
|
json = [4292,12436,13141,14268,14650,0,55,774,891,1045,1184,1520,1786,1819,2103,2523,2846,2895,3010,3219,13046,0,284,507,525,1410,1531,1673,1803,1978,2652,2961,4224,4863,5056,12281,0,561,812,903,2161,2210,2312,2450,2559,2725,3273,4559,4727,5868,7777,0,1621,6982,9008,14035,0,1181,2753,2782,3580,3945,5779,7936,21489,0,196,1587,1611,1648,2603,2998,3802,4265,4464,5323,5606,6551,9982,10417,0,884,989,1202,1247,1282,2297,2577,2735,2935,3288,4261,4652,4706,4855,6509];
|
||||||
|
|
||||||
|
// var data = lineData = d3.layout.histogram()
|
||||||
|
// .frequency(true)
|
||||||
|
// .bins(x.ticks(40))
|
||||||
|
// (json);
|
||||||
|
|
||||||
|
// y.domain([0, d3.max(data, function(d) { return d.y; })]);
|
||||||
|
|
||||||
|
/* Start drawing */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// d3.tsv("histogram.tsv", type, function(error, histogram) {
|
||||||
|
// var n = d3.sum(histogram, function(d) { return d.y = d.a; });
|
||||||
|
|
||||||
|
// y.domain([0, d3.max(histogram, function(d) { return d.y; })]);
|
||||||
|
|
||||||
|
// var bar = svg.insert("g", ".axis")
|
||||||
|
// .attr("class", "bar")
|
||||||
|
// .selectAll("g")
|
||||||
|
// .data(histogram)
|
||||||
|
// .enter().append("g")
|
||||||
|
// .attr("transform", function(d) { return "translate(" + x(d.x) + ",0)"; });
|
||||||
|
|
||||||
|
// bar.append("rect")
|
||||||
|
// .attr("class", "b")
|
||||||
|
// .attr("x", 1)
|
||||||
|
// .attr("y", function(d) { return y(d.b); })
|
||||||
|
// .attr("width", x(histogram[0].dx) - 1)
|
||||||
|
// .attr("height", function(d) { return height - y(d.b); });
|
||||||
|
|
||||||
|
// bar.append("rect")
|
||||||
|
// .attr("class", "a")
|
||||||
|
// .attr("x", 1)
|
||||||
|
// .attr("y", function(d) { return y(d.y); })
|
||||||
|
// .attr("width", x(histogram[0].dx) - 1)
|
||||||
|
// .attr("height", function(d) { return height - y(d.a); });
|
||||||
|
|
||||||
|
// bar.filter(function(d) { return d.y / n >= .0095; }).append("text")
|
||||||
|
// .attr("dy", ".015em")
|
||||||
|
// .attr("transform", function(d) { return "translate(" + x(histogram[0].dx) / 2 + "," + (y(1000) + 6) + ")rotate(-90)"; })
|
||||||
|
// // .attr("transform", function(d) { return "translate(" + x(histogram[0].dx) / 2 + "," + (y(d.y) + 6) + ")rotate(-90)"; })
|
||||||
|
// .text(function(d) { return formatPercent(d.y / n); });
|
||||||
|
// });
|
||||||
|
|
||||||
})();
|
})();
|
@ -2,7 +2,7 @@ extends layout
|
|||||||
|
|
||||||
block content
|
block content
|
||||||
div.container-fluid(ng-controller='StatsCtrl')
|
div.container-fluid(ng-controller='StatsCtrl')
|
||||||
div.page-latency
|
div.page-latency(ng-cloak)
|
||||||
span.small-title page latency:#[ ]
|
span.small-title page latency:#[ ]
|
||||||
span(class="{{ {active: true, latency: latency} | latencyClass }}") {{latency}} ms
|
span(class="{{ {active: true, latency: latency} | latencyClass }}") {{latency}} ms
|
||||||
div.row(ng-cloak)
|
div.row(ng-cloak)
|
||||||
@ -65,16 +65,16 @@ block content
|
|||||||
span.small-title block time
|
span.small-title block time
|
||||||
span.big-details.spark-blocktimes
|
span.big-details.spark-blocktimes
|
||||||
|
|
||||||
div.col-xs-4.stat-holder
|
|
||||||
div.big-info.chart
|
|
||||||
span.small-title block propagation
|
|
||||||
span.big-details.spark-blockpropagation
|
|
||||||
|
|
||||||
div.col-xs-4.stat-holder
|
div.col-xs-4.stat-holder
|
||||||
div.big-info.chart
|
div.big-info.chart
|
||||||
span.small-title difficulty
|
span.small-title difficulty
|
||||||
span.big-details.spark-difficulty
|
span.big-details.spark-difficulty
|
||||||
|
|
||||||
|
div.col-xs-4.stat-holder.pull-right
|
||||||
|
div.big-info.chart.double-chart
|
||||||
|
span.small-title block propagation
|
||||||
|
histogram.big-details.d3-blockpropagation(data="blockPropagationChart")
|
||||||
|
|
||||||
div.col-xs-4.stat-holder
|
div.col-xs-4.stat-holder
|
||||||
div.big-info.chart
|
div.big-info.chart
|
||||||
span.small-title transactions
|
span.small-title transactions
|
||||||
@ -106,9 +106,9 @@ block content
|
|||||||
table.table.table-striped
|
table.table.table-striped
|
||||||
thead
|
thead
|
||||||
tr.text-info
|
tr.text-info
|
||||||
th
|
|
||||||
i.icon-node(data-toggle="tooltip", data-placement="top", title="Node name", ng-click="orderTable(['-stats.active', 'info.name'], false)")
|
|
||||||
th.th-nodename
|
th.th-nodename
|
||||||
|
i.icon-node(data-toggle="tooltip", data-placement="top", title="Node name", ng-click="orderTable(['-stats.active', 'info.name'], false)")
|
||||||
|
th.th-nodetype
|
||||||
i.icon-laptop(data-toggle="tooltip", data-placement="top", title="Node type", ng-click="orderTable(['-stats.active', 'info.node'], false)")
|
i.icon-laptop(data-toggle="tooltip", data-placement="top", title="Node type", ng-click="orderTable(['-stats.active', '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.active', 'stats.latency'], false)")
|
i.icon-clock(data-toggle="tooltip", data-placement="top", title="Node latency", ng-click="orderTable(['-stats.active', 'stats.latency'], false)")
|
||||||
|
Loading…
Reference in New Issue
Block a user