152 lines
3.8 KiB
JavaScript
152 lines
3.8 KiB
JavaScript
// graph takes dspeed and uspeed, it queries them every second and draws
|
||
// the last 180 secs, it also takes draw as an optional attribute and only
|
||
// draws the graph when it is true, if not given then graph is always drawn
|
||
angular
|
||
.module('webui.directives.dgraph', ['webui.filters.bytes', 'webui.services.deps'])
|
||
.directive('dgraph', ['$', '$filter', '$parse', function($, filter, parse) {
|
||
var ratio = 0.4;
|
||
var xfmt = "%H:%M:%S";
|
||
var yTicks = 7; // Number of y-axis ticks (sans 0)
|
||
var yTickBase = 10240; // y-axis ticks must be a multiple of this (bytes).
|
||
try {
|
||
// Try to detect AM/PM locales.
|
||
if (!/16/.test(new Date(2000,0,1,16,7,9).toLocaleTimeString())) {
|
||
xfmt = "%I:%M:%S %P";
|
||
}
|
||
}
|
||
catch (ex) {
|
||
// Ignore. Browser does not support toLocaleTimeString.
|
||
}
|
||
|
||
return function(scope, elem, attrs) {
|
||
var canDraw = false;
|
||
|
||
var graphSize = 180
|
||
, dspeed = 0, uspeed = 0, hasSpeeds = false
|
||
, dconf = {
|
||
label: "DOWN",
|
||
data: [],
|
||
color: "#00ff00",
|
||
lines: { show: true }
|
||
}
|
||
, uconf = {
|
||
label: "UP",
|
||
data: [],
|
||
color: "#0000ff",
|
||
lines: { show: true }
|
||
}
|
||
;
|
||
|
||
// hack for the null height for flot elem
|
||
elem.height(elem.width() * ratio);
|
||
|
||
var graph = $.plot(elem, [dconf, uconf], {
|
||
legend: {
|
||
show: true,
|
||
backgroundOpacity: 0,
|
||
margin: [10, 20],
|
||
labelFormatter: function(label, series) {
|
||
if (!series.data.length) {
|
||
return label;
|
||
}
|
||
return label + " (" + filter("bspeed")(series.data[series.data.length-1][1]) + ")";
|
||
},
|
||
position: "sw"
|
||
},
|
||
xaxis: {
|
||
show: true,
|
||
mode: "time",
|
||
timeformat: xfmt,
|
||
minTickSize: [30, "second"] // 180 / 30 == 6
|
||
},
|
||
yaxis: {
|
||
position: "right",
|
||
ticks: function(axis) {
|
||
var res = [0];
|
||
var round = Math.max(1, Math.ceil(axis.max / yTickBase));
|
||
var step = Math.max(1, Math.ceil(round / yTicks));
|
||
for (var s = 1; s <= yTicks; ++s) {
|
||
var c = yTickBase * step * s;
|
||
res.push(c);
|
||
if (c > axis.max) {
|
||
break;
|
||
}
|
||
}
|
||
return res;
|
||
},
|
||
tickFormatter: function(val, axis) {
|
||
return filter('bspeed')(val);
|
||
},
|
||
min: 0
|
||
}
|
||
});
|
||
|
||
var draw = function() {
|
||
var width = elem.width();
|
||
if (width == 0) return;
|
||
|
||
elem.height(width * ratio);
|
||
|
||
graph.setData([dconf, uconf]);
|
||
graph.resize();
|
||
graph.setupGrid();
|
||
graph.draw();
|
||
};
|
||
|
||
function update() {
|
||
if (!hasSpeeds) {
|
||
return;
|
||
}
|
||
|
||
// Convoluted way to get the local date timestamp instead of the UTC one.
|
||
var cnt = new Date();
|
||
cnt = Date.UTC(
|
||
cnt.getFullYear(),
|
||
cnt.getMonth(),
|
||
cnt.getDate(),
|
||
cnt.getHours(),
|
||
cnt.getMinutes(),
|
||
cnt.getSeconds());
|
||
|
||
if (dconf.data.length === graphSize) dconf.data.shift();
|
||
dconf.data.push([cnt, dspeed]);
|
||
|
||
if (uconf.data.length === graphSize) uconf.data.shift();
|
||
uconf.data.push([cnt, uspeed]);
|
||
|
||
// if any parents is collapsable, then confirm if it isnt
|
||
if (canDraw) {
|
||
draw();
|
||
}
|
||
};
|
||
|
||
scope.$watch(attrs.dspeed, function(val) {
|
||
if (val === undefined) {
|
||
return;
|
||
}
|
||
hasSpeeds = true;
|
||
dspeed = parseFloat(val) || 0;
|
||
});
|
||
|
||
scope.$watch(attrs.uspeed, function(val) {
|
||
if (val === undefined) {
|
||
return;
|
||
}
|
||
hasSpeeds = true;
|
||
uspeed = parseFloat(val) || 0;
|
||
});
|
||
|
||
scope.$watch(attrs.draw, function(val) {
|
||
canDraw = val;
|
||
});
|
||
|
||
var interval = setInterval(update, 1000);
|
||
|
||
angular.element(window).bind('resize', draw);
|
||
elem.bind('$destroy', function() {
|
||
clearInterval(interval);
|
||
});
|
||
|
||
};
|
||
}]);
|