Skip to content
Snippets Groups Projects
Unverified Commit f7537e93 authored by Angelo Capossele's avatar Angelo Capossele Committed by GitHub
Browse files

Merge pull request #199 from iotaledger/feat/autopeering-visualizer

New autopeering visualizer
parents c20feec3 358d1ec2
No related branches found
No related tags found
No related merge requests found
Showing
with 1442 additions and 341 deletions
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
"serverAddress": "ressims.iota.cafe:188" "serverAddress": "ressims.iota.cafe:188"
}, },
"server": { "server": {
"port": 0 "port": 9191
}, },
"httpServer": { "httpServer": {
"bindAddress": "0.0.0.0:80" "bindAddress": "0.0.0.0:80"
......
...@@ -75,7 +75,6 @@ github.com/gobuffalo/logger v1.0.3 h1:YaXOTHNPCvkqqA7w05A4v0k2tCdpr+sgFlgINbQ6gq ...@@ -75,7 +75,6 @@ github.com/gobuffalo/logger v1.0.3 h1:YaXOTHNPCvkqqA7w05A4v0k2tCdpr+sgFlgINbQ6gq
github.com/gobuffalo/logger v1.0.3/go.mod h1:SoeejUwldiS7ZsyCBphOGURmWdwUFXs0J7TCjEhjKxM= github.com/gobuffalo/logger v1.0.3/go.mod h1:SoeejUwldiS7ZsyCBphOGURmWdwUFXs0J7TCjEhjKxM=
github.com/gobuffalo/packd v0.3.0 h1:eMwymTkA1uXsqxS0Tpoop3Lc0u3kTfiMBE6nKtQU4g4= github.com/gobuffalo/packd v0.3.0 h1:eMwymTkA1uXsqxS0Tpoop3Lc0u3kTfiMBE6nKtQU4g4=
github.com/gobuffalo/packd v0.3.0/go.mod h1:zC7QkmNkYVGKPw4tHpBQ+ml7W/3tIebgeo1b36chA3Q= github.com/gobuffalo/packd v0.3.0/go.mod h1:zC7QkmNkYVGKPw4tHpBQ+ml7W/3tIebgeo1b36chA3Q=
github.com/gobuffalo/packr v1.30.1 h1:hu1fuVR3fXEZR7rXNW3h8rqSML8EVAf6KNm0NKO/wKg=
github.com/gobuffalo/packr/v2 v2.7.1 h1:n3CIW5T17T8v4GGK5sWXLVWJhCz7b5aNLSxW6gYim4o= github.com/gobuffalo/packr/v2 v2.7.1 h1:n3CIW5T17T8v4GGK5sWXLVWJhCz7b5aNLSxW6gYim4o=
github.com/gobuffalo/packr/v2 v2.7.1/go.mod h1:qYEvAazPaVxy7Y7KR0W8qYEE+RymX74kETFqjFoFlOc= github.com/gobuffalo/packr/v2 v2.7.1/go.mod h1:qYEvAazPaVxy7Y7KR0W8qYEE+RymX74kETFqjFoFlOc=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
...@@ -336,8 +335,6 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U ...@@ -336,8 +335,6 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876 h1:sKJQZMuxjOAR/Uo2LBfU90onWEf1dF4C+0hPJCc9Mpc=
golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d h1:9FCpayM9Egr1baVnV1SX0H87m+XB0B8S0hAMi99X/3U= golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d h1:9FCpayM9Egr1baVnV1SX0H87m+XB0B8S0hAMi99X/3U=
golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
...@@ -391,8 +388,6 @@ golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7w ...@@ -391,8 +388,6 @@ golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191018095205-727590c5006e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191018095205-727590c5006e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8 h1:JA8d3MPx/IToSyXZG/RhwYEtfrKO1Fxrqe8KrkiLXKM=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9 h1:1/DFK4b7JH8DmkqhUk48onnSfrPzImPoVxuomtbT2nk= golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9 h1:1/DFK4b7JH8DmkqhUk48onnSfrPzImPoVxuomtbT2nk=
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
......
// +build !skippackr
// Code generated by github.com/gobuffalo/packr/v2. DO NOT EDIT.
// You can use the "packr clean" command to clean up this,
// and any other packr generated files.
package httpserver
import _ "github.com/iotaledger/goshimmer/plugins/analysis/webinterface/httpserver/packrd"
package httpserver
import (
"fmt"
"net/http"
)
func index(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, `<head>
<style>
html {
font-family: monospace, monospace;
line-height: 1.15;
-webkit-text-size-adjust: 100%%;
}
body {
text-align: center;
margin: 0;
overflow: hidden;
}
#nfo{
position:absolute;
right: 0;
padding:10px;
}
#knownPeers{
position:relative;
margin:0;
font-size:14px;
font-weight: bold;
text-align:right;
color:#aaa;
}
#avgNeighbors{
position:relative;
margin:0;
font-size:13px;
text-align:right;
color:grey;
}
#graphc {
position: absolute;
top: 0px;
right: 0px;
margin:0;
right: 0px;
}
#nodeId{
position:relative;
margin:0;
padding:5px 0;
font-size:13px;
font-weight: bold;
text-align:right;
color:#aaa;
}
#nodestat{
position:relative;
margin:0;
font-size:12px;
text-align:right;
color:grey;
}
#in, #out{
margin:0;
padding: 3px 0;
}
</style>
<script src="https://unpkg.com/3d-force-graph"></script>
<!--<script src="../../dist/3d-force-graph.js"></script>-->
</head>
<body>
<div id="graphc"></div>
<div id="nfo">
<p id="knownPeers"></p>
<p id="avgNeighbors"></p>
<div id="nodeId"></div>
<div id="nodestat">
<p id="in"></p>
<p id="out"></p>
</div>
</div>
<script>
var socket = new WebSocket(((window.location.protocol === "https:") ? "wss://" : "ws://") + window.location.host + "/datastream");
socket.onopen = function () {
setInterval(function() {
socket.send("_");
}, 1000);
};
socket.onmessage = function (e) {
document.getElementById("knownPeers").innerHTML = "Known peers: " + data.nodes.length;
document.getElementById("avgNeighbors").innerHTML = "Average neighbors: " + parseFloat(((data.links.length * 2) / data.nodes.length).toFixed(2));
switch (e.data[0]) {
case "_":
// do nothing - its just a ping
break;
case "A":
addNode(e.data.substr(1));
console.log("Add node:",e.data.substr(1));
break;
case "a":
removeNode(e.data.substr(1));
console.log("Remove node:", e.data.substr(1));
break;
case "C":
connectNodes(e.data.substr(1, 64), e.data.substr(65, 64));
console.log("Connect nodes:",e.data.substr(1, 64), " - ", e.data.substr(65, 64));
break;
case "c":
disconnectNodes(e.data.substr(1, 64), e.data.substr(65, 64));
console.log("Disconnect nodes:",e.data.substr(1, 64), " - ", e.data.substr(65, 64));
break;
case "O":
setNodeOnline(e.data.substr(1));
console.log("setNodeOnline:",e.data.substr(1));
break;
case "o":
setNodeOffline(e.data.substr(1));
console.log("setNodeOffline:",e.data.substr(1));
break;
}
};
var nodesById = {};
const data = {
nodes: [],
links: []
};
var existingLinks = {};
let highlightNodes = [];
let highlightInbound = [];
let highlightOutbound = [];
let highlightLinks = [];
let highlightLink = null;
const elem = document.getElementById("graphc");
//.onNodeHover(node => elem.style.cursor = node ? 'pointer' : null)
const Graph = ForceGraph3D()(elem)
.graphData(data)
.enableNodeDrag(false)
.onNodeClick(showNodeStat)
.nodeColor(node => {
if (highlightNodes.indexOf(node) != -1) {
return 'rgb(255,0,0,1)'
}
if (highlightInbound.indexOf(node) != -1) {
return 'rgba(0,255,100,0.6)'
}
if (highlightOutbound.indexOf(node) != -1) {
return 'rgba(0,100,255,0.6)'
}
else {
return 'rgba(0,255,255,0.6)'
}
})
.linkWidth(link => highlightLinks.indexOf(link) === -1 ? 1 : 3)
.linkDirectionalParticles(link => highlightLinks.indexOf(link) === -1 ? 0 : 3)
.linkDirectionalParticleWidth(3)
.onNodeHover(node => {
// no state change
if ((!node && !highlightNodes.length) || (highlightNodes.length === 1 && highlightNodes[0] === node)) return;
highlightNodes = node ? [node] : [];
highlightLinks = [];
highlightInbound = [];
highlightOutbound = [];
clearNodeStat();
if (node != null) {
highlightLinks = data.links.filter(l => (l.target.id == node.id) || (l.source.id == node.id));
highlightLinks.forEach(function(link){
if (link.target.id == node.id) {
highlightInbound.push(link.source)
}
else {
highlightOutbound.push(link.target)
}
});
showNodeStat(node);
}
updateHighlight();
})
.onLinkHover(link => {
// no state change
if ((!link && !highlightLinks.length) || (highlightLinks.length === 1 && highlightLinks[0] === link)) return;
highlightLinks = [link];
highlightNodes = link ? [link.source, link.target] : [];
updateHighlight();
});
var updateRequired = true;
setInterval(function() {
if (updateRequired) {
Graph.graphData(data);
updateRequired = false;
}
}, 500)
function updateHighlight() {
// trigger update of highlighted objects in scene
Graph
.nodeColor(Graph.nodeColor())
.linkWidth(Graph.linkWidth())
.linkDirectionalParticles(Graph.linkDirectionalParticles());
}
updateGraph = function() {
updateRequired = true;
};
function addNode(nodeId, displayImmediately) {
node = {id : nodeId, online: false};
if (!(node.id in nodesById)) {
data.nodes = [...data.nodes, node];
nodesById[node.id] = node;
nodesById[nodeId].online = true;
updateGraph();
}
}
function removeNode(nodeId) {
data.links = data.links.filter(l => l.source.id !== nodeId && l.target.id !== nodeId);
data.nodes = data.nodes.filter(currentNode => currentNode.id != nodeId)
delete nodesById[nodeId];
updateGraph();
}
function setNodeOnline(nodeId) {
if (nodeId in nodesById) {
nodesById[nodeId].online = true;
}
updateGraph();
}
function setNodeOffline(nodeId) {
if (nodeId in nodesById) {
nodesById[nodeId].online = false;
updateGraph();
}
}
function connectNodes(sourceNodeId, targetNodeId) {
if(existingLinks[sourceNodeId + targetNodeId] == undefined) {
if ((sourceNodeId in nodesById) && (targetNodeId in nodesById)) {
//nodesById[sourceNodeId].online = true;
//nodesById[targetNodeId].online = true;
existingLinks[sourceNodeId + targetNodeId] = true
data.links = [...data.links, { source: sourceNodeId, target: targetNodeId }];
}
updateGraph();
}
}
function disconnectNodes(sourceNodeId, targetNodeId) {
data.links = data.links.filter(l => !(l.source.id == sourceNodeId && l.target.id == targetNodeId));
delete existingLinks[sourceNodeId + targetNodeId];
updateGraph();
}
function clearNodeStat() {
document.getElementById("nodeId").innerHTML = ""
document.getElementById("in").innerHTML = ""
document.getElementById("out").innerHTML = ""
}
function showNodeStat(node) {
document.getElementById("nodeId").innerHTML = "ID: " + node.id.substr(0, 16);
var incoming = data.links.filter(l => (l.target.id == node.id));
document.getElementById("in").innerHTML = "INBOUND (accepted): " + incoming.length + "<br>";
incoming.forEach(function(link){
document.getElementById("in").innerHTML += link.source.id.substr(0, 16) + " &rarr; NODE <br>";
});
var outgoing = data.links.filter(l => (l.source.id == node.id));
document.getElementById("out").innerHTML = "OUTBOUND (chosen): " + outgoing.length + "<br>";
outgoing.forEach(function(link){
document.getElementById("out").innerHTML += "NODE &rarr; " + link.target.id.substr(0, 16) + "<br>";
});
}
</script>
</body>`)
}
This diff is collapsed.
...@@ -6,8 +6,10 @@ import ( ...@@ -6,8 +6,10 @@ import (
const ( const (
CFG_BIND_ADDRESS = "analysis.httpServer.bindAddress" CFG_BIND_ADDRESS = "analysis.httpServer.bindAddress"
CFG_DEV = "analysis.httpServer.dev"
) )
func init() { func init() {
flag.String(CFG_BIND_ADDRESS, "0.0.0.0:80", "the bind address for the web API") flag.String(CFG_BIND_ADDRESS, "0.0.0.0:80", "the bind address for the web API")
flag.Bool(CFG_DEV, false, "whether the analysis server visualizer is running dev mode")
} }
...@@ -5,34 +5,41 @@ import ( ...@@ -5,34 +5,41 @@ import (
"net/http" "net/http"
"time" "time"
"github.com/gobuffalo/packr/v2"
"github.com/iotaledger/goshimmer/packages/parameter" "github.com/iotaledger/goshimmer/packages/parameter"
"github.com/iotaledger/goshimmer/packages/shutdown" "github.com/iotaledger/goshimmer/packages/shutdown"
"github.com/iotaledger/hive.go/daemon" "github.com/iotaledger/hive.go/daemon"
"github.com/iotaledger/hive.go/logger" "github.com/iotaledger/hive.go/logger"
"github.com/labstack/echo"
"golang.org/x/net/context" "golang.org/x/net/context"
"golang.org/x/net/websocket" "golang.org/x/net/websocket"
) )
var ( var (
log *logger.Logger log *logger.Logger
httpServer *http.Server engine *echo.Echo
router *http.ServeMux
) )
const name = "Analysis HTTP Server" const name = "Analysis HTTP Server"
var assetsBox = packr.New("Assets", "./static")
func Configure() { func Configure() {
log = logger.NewLogger(name) log = logger.NewLogger(name)
router = http.NewServeMux() engine = echo.New()
engine.HideBanner = true
httpServer = &http.Server{ // we only need this special flag, because we always keep a packed box in the same directory
Addr: parameter.NodeConfig.GetString(CFG_BIND_ADDRESS), if parameter.NodeConfig.GetBool(CFG_DEV) {
Handler: router, engine.Static("/static", "./plugins/analysis/webinterface/httpserver/static")
engine.File("/", "./plugins/analysis/webinterface/httpserver/static/index.html")
} else {
engine.GET("/static/*", echo.WrapHandler(http.StripPrefix("/static", http.FileServer(assetsBox))))
engine.GET("/", index)
} }
router.Handle("/datastream", websocket.Handler(dataStream)) engine.GET("/datastream", echo.WrapHandler(websocket.Handler(dataStream)))
router.HandleFunc("/", index)
} }
func Run() { func Run() {
...@@ -44,9 +51,10 @@ func Run() { ...@@ -44,9 +51,10 @@ func Run() {
func start(shutdownSignal <-chan struct{}) { func start(shutdownSignal <-chan struct{}) {
stopped := make(chan struct{}) stopped := make(chan struct{})
bindAddr := parameter.NodeConfig.GetString(CFG_BIND_ADDRESS)
go func() { go func() {
log.Infof("Started %s: http://%s", name, httpServer.Addr) log.Infof("Started %s: http://%s", name, bindAddr)
if err := httpServer.ListenAndServe(); err != nil { if err := engine.Start(bindAddr); err != nil {
if !errors.Is(err, http.ErrServerClosed) { if !errors.Is(err, http.ErrServerClosed) {
log.Errorf("Error serving: %s", err) log.Errorf("Error serving: %s", err)
} }
...@@ -63,8 +71,16 @@ func start(shutdownSignal <-chan struct{}) { ...@@ -63,8 +71,16 @@ func start(shutdownSignal <-chan struct{}) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second) ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel() defer cancel()
if err := httpServer.Shutdown(ctx); err != nil { if err := engine.Shutdown(ctx); err != nil {
log.Errorf("Error stopping: %s", err) log.Errorf("Error stopping: %s", err)
} }
log.Info("Stopping %s ... done", name) log.Info("Stopping %s ... done", name)
} }
func index(e echo.Context) error {
indexHTML, err := assetsBox.Find("index.html")
if err != nil {
return err
}
return e.HTMLBlob(http.StatusOK, indexHTML)
}
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
/* Document
========================================================================== */
/**
* 1. Correct the line height in all browsers.
* 2. Prevent adjustments of font size after orientation changes in iOS.
*/
html {
font-family: monospace, monospace; /* 1 */
line-height: 1.15; /* 1 */
-webkit-text-size-adjust: 100%; /* 2 */
}
/* Sections
========================================================================== */
/**
* Remove the margin in all browsers.
*/
body {
margin: 0;
overflow: hidden;
}
/**
* Render the `main` element consistently in IE.
*/
main {
display: block;
}
/**
* Correct the font size and margin on `h1` elements within `section` and
* `article` contexts in Chrome, Firefox, and Safari.
*/
h1 {
font-size: 2em;
margin: 0.67em 0;
}
/* Grouping content
========================================================================== */
/**
* 1. Add the correct box sizing in Firefox.
* 2. Show the overflow in Edge and IE.
*/
hr {
box-sizing: content-box; /* 1 */
height: 0; /* 1 */
overflow: visible; /* 2 */
}
/**
* 1. Correct the inheritance and scaling of font size in all browsers.
* 2. Correct the odd `em` font sizing in all browsers.
*/
pre {
font-family: monospace, monospace; /* 1 */
font-size: 1em; /* 2 */
}
/* Text-level semantics
========================================================================== */
/**
* Remove the gray background on active links in IE 10.
*/
a {
background-color: transparent;
}
/**
* 1. Remove the bottom border in Chrome 57-
* 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
*/
abbr[title] {
border-bottom: none; /* 1 */
text-decoration: underline; /* 2 */
text-decoration: underline dotted; /* 2 */
}
/**
* Add the correct font weight in Chrome, Edge, and Safari.
*/
b,
strong {
font-weight: bolder;
}
/**
* 1. Correct the inheritance and scaling of font size in all browsers.
* 2. Correct the odd `em` font sizing in all browsers.
*/
code,
kbd,
samp {
font-family: monospace, monospace; /* 1 */
font-size: 1em; /* 2 */
}
/**
* Add the correct font size in all browsers.
*/
small {
font-size: 80%;
}
/**
* Prevent `sub` and `sup` elements from affecting the line height in
* all browsers.
*/
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
/* Embedded content
========================================================================== */
/**
* Remove the border on images inside links in IE 10.
*/
img {
border-style: none;
}
/* Forms
========================================================================== */
/**
* 1. Change the font styles in all browsers.
* 2. Remove the margin in Firefox and Safari.
*/
button,
input,
optgroup,
select,
textarea {
font-family: monospace, monospace; /* 1 */
font-size: 100%; /* 1 */
line-height: 1.15; /* 1 */
margin: 0; /* 2 */
}
/**
* Show the overflow in IE.
* 1. Show the overflow in Edge.
*/
button,
input { /* 1 */
overflow: visible;
}
/**
* Remove the inheritance of text transform in Edge, Firefox, and IE.
* 1. Remove the inheritance of text transform in Firefox.
*/
button,
select { /* 1 */
text-transform: none;
}
/**
* Correct the inability to style clickable types in iOS and Safari.
*/
button,
[type="button"],
[type="reset"],
[type="submit"] {
-webkit-appearance: button;
}
/**
* Remove the inner border and padding in Firefox.
*/
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
border-style: none;
padding: 0;
}
/**
* Restore the focus styles unset by the previous rule.
*/
button:-moz-focusring,
[type="button"]:-moz-focusring,
[type="reset"]:-moz-focusring,
[type="submit"]:-moz-focusring {
outline: 1px dotted ButtonText;
}
/**
* Correct the padding in Firefox.
*/
fieldset {
padding: 0.35em 0.75em 0.625em;
}
/**
* 1. Correct the text wrapping in Edge and IE.
* 2. Correct the color inheritance from `fieldset` elements in IE.
* 3. Remove the padding so developers are not caught out when they zero out
* `fieldset` elements in all browsers.
*/
legend {
box-sizing: border-box; /* 1 */
color: inherit; /* 2 */
display: table; /* 1 */
max-width: 100%; /* 1 */
padding: 0; /* 3 */
white-space: normal; /* 1 */
}
/**
* Add the correct vertical alignment in Chrome, Firefox, and Opera.
*/
progress {
vertical-align: baseline;
}
/**
* Remove the default vertical scrollbar in IE 10+.
*/
textarea {
overflow: auto;
}
/**
* 1. Add the correct box sizing in IE 10.
* 2. Remove the padding in IE 10.
*/
[type="checkbox"],
[type="radio"] {
box-sizing: border-box; /* 1 */
padding: 0; /* 2 */
}
/**
* Correct the cursor style of increment and decrement buttons in Chrome.
*/
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}
/**
* 1. Correct the odd appearance in Chrome and Safari.
* 2. Correct the outline style in Safari.
*/
[type="search"] {
-webkit-appearance: textfield; /* 1 */
outline-offset: -2px; /* 2 */
}
/**
* Remove the inner padding in Chrome and Safari on macOS.
*/
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
/**
* 1. Correct the inability to style clickable types in iOS and Safari.
* 2. Change font properties to `inherit` in Safari.
*/
::-webkit-file-upload-button {
-webkit-appearance: button; /* 1 */
font: inherit; /* 2 */
}
/* Interactive
========================================================================== */
/*
* Add the correct display in Edge, IE 10+, and Firefox.
*/
details {
display: block;
}
/*
* Add the correct display in all browsers.
*/
summary {
display: list-item;
}
/* Misc
========================================================================== */
/**
* Add the correct display in IE 10+.
*/
template {
display: none;
}
/**
* Add the correct display in IE 10.
*/
[hidden] {
display: none;
}
/*-----------own------------*/
#logo {
position:absolute;
left: 0;
margin:10px;
height: 100px;
width: 100px;
}
.logo {
display: block;
margin-left: auto;
margin-right: auto;
width: 50%;
}
#title {
color: grey;
text-align: center;
font-size: 14px;
font-weight:bold;
margin: 0;
padding-bottom: 5px;
}
#info {
position:absolute;
right: 0;
padding:10px;
font-size:12px;
text-align:right;
}
#status {
position:relative;
margin:0;
font-size:14px;
font-weight: bold;
color:#aaa;
z-index: 10;
}
#streamstatus {
position:relative;
margin: 2px 0 0 0;
color:grey;
}
#searchWrapper {
display: none;
position:relative;
margin:10px 0 3px 0;
z-index: 10;
}
#search {
display: inline-block;
background: transparent;
border: 0;
margin: 0;
padding: 0;
width: 200px;
color: grey;
text-align: right;
}
#search:focus {
outline: none;
color: #aaa;
}
#clear {
display: inline-block;
background: transparent;
border: 0;
margin: 0;
padding: 0;
cursor: pointer;
color: grey;
}
#clear:focus {
outline: none;
}
#clear:hover {
color: #aaa;
text-decoration: line-through;
}
#nodesOnlineWrapper{
position: relative;
height: 80px;
overflow-y: scroll;
margin:0;
padding: 5px 0;
color: grey;
z-index: 10;
}
#nodesOnline {
display: inline-block;
/* background: black; */
}
#nodesOnline span {
display: block;
padding: 5px 5px;
border-bottom: 1px dashed #7c7c7c;
cursor: pointer;
}
#nodesOnline span.active {
color: #336db5;
}
#nodesOnline span:first-child {
border-top: 1px dashed #7c7c7c;
}
#nodeId {
margin:0;
padding:5px 0;
font-weight: bold;
text-decoration: underline;
color:#aaa;
}
#nodestats {
position:relative;
margin: 7px 0 0 0;
color:grey;
}
#in, #out {
margin:0;
padding: 3px 0;
}
#graphc {
position: absolute;
width: 100%;
height: 100%;
margin:0;
z-index: 1;
}
\ No newline at end of file
plugins/analysis/webinterface/httpserver/static/img/gos.png

