From 34e2bf7a61b62927a1e9250ab146ecb3335d9fd3 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Mon, 21 Mar 2016 16:08:48 +0100 Subject: Cleanup, features, everything, nonsense commitmsg --- static/status-dnbd3.html | 211 +++++++++++++++++++++++------------------------ 1 file changed, 105 insertions(+), 106 deletions(-) diff --git a/static/status-dnbd3.html b/static/status-dnbd3.html index a318ab2..184521d 100644 --- a/static/status-dnbd3.html +++ b/static/status-dnbd3.html @@ -40,9 +40,9 @@ var nodes = {}; // idle links (blue) var idleColor = { "r": 85, "g": 102, "b": 255}; // active links (green) -var activeColor = { "r": 0, "g": 255, "b": 0}; +var activeColor = { "r": 0, "g": 230, "b": 20}; // peaking links (red) -var peakColor = { "r": 255, "g": 0, "b": 0}; +var peakColor = { "r": 255, "g": 40, "b": 30}; // IDs need to begin with a letter. function makeId(prefix, text) { @@ -56,48 +56,29 @@ function logarithmicScaling(value) { function myGraph(el) { var changed = false; - // to spawn new clients near already existing nodes. - var ccX = 0, ccY = 0, ccCount = 0; // Add/update and remove elements on the graph object this.updateNode = function (id) { - x = 1; - y = 1; - title = id; - id = makeId("a", id); - var distance = 2; - var radius = 4; - var color = "#0000FF"; // Blue for client nodes - - // Servers look different - var s = servers[title] - if(s) { - distance = 6; - radius = 15; - } - distance *= w / 2000; + var title = id; + var id = makeId("a", id); + var node = findNode(id); // Add node, if it doesn't exist if (!node) { - if (ccCount != 0) { - x = ccX / ccCount; - y = ccY / ccCount; - } - nodes.push({"id":id, "title": title, "distance":distance, "radius":radius, "x":x, "y":y, "color":color}); + nodes.push(node = {"id": id, "title": title, "x": w/2, "y":h/2}); changed = true; - } else { + } else if (!node.isServer && servers[title]) { + node.isServer = true; + // Change color and radius if server. var visNode = vis.select("#" + id); if (visNode) { - // Change color and radius if server. - var s = servers[title]; - if (s) { - visNode.select("circle").attr("r", radius); - visNode.select("circle").style("fill", s.color); - } + visNode.select("circle") + .attr("r", 15) + .style("fill", servers[title].color); } - node.lifetime = 2; } + node.lifetime = 2; } // Remove nodes/edges that haven't reported for a while. @@ -127,28 +108,28 @@ function myGraph(el) { this.updateLink = function (edge, timestamp) { var sourceId = edge.source; var targetId = edge.target; - var stroke = idleColor; + var width = '2.5px'; // Change color to red for links between servers - if (servers[sourceId] && servers[targetId]) stroke = "rgb(255, 0, 0)"; + if (servers[sourceId] && servers[targetId]) width = '3.5px'; sourceId = makeId("a", sourceId); targetId = makeId("a", targetId); var sourceNode = findNode(sourceId); var targetNode = findNode(targetId); - if ((sourceNode !== undefined) && (targetNode !== undefined)) { + if ((typeof(sourceNode) !== 'undefined') && (typeof(targetNode) !== 'undefined')) { var link = findLink(sourceNode, targetNode); // Add non existing links if (!link) { var index = $.inArray(sourceId + targetId, pendingLinks); if (index !== -1) { - links.push({"id": sourceId + "-" + targetId ,"source": sourceNode, "target": targetNode, "lifetime":2, "color": stroke, "downloadRate" : 0, "lastReceived": 0, "lastTimestamp": 0, "lastUptime": 0, "colorIntensity": 0 }); + links.push({"id": sourceId + "-" + targetId ,"source": sourceNode, "target": targetNode, "lifetime":2, "color": idleColor, "downloadRate" : 0, "lastReceived": 0, "lastTimestamp": 0, "lastUptime": 0, "colorIntensity": 0, "width": width }); changed = true; } else { newLinks.push(sourceId + targetId); } - } else { + } else { link.lifetime = 2; // Calculate download rate for clients and color links. @@ -201,7 +182,7 @@ function myGraph(el) { } // Update the color of a link in the svg. - function updateLinkColor(link){ + function updateLinkColor(link) { // Prevent future searches for links to improve performance. if(!link.visObject) { link.visObject = vis.select("#" + link.source.id + "-" + link.target.id); @@ -211,9 +192,8 @@ function myGraph(el) { } // Interval for fading out the color of active links - window.setInterval(decayLinkColor, 500); function decayLinkColor() { - for (var i = 0; i < links.length ; i++ ){ + for (var i = 0; i < links.length ; i++) { var link = links[i]; // Do nothing if there is no intensity to decay. if(link.colorIntensity > 0) { @@ -230,6 +210,14 @@ function myGraph(el) { } } } + window.setInterval(decayLinkColor, 500); + window.setInterval(function() { + if (force.alpha() == 0) { + force.alpha(0.015); + force.tick(); + force.stop(); + } + }, 125); // Set the color intensity of link according to its download rate. @@ -296,14 +284,15 @@ function myGraph(el) { var force = d3.layout.force() // Force of center gravitation .gravity(.12) - // Distance of the links - .distance(function(bla) { return 4; }) - // Strength of the links + // Desired distance of the links + .distance(function(bla) { if (bla.source.isServer && bla.target.isServer) return 10; return 4; }) + // Strength of the links (how strongly the distance is enforced) (0-1) .linkStrength(0.3) - // Force with which the links "pull" + // Force with which all nodes attract each other .charge(function(bla) { return -0.9; }) // Friction for the graph nodes .friction(0.5) + .theta(0.75) .size([w, h]); nodes = force.nodes(); @@ -311,19 +300,23 @@ function myGraph(el) { this.update = function () { - if(changed){ + if(changed) { + var first = svgLinks.length === 0; update(); + if (first) force.alpha(0.9); } } - // Update the complete svg. Performance intensive. - function update () { + // Update the complete svg. + var svgNodes = []; + var svgLinks = []; + function update() { changed = false; - var node = vis.selectAll("g.node") + svgNodes = vis.selectAll("g.node") .data(nodes, function(d) { return d.id; }); - var nodeEnter = node.enter().append("g") + var nodeEnter = svgNodes.enter().append("g") .attr("class", "node") .attr("id", function(d) { return d.id; }) .on("mouseover", function(d) { @@ -353,8 +346,7 @@ function myGraph(el) { nodeEnter.append("circle") .attr("class", "circle") - .attr("r", function(d) { return d.radius; }) - .style("fill", function(d) { return d.color; }); + .attr("r", 4).style("fill", "#00f"); nodeEnter.append("text") .attr("class", "nodetext") @@ -362,69 +354,64 @@ function myGraph(el) { .attr("dy", "-1em") .text(function(d) {return d.title}); - node.exit().remove(); + svgNodes.exit().remove(); - var link = vis.selectAll("line.link") + svgLinks = vis.selectAll("line.link") .data(links, function(d) { return d.source.id + "-" + d.target.id; }); - link.enter().insert("line") + svgLinks.enter().insert("line") .attr("class", "link") .attr("id", function(d) {return d.id; }) - .style({stroke: function(d) { return d.color; }}); - - // Aplly color of exitsting nodes - link.style({stroke: function(d) { return d.color; }}); + .style({stroke: function(d) { return d.color }, "stroke-width": function(d) { return d.width } }); - link.exit().remove(); + svgLinks.exit().remove(); - vis.selectAll('g.node').forEach(function(e){$('#graph').find('svg').append(e)}); + // Put all nodes on top again by adding them again + var jGraph = $('#graph').find('svg'); + vis.selectAll('g.node').forEach(function(e){jGraph.append(e)}); - var render = function() { - var fixX = function(x) { - return (x - lx) * scale + 20 + offX; - } - var fixY = function(y) { - return (y - ly) * scale + 20 + offY; - } - var lx = 1000000, ly = 1000000, ux = -1000000, uy = -1000000; - for (var i = 0; i < nodes.length; ++i) { - if (nodes[i].x < lx) lx = nodes[i].x; - if (nodes[i].x > ux) ux = nodes[i].x; - if (nodes[i].y < ly) ly = nodes[i].y; - if (nodes[i].y > uy) uy = nodes[i].y; - } - var width = (ux - lx), height = (uy - ly); - var scale; - var offX = 0, offY = 0; - if ( (width / w) > (height / h) ) { - scale = (w - 40) / width; - offY = (h - (height * scale + 20)) / 2; - } else { - scale = (h - 40) / height; - offX = (w - (width * scale + 20)) / 2; - } - link.attr("x1", function(d) { return fixX(d.source.x); }) - .attr("y1", function(d) { return fixY(d.source.y); }) - .attr("x2", function(d) { return fixX(d.target.x); }) - .attr("y2", function(d) { return fixY(d.target.y); }); - - node.attr("transform", function(d) { - if (ccCount > 10) { - ccX = ccY = ccCount = 0; - } - ccCount++; - ccX += d.x; - ccY += d.y; - return "translate(" + fixX(d.x) + "," + fixY(d.y) + ")"; - }); - }; - force.on("tick", render); + force.on("tick", renderTick); updateBounds(); force.start(); } + // Render function + function renderTick() { + var lx = 1000000, ly = 1000000, ux = -1000000, uy = -1000000; + for (var i = 0; i < nodes.length; ++i) { + if (nodes[i].x < lx) lx = nodes[i].x; + if (nodes[i].x > ux) ux = nodes[i].x; + if (nodes[i].y < ly) ly = nodes[i].y; + if (nodes[i].y > uy) uy = nodes[i].y; + } + var width = (ux - lx), height = (uy - ly); + var scale; + var offX = 0, offY = 0; + if ( (width / w) > (height / h) ) { + scale = (w - 40) / width; + offY = (h - (height * scale + 20)) / 2; + } else { + scale = (h - 40) / height; + offX = (w - (width * scale + 20)) / 2; + } + var fixX = function(x) { + return (x - lx) * scale + 20 + offX; + } + var fixY = function(y) { + return (y - ly) * scale + 20 + offY; + } + svgLinks.attr("x1", function(d) { return fixX(d.source.x); }) + .attr("y1", function(d) { return fixY(d.source.y); }) + .attr("x2", function(d) { return fixX(d.target.x); }) + .attr("y2", function(d) { return fixY(d.target.y); }); + + svgNodes.attr("transform", function(d) { + return "translate(" + fixX(d.x) + "," + fixY(d.y) + ")"; + }); + }; + window.onresize = update; update(); } @@ -455,7 +442,7 @@ setInterval( function() { // Update data of the graph -function updateGraph(g, data){ +function updateGraph(g, data) { if (g) { for (var i = 0; i < g.nodes.length; ++i) { graph.updateNode(g.nodes[i].name); @@ -494,13 +481,21 @@ function bytesToString( bytes ) { } // Update data of the statistics divs -function updateTextStatistics(stats){ +function updateTextStatistics(stats) { + var glob = $('#gstats'); + if (glob.length === 0) { + $('#statistics').append('
'); + glob = $('#gstats'); + } + glob.html('

