From c687e46fca190b37fdddeffef9538540ea897f21 Mon Sep 17 00:00:00 2001 From: Stephan Schwaer Date: Mon, 14 Mar 2016 18:16:04 +0100 Subject: Remodeled functions to use new server data. Red links for active clients. --- static/status-dnbd3.html | 322 +++++++++++++++++++++++++++-------------------- 1 file changed, 185 insertions(+), 137 deletions(-) diff --git a/static/status-dnbd3.html b/static/status-dnbd3.html index 8fdcfa6..263d621 100644 --- a/static/status-dnbd3.html +++ b/static/status-dnbd3.html @@ -30,6 +30,11 @@ var colorList = d3.scale.category10(); var pendingLinks = []; var intLinks = []; var newLinks = []; +var links = {}; +var nodes = {}; + +var idleColor = { "r": 85, "g": 102, "b": 255}; +var activeColor = { "r": 255, "g": 0, "b": 0}; // IDs need to begin with a letter. function makeId(prefix, text) { @@ -46,7 +51,9 @@ function myGraph(el) { var ccX = 0, ccY = 0, ccCount = 0; // Add and remove elements on the graph object - this.addNode = function (id, x, y) { + this.addNode = function (id) { + x = 1; + y = 1; title = id; id = makeId("a", id); var distance = 2; @@ -55,14 +62,11 @@ function myGraph(el) { // Other attr if server. var s = servers[title] if(s) { -// console.log(color); distance = 6; radius = 15; } -// if (!distance) distance = 5; -// distance *= w / 2000; -// if (!radius) radius = 5; + distance *= w / 2000; var node = findNode(id); // Add node, if it doesn't exist if (!node) { @@ -76,14 +80,13 @@ function myGraph(el) { var visNode = vis.select("#" + id); if (visNode) { visNode.select("circle").attr("r", radius); + // Change color if server. + var s = servers[title]; + if (s) { + visNode.select("circle").style("fill", s.color); + } } - node.lifetime = 2; - - var s = servers[title]; - if (s && visNode) { - visNode.select("circle").style("fill", s.color) - } } } @@ -110,11 +113,27 @@ function myGraph(el) { } } - this.addLink = function (sourceId, targetId) { - // Link between servers? - var stroke = "#56f"; - if (servers[sourceId] && servers[targetId]) stroke = "#f00"; + this.addLink = function (edge, timestamp) { + + var sourceId = edge.source; + var targetId = edge.target; + var stroke = "rgb(85, 102, 255)"; + // Change color to red for links between servers + if (servers[sourceId] && servers[targetId]) stroke = "rgb(255, 0, 0)"; + + + // // TODO Change color for already active links here + // if(servers[sourceId]) { + // var uploadRate = Math.round( ( servers[sourceId].uploadRate/ 1048576) * 100 ) / 100; + // //console.log(uploadRate) + // if(uploadRate > 1) { + // //changed = true; + // stroke = "#f00"; + // } + // } + + sourceId = makeId("a", sourceId); targetId = makeId("a", targetId); @@ -126,17 +145,52 @@ function myGraph(el) { if (!link) { var index = $.inArray(sourceId + targetId, pendingLinks); if (index !== -1) { - links.push({"source": sourceNode, "target": targetNode, "lifetime":2, "color": stroke}); + links.push({"source": sourceNode, "target": targetNode, "lifetime":2, "color": stroke, "downloadRate" : 0, "lastReceived": 0, "lastTimestamp": 0, "lastUptime": 0, "colorIntensity": 0 }); changed = true; } else { newLinks.push(sourceId + targetId); } - } else { + } else { link.lifetime = 2; + //link.color = stroke; + + //console.log(link); + if (link.lastTimestamp != 0) { + var upperIntensity = 3000; + link.downloadRate = ((edge.received - link.lastReceived) / (timestamp - link.lastTimestamp)) / 0.004; + link.colorIntensity += link.downloadRate; + if (link.colorIntensity >= upperIntensity) link.colorIntensity = upperIntensity; + link.colorIntensity -= 300; + if (link.colorIntensity < 0) link.colorIntensity = 0; + var factor = link.colorIntensity / upperIntensity; + var cFactor = 1 - factor; + + + var red = cFactor * idleColor.r + factor * activeColor.r; + var green = cFactor * idleColor.g + factor * activeColor.g; + var blue = cFactor * idleColor.b + factor * activeColor.b; + //console.log(red +", "+ green +", " +blue); + link.color = "rgb("+ Math.floor(red) + ", " + Math.floor(green) + ", " + Math.floor(blue) + ")"; + + } else { + link['downloadRate'] = 0; + } + link['lastReceived'] = edge.received; + link['lastTimestamp'] = timestamp; + + } } } + function findLink(sourceId, targetId) { + for (var i = 0; i < links.length; ++i) { + if ( (links[i].source === sourceId && links[i].target === targetId) + || (links[i].source === targetId && links[i].target === sourceId) ) + return links[i]; + } + } + var findNode = function (id) { for (var i = 0; i < nodes.length; i++) { if (nodes[i].id === id) @@ -144,13 +198,6 @@ function myGraph(el) { } } - var findLink = function (sourceId, targetId) { - for (var i = 0; i < links.length; ++i) { - if ( (links[i].source === sourceId && links[i].target === targetId) - || (links[i].source === targetId && links[i].target === sourceId) ) - return links[i]; - } - } var findNodeIndex = function (id) { for (var i=0; i < nodes.length; i++) { @@ -189,129 +236,143 @@ function myGraph(el) { // Settings for movement of the graph var force = d3.layout.force() // Force of center gravitation - .gravity(.06) + .gravity(.12) // Distance of the links - .distance(function(bla) { return bla.source.distance * bla.target.distance; }) + .distance(function(bla) { return bla.source.distance + bla.target.distance; }) // Strength of the links - .linkStrength(0.5) + .linkStrength(0.3) // Force with which the links "pull" - .charge(function(bla) { return -bla.distance * 10 * bla.distance; }) + .charge(function(bla) { return -0.9; }) // Friction for the graph nodes - .friction(0.4) + .friction(0.5) .size([w, h]); - var nodes = force.nodes(), - links = force.links(); + nodes = force.nodes(); + links = force.links(); this.update = function () { - if (!changed) return; + //if (!changed) return; update(); } var update = function () { - changed = false; + + + var link = vis.selectAll("line.link") + .data(links, function(d) { return d.source.id + "-" + d.target.id; }); - var node = vis.selectAll("g.node") - .data(nodes, function(d) { return d.id;}); + link.enter().insert("line") + .attr("class", "link").style({stroke: function(d) { return d.color }}); + // change color of of exitsting nodes + link.style({stroke: function(d) { return d.color }}); - var nodeEnter = node.enter().append("g") - .attr("class", "node") - .attr("id", function(d) { return d.id;}) - .on("mouseover", function(d) { - // Highlight statistics div - var statDiv = document.getElementById(makeId("b", d.title)) - if (statDiv){ - statDiv.setAttribute("style", "background-color:blue; color:white;"); - } + if (changed){ + changed = false; - // Increase line width of server in chart - var s = servers[d.title]; - if (!s) return; - smoothie.seriesSet[s.index].options.lineWidth = 4; - }) - .on("mouseout", function(d) { - // Make statistics div normal again - var statDiv = document.getElementById(makeId("b", d.title)) - if (statDiv){ - statDiv.setAttribute("style", "background-color:white; color:black;"); - } + var node = vis.selectAll("g.node") + .data(nodes, function(d) { return d.id;}); - // Reset line width - var s = servers[d.title]; - if (!s) return; - smoothie.seriesSet[s.index].options.lineWidth = 2; - }); - nodeEnter.append("circle") - .attr("class", "circle") - .attr("r", function(d) { return d.radius; }) - .style("fill", function(d) { return d.color; }); + var nodeEnter = node.enter().append("g") + .attr("class", "node") + .attr("id", function(d) { return d.id;}) + .on("mouseover", function(d) { + // Highlight statistics div + var statDiv = document.getElementById(makeId("b", d.title)) + if (statDiv){ + statDiv.setAttribute("style", "background-color:blue; color:white;"); + } + // Increase line width of server in chart + var s = servers[d.title]; + if (!s) return; + smoothie.seriesSet[s.index].options.lineWidth = 4; + }) + .on("mouseout", function(d) { + // Make statistics div normal again + var statDiv = document.getElementById(makeId("b", d.title)) + if (statDiv){ + statDiv.setAttribute("style", "background-color:white; color:black;"); + } - nodeEnter.append("text") - .attr("class", "nodetext") - .attr("dx", -32) - .attr("dy", "-1em") - .text(function(d) {return d.title}); + // Reset line width + var s = servers[d.title]; + if (!s) return; + smoothie.seriesSet[s.index].options.lineWidth = 2; + }); - node.exit().remove(); + nodeEnter.append("circle") + .attr("class", "circle") + .attr("r", function(d) { return d.radius; }) + .style("fill", function(d) { return d.color; }); - var link = vis.selectAll("line.link") - .data(links, function(d) { return d.source.id + "-" + d.target.id; }); - link.enter().insert("line") - .attr("class", "link").style({stroke: function(d) { return d.color }}); + nodeEnter.append("text") + .attr("class", "nodetext") + .attr("dx", -32) + .attr("dy", "-1em") + .text(function(d) {return d.title}); - link.exit().remove(); + node.exit().remove(); - vis.selectAll('g.node').forEach(function(e){$('#graph').find('svg').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) + ")"; - }); - }; + + + link.exit().remove(); - force.on("tick", render); + vis.selectAll('g.node').forEach(function(e){$('#graph').find('svg').append(e)}); - updateBounds(); - force.start(); + var render = function() { + var fixX = function(x) { + // console.log("X:" +x + " lx:" + lx + " scale:" + scale +" offX:" + offX); + + 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); + + updateBounds(); + force.start(); + } } update(); @@ -333,6 +394,7 @@ setInterval( function() { var g = data.graph; var stats = data.servers; updateGraph(g, data); + //updateLinks(g.edges, data); // updateTrafficGraph has to be called before updateTextStatistics to populate servers updateTrafficGraph(stats, data); updateTextStatistics(stats); @@ -343,14 +405,16 @@ setInterval( function() { }); }, 2000); + + // Update data of the graph function updateGraph(g, data){ if (g) { for (var i = 0; i < g.nodes.length; ++i) { - graph.addNode(g.nodes[i].name, g.nodes[i].x, g.nodes[i].y); // g.nodes[i].x, g.nodes[i].y); + graph.addNode(g.nodes[i].name); // g.nodes[i].x, g.nodes[i].y); } for (var i = 0; i < g.edges.length; ++i) { - graph.addLink(g.edges[i].source, g.edges[i].target); + graph.addLink(g.edges[i], data.timestamp); } pendingLinks = intLinks; intLinks = newLinks; @@ -359,6 +423,7 @@ function updateGraph(g, data){ } + // Convert bytes to GiB or TiB and return a string in form "10,23 GiB" function bytesToString( bytes ) { var convertedValue; @@ -374,7 +439,6 @@ function bytesToString( bytes ) { unit = " MiB"; } else if ( bytes >= 1024 ) { convertedValue = Math.round( (bytes / 1024) * 100 ) / 100 ; -// convertedValue = Math.round( ( convertedValue / 1024 ) * 100 ) / 100; unit = " KiB"; } else { convertedValue = Math.round(bytes); @@ -421,7 +485,6 @@ function updateTrafficGraph(stats, data){ servers[stats[i].address] = server = { 'lastUptime': 0, 'lastTimestamp': 0, 'lastSent': 0, 'line': new TimeSeries({logarithmicScale: true}), 'index': serverCount++ , 'uploadRate': 0, 'downloadRate': 0, 'uploadPeak': 0 } server.color = colorList(stats[i].address); smoothie.addTimeSeries(server['line'], {lineWidth:2, strokeStyle: server.color}); - //console.log(server); } // Server seems to have rebootet, redo values but add no point to chart. if (server['lastUptime'] > stats[i].uptime) { @@ -442,21 +505,6 @@ function updateTrafficGraph(stats, data){ server['lastUptime'] = stats[i].uptime; server['lastSent'] = stats[i].bytesSent; server['lastTimestamp'] = stats[i].timestamp; - -// if (Math.random() > .8){ -// var delServ = server; -// setTimeout(function() { -// smoothie.removeTimeSeries(delServ.line); -// for (var srv in servers) { -// if (srv.index > delServ.index) -// srv.index--; -// } -// serverCount--; -// }, 30000); -// delete servers[stats[i].address]; -// console.log("Baleeted"); -// console.log(servers); -// } } } } -- cgit v1.2.3-55-g7522