summaryrefslogtreecommitdiffstats
path: root/static
diff options
context:
space:
mode:
authorStephan Schwaer2016-03-17 14:41:39 +0100
committerStephan Schwaer2016-03-17 14:41:39 +0100
commitdccd6c39f79f27502b08208d4355b1d403035986 (patch)
tree5564de85edb26694105b7f1e3fff8e5d937df218 /static
parentFixed resize of window. (diff)
downloaddnbd3-status-dccd6c39f79f27502b08208d4355b1d403035986.tar.gz
dnbd3-status-dccd6c39f79f27502b08208d4355b1d403035986.tar.xz
dnbd3-status-dccd6c39f79f27502b08208d4355b1d403035986.zip
Improved link coloring, link color fading, performance, and code cleanup.
Now using pow and sqrt function to blend link colors. Link color now fades in 500ms intervals. Link color intensity no longer additive. Optimised coloring of links for performance. Code cleanup. Added/changed some comments.
Diffstat (limited to 'static')
-rw-r--r--static/status-dnbd3.html296
1 files changed, 162 insertions, 134 deletions
diff --git a/static/status-dnbd3.html b/static/status-dnbd3.html
index 0a9556e..a318ab2 100644
--- a/static/status-dnbd3.html
+++ b/static/status-dnbd3.html
@@ -27,6 +27,9 @@ smoothie.streamTo(document.getElementById("traffic"), 2000);
// For coloring the servers and the chart-lines.
var colorList = d3.scale.category10();
+// Max intensity ~ 50MB/s
+var maxIntensity = 50000;
+
var pendingLinks = [];
var intLinks = [];
var newLinks = [];
@@ -34,11 +37,11 @@ var links = {};
var nodes = {};
// color for links
-// color for idle links
+// idle links (blue)
var idleColor = { "r": 85, "g": 102, "b": 255};
-// links that are active
+// active links (green)
var activeColor = { "r": 0, "g": 255, "b": 0};
-// links with peaking download
+// peaking links (red)
var peakColor = { "r": 255, "g": 0, "b": 0};
// IDs need to begin with a letter.
@@ -64,7 +67,7 @@ function myGraph(el) {
id = makeId("a", id);
var distance = 2;
var radius = 4;
- var color = "#0000FF"; // Blue
+ var color = "#0000FF"; // Blue for client nodes
// Servers look different
var s = servers[title]
@@ -140,7 +143,7 @@ function myGraph(el) {
if (!link) {
var index = $.inArray(sourceId + targetId, pendingLinks);
if (index !== -1) {
- links.push({"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": stroke, "downloadRate" : 0, "lastReceived": 0, "lastTimestamp": 0, "lastUptime": 0, "colorIntensity": 0 });
changed = true;
} else {
newLinks.push(sourceId + targetId);
@@ -150,16 +153,19 @@ function myGraph(el) {
// Calculate download rate for clients and color links.
if (link.lastTimestamp != 0) {
-
if(timestamp - lastTime > 0) {
// Download rate in KB/s
link.downloadRate = ((edge.received - link.lastReceived) / (timestamp - lastTime)) * 4 * 1000;
// Clients may have multiple connections with different received data -> prevent negative download rate...
if(link.downloadRate < 0) link.downloadRate = 0;
- colorLink(link);
+ // only need fiddle with colors if needed.
+ if (link.downloadRate > 0) {
+ increasColorIntensity(link);
+ colorLink(link);
+ updateLinkColor(link);
+ }
}
-
} else {
link['downloadRate'] = 0;
}
@@ -169,18 +175,8 @@ function myGraph(el) {
}
}
- // Color a link according to its intensity
+ // Color a link according to its intensity, does not apply the color in the svg! Use updateLinkColor function for that.
function colorLink(link) {
- // Max intensity ~ 50MB/s
- var maxIntensity = 50000;
- // Fading rate of colored links
- var fadingValue = (link.colorIntensity*0.15) + 100;
- link.colorIntensity -= fadingValue;
- if (link.colorIntensity < 0) link.colorIntensity = 0;
-
- link.colorIntensity += link.downloadRate;
- if (link.colorIntensity >= maxIntensity) link.colorIntensity = maxIntensity;
-
var red, green, blue;
// Green colors between 0 - 1 MB/s
if( link.colorIntensity <= 1000 ) {
@@ -188,24 +184,64 @@ function myGraph(el) {
var factor = link.colorIntensity / 1000;
var cFactor = 1 - factor;
- red = cFactor * idleColor.r + factor * activeColor.r;
- green = cFactor * idleColor.g + factor * activeColor.g;
- blue = cFactor * idleColor.b + factor * activeColor.b;
+ red = Math.sqrt(cFactor * Math.pow(idleColor.r, 2) + factor * Math.pow(activeColor.r, 2));
+ green = Math.sqrt(cFactor * Math.pow(idleColor.g, 2) + factor * Math.pow(activeColor.g, 2));
+ blue = Math.sqrt(cFactor * Math.pow(idleColor.b, 2) + factor * Math.pow(activeColor.b, 2));
} else { // Red over 1MB/s
// Blending active (green) and peak (red) color
var factor = (link.colorIntensity - 1000)/ (maxIntensity - 1000);
var cFactor = 1 - factor;
- red = cFactor * activeColor.r + factor * peakColor.r;
- green = cFactor * activeColor.g + factor * peakColor.g;
- blue = cFactor * activeColor.b + factor * peakColor.b;
- //console.log(" " + red + " " + " " + green + " " + " " + blue)
+ red = Math.sqrt(cFactor * Math.pow(activeColor.r, 2) + factor * Math.pow(peakColor.r, 2));
+ green = Math.sqrt(cFactor * Math.pow(activeColor.g, 2) + factor * Math.pow(peakColor.g, 2));
+ blue = Math.sqrt(cFactor * Math.pow(activeColor.b, 2) + factor * Math.pow(peakColor.b, 2));
}
- //console.log(" " + red + " " + " " + green + " " + " " + blue)
link.color = "rgb("+ Math.floor(red) + ", " + Math.floor(green) + ", " + Math.floor(blue) + ")";
}
+ // Update the color of a link in the svg.
+ function updateLinkColor(link){
+ // Prevent future searches for links to improve performance.
+ if(!link.visObject) {
+ link.visObject = vis.select("#" + link.source.id + "-" + link.target.id);
+ }
+ var visLink = link.visObject;
+ visLink.style({stroke: function(d) { return d.color; }});
+ }
+
+ // Interval for fading out the color of active links
+ window.setInterval(decayLinkColor, 500);
+ function decayLinkColor() {
+ 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) {
+ // Fading rate of colored links
+ var fadingValue = (link.colorIntensity * 0.15) + 10;
+ link.colorIntensity -= fadingValue;
+ if (link.colorIntensity < 0) {
+ link.colorIntensity = 0;
+ } else if (link.colorIntensity < link.downloadRate) {
+ link.colorIntensity = link.downloadRate;
+ }
+ colorLink(link);
+ updateLinkColor(link);
+ }
+ }
+ }
+
+
+ // Set the color intensity of link according to its download rate.
+ function increasColorIntensity(link) {
+ if (link.colorIntensity < link.downloadRate) {
+ link.colorIntensity = link.downloadRate;
+ }
+ if (link.colorIntensity >= maxIntensity) {
+ link.colorIntensity = maxIntensity;
+ }
+ }
+
function findLink(sourceId, targetId) {
for (var i = 0; i < links.length; ++i) {
if ( (links[i].source === sourceId && links[i].target === targetId)
@@ -270,137 +306,131 @@ function myGraph(el) {
.friction(0.5)
.size([w, h]);
-
nodes = force.nodes();
links = force.links();
+
this.update = function () {
- update();
+ if(changed){
+ update();
+ }
}
-
+ // Update the complete svg. Performance intensive.
function update () {
+ changed = false;
+
+ var node = vis.selectAll("g.node")
+ .data(nodes, function(d) { return d.id; });
+
+ 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;");
+ }
- 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; }});
-
- // change color of exitsting nodes
- link.style({stroke: function(d) { return d.color; }});
-
- if (changed){
- changed = false;
+ // Increase line width of server in traffic 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;
+ });
- 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;");
- }
+ nodeEnter.append("circle")
+ .attr("class", "circle")
+ .attr("r", function(d) { return d.radius; })
+ .style("fill", function(d) { return d.color; });
- // Increase line width of server in traffic 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; });
- nodeEnter.append("text")
- .attr("class", "nodetext")
- .attr("dx", -32)
- .attr("dy", "-1em")
- .text(function(d) {return d.title});
+ link.enter().insert("line")
+ .attr("class", "link")
+ .attr("id", function(d) {return d.id; })
+ .style({stroke: function(d) { return d.color; }});
- node.exit().remove();
+ // Aplly color of exitsting nodes
+ link.style({stroke: function(d) { return d.color; }});
- link.exit().remove();
+ link.exit().remove();
- vis.selectAll('g.node').forEach(function(e){$('#graph').find('svg').append(e)});
+ 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;
+ 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;
}
- 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) + ")";
- });
- };
+ ccCount++;
+ ccX += d.x;
+ ccY += d.y;
+ return "translate(" + fixX(d.x) + "," + fixY(d.y) + ")";
+ });
+ };
- force.on("tick", render);
+ force.on("tick", render);
- updateBounds();
- force.start();
- }
+ updateBounds();
+ force.start();
}
-
- window.onresize = forceUpdate;
-
- function forceUpdate () {
- changed = true;
- update();
- }
- forceUpdate();
+ window.onresize = update;
+ update();
}
graph = new myGraph("#graph");
-
var servers = {};
var serverCount = 0;
var lastTime = 0;
@@ -424,7 +454,6 @@ setInterval( function() {
}, 2000);
-
// Update data of the graph
function updateGraph(g, data){
if (g) {
@@ -441,7 +470,6 @@ function updateGraph(g, data){
}
-
// Convert bytes to GiB or TiB and return a string in form "10,23 GiB"
function bytesToString( bytes ) {
var convertedValue;
@@ -527,4 +555,4 @@ function updateTrafficGraph(stats, data){
}
}
-</script>
+</script> \ No newline at end of file