Global
' + + 'Upload: ' + bytesToString(globalUploadRate) + '/s
' + + 'Upload Peak: ' + bytesToString(globalUploadMax) + '/s

'); if (stats) { for (var i = 0; i < stats.length; ++i) { var divId = makeId("b", stats[i].address); var server = $('#' + divId); - if (server.length == 0){ - $("#statistics").append("

"); + if (server.length === 0) { + $("#statistics").append('
'); server = $("#" + divId); } @@ -521,10 +516,12 @@ function updateTextStatistics(stats){ } } +var globalUploadRate = 0, globalUploadMax = 0; // Update the traffic graph -function updateTrafficGraph(stats, data){ +function updateTrafficGraph(stats, data) { if (stats) { + globalUploadRate = 0; for (var i = 0; i < stats.length; ++i) { var server = servers[stats[i].address]; if (!server) { @@ -551,8 +548,10 @@ function updateTrafficGraph(stats, data){ server['lastUptime'] = stats[i].uptime; server['lastSent'] = stats[i].bytesSent; server['lastTimestamp'] = stats[i].timestamp; + globalUploadRate += server['uploadRate']; } + if (globalUploadRate > globalUploadMax) globalUploadMax = globalUploadRate; } } - \ No newline at end of file + -- cgit v1.2.3-55-g7522