3.62 KiB

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>GoShimmer - Network Visualizer</title>
<link rel="stylesheet" type="text/css" href="/static/css/normalize.css">
<script type="text/javascript" src="/static/js/vivagraph-0.12.0.min.js"></script>
<script type="text/javascript" src="/static/js/main.js"></script>
</head>
<body style="background: #202126;">
<div id="logo">
<p id="title">GOSHIMMER<br>NETWORK</p>
<img class="logo" src="/static/img/gos.png" alt="GoShimmer">
</div>
<div id="graphc"></div>
<div id="info">
<p id="status"></p>
<p id="streamstatus"></p>
<div id="searchWrapper">
<input id="search" type="text" placeholder="search for node..." autocomplete="off">
<input type="button" id="clear" value="clear">
</div>
<div id="nodesOnlineWrapper"><div id="nodesOnline"></div></div>
<div id="nodestats">
<p id="nodeId"></p>
<p id="in"></p>
<p id="out"></p>
</div>
</div>
</body>
</html>
\ No newline at end of file
This diff is collapsed.
...@@ -30,8 +30,8 @@ func Configure(plugin *node.Plugin) { ...@@ -30,8 +30,8 @@ func Configure(plugin *node.Plugin) {
lock.Lock() lock.Lock()
defer lock.Unlock() defer lock.Unlock()
//delete(nodes, nodeId) delete(nodes, nodeId)
nodes[nodeId] = false //nodes[nodeId] = false
})) }))
server.Events.NodeOnline.Attach(events.NewClosure(func(nodeId string) { server.Events.NodeOnline.Attach(events.NewClosure(func(nodeId string) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment