mirror of https://git.openwrt.org/project/luci.git
Completed LuCI Livestats
This commit is contained in:
parent
dd74b986a0
commit
5c61c377c1
|
@ -1,4 +1,4 @@
|
||||||
function Graph(container, id, options, transform) {
|
function Graph(container, id, options, transform, legend) {
|
||||||
if( !options ) options = { };
|
if( !options ) options = { };
|
||||||
|
|
||||||
this.id = id;
|
this.id = id;
|
||||||
|
@ -7,11 +7,15 @@ function Graph(container, id, options, transform) {
|
||||||
this.options = options;
|
this.options = options;
|
||||||
this.transform = transform;
|
this.transform = transform;
|
||||||
this.dataset = {};
|
this.dataset = {};
|
||||||
|
this.legend = legend;
|
||||||
|
this.lastvalue = {};
|
||||||
|
|
||||||
|
var name = (options.instanceNames && options.instanceNames[id])
|
||||||
|
? options.instanceNames[id] : id;
|
||||||
var graph = document.createElement('div');
|
var graph = document.createElement('div');
|
||||||
var label = document.createElement('h2');
|
var label = document.createElement('h2');
|
||||||
label.innerHTML = options.title
|
label.innerHTML = options.title
|
||||||
? options.title.replace("%s", id ) : id;
|
? options.title.replace("%s", name) : name;
|
||||||
|
|
||||||
container.appendChild( label );
|
container.appendChild( label );
|
||||||
container.appendChild( graph );
|
container.appendChild( graph );
|
||||||
|
@ -49,8 +53,9 @@ Graph.prototype.updateDataset = function(name, value) {
|
||||||
value = Math.abs( parseFloat(value) || 0 );
|
value = Math.abs( parseFloat(value) || 0 );
|
||||||
|
|
||||||
if( this.transform ) {
|
if( this.transform ) {
|
||||||
value = ( ds[this.cols-1][1] > 0 )
|
var orgvalue = value;
|
||||||
? this.transform(value, ds[this.cols-1][1]) : 0.01;
|
value = (this.lastvalue[name]) ? this.transform(value, this.lastvalue[name]) : 0;
|
||||||
|
this.lastvalue[name] = orgvalue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ds[this.cols-1][1] = value;
|
ds[this.cols-1][1] = value;
|
||||||
|
@ -66,6 +71,13 @@ Graph.prototype.draw = function( options ) {
|
||||||
|
|
||||||
this.layout.evaluate();
|
this.layout.evaluate();
|
||||||
this.plotter.render();
|
this.plotter.render();
|
||||||
|
|
||||||
|
legend_opt = {
|
||||||
|
"legendStyle": 'li'
|
||||||
|
};
|
||||||
|
|
||||||
|
legend = new LegendRenderer(this.legend, this.layout, legend_opt);
|
||||||
|
legend.render();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +90,7 @@ Graph.prototype.redraw = function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function GraphRPC(container, uri, action, interval, datasources, options, transform) {
|
function GraphRPC(container, uri, action, interval, datasources, options, transform, legend) {
|
||||||
this.ds = datasources;
|
this.ds = datasources;
|
||||||
this.uri = uri
|
this.uri = uri
|
||||||
this.action = action;
|
this.action = action;
|
||||||
|
@ -87,6 +99,7 @@ function GraphRPC(container, uri, action, interval, datasources, options, transf
|
||||||
this.transform = transform;
|
this.transform = transform;
|
||||||
this.proxy = new MochiKit.JsonRpc.JsonRpcProxy(uri, [action]);
|
this.proxy = new MochiKit.JsonRpc.JsonRpcProxy(uri, [action]);
|
||||||
this.graphs = new Object();
|
this.graphs = new Object();
|
||||||
|
this.legend = legend;
|
||||||
|
|
||||||
this.requestData();
|
this.requestData();
|
||||||
|
|
||||||
|
@ -126,7 +139,7 @@ GraphRPC.prototype.dispatchResponse = function(response) {
|
||||||
if( !this.graphs[gid] ) {
|
if( !this.graphs[gid] ) {
|
||||||
this.options.title = otle.replace('%s', instance) + ': ' + name;
|
this.options.title = otle.replace('%s', instance) + ': ' + name;
|
||||||
this.graphs[gid] = new Graph(
|
this.graphs[gid] = new Graph(
|
||||||
this.container, gid, this.options, this.transform
|
this.container, gid, this.options, this.transform, this.legend
|
||||||
);
|
);
|
||||||
|
|
||||||
this.graphs[gid].addDataset(name);
|
this.graphs[gid].addDataset(name);
|
||||||
|
@ -135,10 +148,18 @@ GraphRPC.prototype.dispatchResponse = function(response) {
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this.graphs[gid].updateDataset(
|
var datum = null;
|
||||||
name, instance
|
if (typeof (this.ds[i]) == "function") {
|
||||||
|
datum = this.ds[i](
|
||||||
|
instance ? response[instance] : response
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
datum = instance
|
||||||
? response[instance][this.ds[i]]
|
? response[instance][this.ds[i]]
|
||||||
: response[this.ds[i]]
|
: response[this.ds[i]]
|
||||||
|
}
|
||||||
|
this.graphs[gid].updateDataset(
|
||||||
|
name, datum
|
||||||
);
|
);
|
||||||
this.graphs[gid].redraw();
|
this.graphs[gid].redraw();
|
||||||
}
|
}
|
||||||
|
@ -148,7 +169,7 @@ GraphRPC.prototype.dispatchResponse = function(response) {
|
||||||
var gid = instance || 'livegraph';
|
var gid = instance || 'livegraph';
|
||||||
if( !this.graphs[gid] ) {
|
if( !this.graphs[gid] ) {
|
||||||
this.graphs[gid] = new Graph(
|
this.graphs[gid] = new Graph(
|
||||||
this.container, gid, this.options, this.transform
|
this.container, gid, this.options, this.transform, this.legend
|
||||||
);
|
);
|
||||||
|
|
||||||
for( var i = 0; i < this.ds.length; i += 2 ) {
|
for( var i = 0; i < this.ds.length; i += 2 ) {
|
||||||
|
@ -161,10 +182,18 @@ GraphRPC.prototype.dispatchResponse = function(response) {
|
||||||
else {
|
else {
|
||||||
for( var i = 0; i < this.ds.length; i += 2 ) {
|
for( var i = 0; i < this.ds.length; i += 2 ) {
|
||||||
var name = this.ds[i+1] || this.ds[i];
|
var name = this.ds[i+1] || this.ds[i];
|
||||||
this.graphs[gid].updateDataset(
|
var datum = null;
|
||||||
name, instance
|
if (typeof (this.ds[i]) == "function") {
|
||||||
|
datum = this.ds[i](
|
||||||
|
instance ? response[instance] : response
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
datum = instance
|
||||||
? response[instance][this.ds[i]]
|
? response[instance][this.ds[i]]
|
||||||
: response[this.ds[i]]
|
: response[this.ds[i]]
|
||||||
|
}
|
||||||
|
this.graphs[gid].updateDataset(
|
||||||
|
name, datum
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,228 @@
|
||||||
|
/*
|
||||||
|
PlotKit Legend
|
||||||
|
==============
|
||||||
|
|
||||||
|
Handles laying out legend into a DIV element.
|
||||||
|
Design taken from comments of Julien Wajsberg (http://
|
||||||
|
groups.google.com/group/plotkit/browse_thread/thread/2494bd88e6e9956d)
|
||||||
|
and Niel Domingo (http://nieldomingo.blogspot.com/2007/03/legend-
|
||||||
|
for-plotkit-bar-charts.html).
|
||||||
|
|
||||||
|
Copyright
|
||||||
|
---------
|
||||||
|
Copyright 2007 (c) Ashley Martens <ashleym_72^yahoo.com>
|
||||||
|
For use under the BSD license. <http://www.liquidx.net/plotkit>
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (typeof(MochiKit.Base) == 'undefined' ||
|
||||||
|
typeof(MochiKit.DOM) == 'undefined' ||
|
||||||
|
typeof(MochiKit.Color) == 'undefined' ||
|
||||||
|
typeof(MochiKit.Format) == 'undefined' ||
|
||||||
|
typeof(PlotKit.Layout) == 'undefined' ||
|
||||||
|
typeof(PlotKit.Base) == 'undefined')
|
||||||
|
{
|
||||||
|
throw "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
throw "PlotKit depends on MochiKit.{Base,Color,DOM,Format}"
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof(PlotKit.LegendRenderer) == 'undefined') {
|
||||||
|
PlotKit.LegendRenderer = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
PlotKit.LegendRenderer = function(element, layout, options) {
|
||||||
|
if (arguments.length > 0)
|
||||||
|
this.__init__(element, layout, options);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
PlotKit.LegendRenderer.NAME = "PlotKit.LegendRenderer";
|
||||||
|
PlotKit.LegendRenderer.VERSION = PlotKit.VERSION;
|
||||||
|
|
||||||
|
PlotKit.LegendRenderer.__repr__ = function() {
|
||||||
|
return "[" + this.NAME + " " + this.VERSION + "]";
|
||||||
|
};
|
||||||
|
|
||||||
|
PlotKit.LegendRenderer.toString = function() {
|
||||||
|
return this.__repr__();
|
||||||
|
}
|
||||||
|
|
||||||
|
PlotKit.LegendRenderer.prototype.__init__ = function(element, layout,
|
||||||
|
options) {
|
||||||
|
var isNil = MochiKit.Base.isUndefinedOrNull;
|
||||||
|
var Color = MochiKit.Color.Color;
|
||||||
|
|
||||||
|
this.options = {
|
||||||
|
"colorScheme": PlotKit.Base.palette(PlotKit.Base.baseColors()
|
||||||
|
[0]),
|
||||||
|
"legendStyle": "table",
|
||||||
|
"tableColumns": 1
|
||||||
|
};
|
||||||
|
MochiKit.Base.update(this.options, options ? options : {});
|
||||||
|
|
||||||
|
this.layout = layout;
|
||||||
|
this.element = MochiKit.DOM.getElement(element);
|
||||||
|
// --- check whether everything is ok before we return
|
||||||
|
|
||||||
|
if (isNil(this.element))
|
||||||
|
throw "CRILegend() - passed legend is not found";
|
||||||
|
};
|
||||||
|
|
||||||
|
PlotKit.LegendRenderer.prototype.render = function() {
|
||||||
|
var colorScheme = this.options.colorScheme;
|
||||||
|
var setNames = PlotKit.Base.keys(this.layout.datasets);
|
||||||
|
|
||||||
|
MochiKit.DOM.updateNodeAttributes(this.element,
|
||||||
|
{"style":
|
||||||
|
{"margin":"0"
|
||||||
|
,"padding":"0"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
var ul = null;
|
||||||
|
if (this.options.legendStyle == "table")
|
||||||
|
ul = this._renderListTable(colorScheme, setNames);
|
||||||
|
else
|
||||||
|
ul = this._renderList(colorScheme, setNames);
|
||||||
|
MochiKit.DOM.appendChildNodes(this.element, ul);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
PlotKit.LegendRenderer.prototype._renderList = function(colorScheme,
|
||||||
|
setNames) {
|
||||||
|
var ul = document.createElement("ul");
|
||||||
|
ul.style.listStyle="none";
|
||||||
|
ul.style.margin="0";
|
||||||
|
ul.style.padding="0";
|
||||||
|
|
||||||
|
var colorCount = colorScheme.length;
|
||||||
|
var setCount = setNames.length;
|
||||||
|
|
||||||
|
for (var i = 0; i < setCount; i++) {
|
||||||
|
var setName = setNames[i];
|
||||||
|
var color = colorScheme[i%colorCount];
|
||||||
|
var le = this._renderElement(setName, color.toRGBString());
|
||||||
|
ul.appendChild(le);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ul;
|
||||||
|
};
|
||||||
|
|
||||||
|
PlotKit.LegendRenderer.prototype._renderElement = function(title,
|
||||||
|
color) {
|
||||||
|
var le = MochiKit.DOM.createDOM("li");
|
||||||
|
le.style.listStyle="none";
|
||||||
|
le.style.margin="0 0 5px 0";
|
||||||
|
le.style.padding="0";
|
||||||
|
|
||||||
|
var box = MochiKit.DOM.createDOM("div");
|
||||||
|
box.style.backgroundColor=color;
|
||||||
|
box.style.width="2em";
|
||||||
|
box.style.height=".9em";
|
||||||
|
box.style.border="1px solid black";
|
||||||
|
box.style.margin="0 5px 0 0";
|
||||||
|
box.style.padding="0";
|
||||||
|
box.style.float="left";
|
||||||
|
box.style.cssFloat="left";
|
||||||
|
box.style.clear="left";
|
||||||
|
box.style.cssClear="left";
|
||||||
|
|
||||||
|
var span = MochiKit.DOM.createDOM("span");
|
||||||
|
MochiKit.DOM.appendChildNodes(span,
|
||||||
|
document.createTextNode(title));
|
||||||
|
|
||||||
|
MochiKit.DOM.appendChildNodes(le, box, span);
|
||||||
|
|
||||||
|
return le;
|
||||||
|
};
|
||||||
|
|
||||||
|
PlotKit.LegendRenderer.prototype._renderListTable =
|
||||||
|
function(colorScheme, setNames) {
|
||||||
|
var tabhead = THEAD(null);
|
||||||
|
var tabfoot = TFOOT(null);
|
||||||
|
|
||||||
|
var tabbody = partial(TBODY, null);
|
||||||
|
var i = 0;
|
||||||
|
var colorcount = colorScheme.length;
|
||||||
|
var tabrow;
|
||||||
|
var columns = this.options.tableColumns;
|
||||||
|
for (var label in setNames)
|
||||||
|
{
|
||||||
|
var legendcolor = colorScheme[i%colorcount];
|
||||||
|
var legendbox = DIV({'class': 'legendbox', 'className':
|
||||||
|
'legendbox'});
|
||||||
|
legendbox.style.width = "10px";
|
||||||
|
legendbox.style.height = "10px";
|
||||||
|
legendbox.style.backgroundColor = legendcolor.toHexString();
|
||||||
|
legendbox.style.borderWidth = "1px";
|
||||||
|
legendbox.style.borderStyle = "solid";
|
||||||
|
legendbox.style.borderColor = "#000000";
|
||||||
|
var boxcell = TD(null, legendbox);
|
||||||
|
|
||||||
|
var labelcell = TD({'class': 'legendlabel', 'className':
|
||||||
|
'legendlabel'}, setNames[i]);
|
||||||
|
labelcell.style.font = 'normal 10pt arial';
|
||||||
|
|
||||||
|
if (!(i % columns))
|
||||||
|
{
|
||||||
|
tabrow = partial(TR, null);
|
||||||
|
}
|
||||||
|
tabrow = partial(tabrow, boxcell, labelcell);
|
||||||
|
if (i % columns)
|
||||||
|
{
|
||||||
|
tabrow = tabrow(null);
|
||||||
|
tabbody = partial(tabbody, tabrow);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if ((setNames % columns))
|
||||||
|
{
|
||||||
|
tabrow = tabrow(TD(null), TD(null));
|
||||||
|
tabbody = partial(tabbody, tabrow);
|
||||||
|
}
|
||||||
|
tabbody = tabbody(null);
|
||||||
|
|
||||||
|
tab = TABLE({'class': 'legendcontainer', 'className':
|
||||||
|
'legendcontainer'}, tabhead, tabfoot, tabbody);
|
||||||
|
tab.style.marginTop = '1em';
|
||||||
|
tab.style.marginLeft = '1.5em';
|
||||||
|
tab.style.marginBottom = '1em';
|
||||||
|
tab.style.borderWidth = '1px';
|
||||||
|
tab.style.borderStyle = 'solid';
|
||||||
|
tab.style.borderColor = '#000000';
|
||||||
|
|
||||||
|
return tab;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Namespace Iniitialisation
|
||||||
|
|
||||||
|
PlotKit.Legend = {}
|
||||||
|
PlotKit.Legend.LegendRenderer = PlotKit.LegendRenderer;
|
||||||
|
|
||||||
|
|
||||||
|
PlotKit.Legend.EXPORT = [
|
||||||
|
"LegendRenderer"
|
||||||
|
];
|
||||||
|
|
||||||
|
PlotKit.Legend.EXPORT_OK = [
|
||||||
|
"LegendRenderer"
|
||||||
|
];
|
||||||
|
|
||||||
|
PlotKit.Legend.__new__ = function() {
|
||||||
|
var m = MochiKit.Base;
|
||||||
|
|
||||||
|
m.nameFunctions(this);
|
||||||
|
|
||||||
|
this.EXPORT_TAGS = {
|
||||||
|
":common": this.EXPORT,
|
||||||
|
":all": m.concat(this.EXPORT, this.EXPORT_OK)
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
PlotKit.Legend.__new__();
|
||||||
|
MochiKit.Base._exportSymbols(this, PlotKit.Legend);
|
|
@ -19,7 +19,11 @@ function index()
|
||||||
require("luci.i18n")
|
require("luci.i18n")
|
||||||
luci.i18n.loadc("livestats")
|
luci.i18n.loadc("livestats")
|
||||||
|
|
||||||
entry( {"admin", "status", "wifistat"}, template("livestats/wireless"), luci.i18n.translate("livestat_wireless", "Live Wireless Statistics"), 90 ).i18n = "livestat"
|
entry( {"admin", "status", "wifistat"}, template("livestats/wireless"), luci.i18n.translate("livestats_stat_wireless"), 90 ).i18n = "livestats"
|
||||||
entry( {"admin", "status", "trafstat"}, template("livestats/traffic"), luci.i18n.translate("livestat_traffic", "Live Traffic Statistics"), 91 ).i18n = "livestat"
|
entry( {"admin", "status", "trafstat"}, template("livestats/traffic"), luci.i18n.translate("livestats_stat_traffic"), 91 ).i18n = "livestats"
|
||||||
entry( {"admin", "status", "loadavg"}, template("livestats/loadavg"), luci.i18n.translate("livestat_loadavg", "Live Load Statistics"), 92 ).i18n = "livestat"
|
entry( {"admin", "status", "loadavg"}, template("livestats/loadavg"), luci.i18n.translate("livestats_stat_loadavg"), 92 ).i18n = "livestats"
|
||||||
|
|
||||||
|
entry( {"mini", "network", "wifistat"}, template("livestats/wireless"), luci.i18n.translate("livestats_stat_wireless"), 90 ).i18n = "livestats"
|
||||||
|
entry( {"mini", "network", "trafstat"}, template("livestats/traffic"), luci.i18n.translate("livestats_stat_traffic"), 91 ).i18n = "livestats"
|
||||||
|
entry( {"mini", "system", "loadavg"}, template("livestats/loadavg"), luci.i18n.translate("livestats_stat_loadavg"), 92 ).i18n = "livestats"
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
livestats_incoming = "eingehend"
|
||||||
|
livestats_outgoing = "ausgehend"
|
||||||
|
livestats_traffic = "Netzverkehr auf"
|
||||||
|
livestats_wifi = "Signal-Rauschabstand für"
|
||||||
|
livestats_loadavg = "Durchschnittliche Systemlast"
|
||||||
|
livestats_stat_wireless = "Echtzeit-Drahtlosstatus"
|
||||||
|
livestats_stat_traffic = "Echtzeit-Netzwerkverkehr"
|
||||||
|
livestats_stat_loadavg = "Echtzeit-Systemlast"
|
|
@ -0,0 +1,8 @@
|
||||||
|
livestats_incoming = "incoming"
|
||||||
|
livestats_outgoing = "outgoing"
|
||||||
|
livestats_traffic = "traffic on"
|
||||||
|
livestats_wifi = "signal-to-noise ratio for"
|
||||||
|
livestats_loadavg = "load average"
|
||||||
|
livestats_stat_wireless = "Realtime Wireless Status"
|
||||||
|
livestats_stat_traffic = "Realtime Network Traffic"
|
||||||
|
livestats_stat_loadavg = "Realtime System Load"
|
|
@ -5,19 +5,9 @@
|
||||||
<script type="text/javascript" src="<%=resource%>/livestats/JsonRpc.js"></script>
|
<script type="text/javascript" src="<%=resource%>/livestats/JsonRpc.js"></script>
|
||||||
<script type="text/javascript" src="<%=resource%>/livestats/PlotKit.js"></script>
|
<script type="text/javascript" src="<%=resource%>/livestats/PlotKit.js"></script>
|
||||||
<script type="text/javascript" src="<%=resource%>/livestats/GraphRPC.js"></script>
|
<script type="text/javascript" src="<%=resource%>/livestats/GraphRPC.js"></script>
|
||||||
|
<script type="text/javascript" src="<%=resource%>/livestats/Legend.js"></script>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
PlotKit.Base.baseColors = function () {
|
|
||||||
var hexColor = MochiKit.Color.Color.fromHexString;
|
|
||||||
return [hexColor("#ff0000"),
|
|
||||||
hexColor("#ff6000"),
|
|
||||||
hexColor("#fff000"),
|
|
||||||
hexColor("#00ff00"),
|
|
||||||
hexColor("#00ff77"),
|
|
||||||
hexColor("#0090ff"),
|
|
||||||
hexColor("#000000")];
|
|
||||||
};
|
|
||||||
|
|
||||||
function initGraphs() {
|
function initGraphs() {
|
||||||
var rpc = new GraphRPC(
|
var rpc = new GraphRPC(
|
||||||
document.getElementById('live_graphs'),
|
document.getElementById('live_graphs'),
|
||||||
|
@ -25,14 +15,14 @@
|
||||||
2000,
|
2000,
|
||||||
|
|
||||||
// Data sources
|
// Data sources
|
||||||
[ 0, "1 Minute Load", 1, "5 Minutes Load", 2, "15 Minutes Load" ],
|
[ 0, "1 min", 1, "5 min", 2, "15 min" ],
|
||||||
|
|
||||||
// Graph layout options
|
// Graph layout options
|
||||||
{ shouldFill: false, drawBackground: false, strokeColor: null,
|
{ title: '<%:livestats_loadavg%>', strokeWidth: 2.5, shouldFill: false, strokeColor: null,
|
||||||
strokeColorTransform: "asFillColor",
|
|
||||||
title: 'Average Load', strokeWidth: 1,
|
|
||||||
padding: { left: 70, right: 10, top: 10, bottom: 20 },
|
padding: { left: 70, right: 10, top: 10, bottom: 20 },
|
||||||
instances: [ false ], yAxis: [ 0, 2 ] }
|
instances: [ false ], yAxis: [ 0, 2 ], drawBackground: false },
|
||||||
|
null,
|
||||||
|
'live_graphs'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,5 +30,4 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div id="live_graphs"></div>
|
<div id="live_graphs"></div>
|
||||||
|
|
||||||
<%+footer%>
|
<%+footer%>
|
||||||
|
|
|
@ -5,9 +5,11 @@
|
||||||
<script type="text/javascript" src="<%=resource%>/livestats/JsonRpc.js"></script>
|
<script type="text/javascript" src="<%=resource%>/livestats/JsonRpc.js"></script>
|
||||||
<script type="text/javascript" src="<%=resource%>/livestats/PlotKit.js"></script>
|
<script type="text/javascript" src="<%=resource%>/livestats/PlotKit.js"></script>
|
||||||
<script type="text/javascript" src="<%=resource%>/livestats/GraphRPC.js"></script>
|
<script type="text/javascript" src="<%=resource%>/livestats/GraphRPC.js"></script>
|
||||||
|
<script type="text/javascript" src="<%=resource%>/livestats/Legend.js"></script>
|
||||||
|
|
||||||
<%
|
<%
|
||||||
local interfaces = { }
|
local interfaces = { }
|
||||||
|
local ifnames = {}
|
||||||
local uci = luci.model.uci.cursor_state()
|
local uci = luci.model.uci.cursor_state()
|
||||||
|
|
||||||
uci:foreach("network", "interface",
|
uci:foreach("network", "interface",
|
||||||
|
@ -16,6 +18,7 @@
|
||||||
table.insert( interfaces,
|
table.insert( interfaces,
|
||||||
"'" .. ( s.ifname or s['.name'] ) .. "'"
|
"'" .. ( s.ifname or s['.name'] ) .. "'"
|
||||||
)
|
)
|
||||||
|
ifnames[s.ifname or s['.name']] = s['.name']
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
)
|
)
|
||||||
|
@ -29,20 +32,29 @@
|
||||||
2000,
|
2000,
|
||||||
|
|
||||||
// Data sources
|
// Data sources
|
||||||
[ "1", "received Bytes/s", "9", "transmitted Bytes/s" ],
|
[ "0", "<%:livestats_incoming%> (kiB/s)", "8", "<%:livestats_outgoing%> (kiB/s)" ],
|
||||||
|
|
||||||
// Graph layout options
|
// Graph layout options
|
||||||
{ shouldFill: true, drawBackground: false, strokeColor: null,
|
{
|
||||||
strokeColorTransform: "asFillColor",
|
shouldFill: false,
|
||||||
title: 'Traffic on interface "%s"',
|
drawBackground: false,
|
||||||
separateDS: true, strokeWidth: 0.5, height: 140,
|
strokeColor: null,
|
||||||
padding: { left: 70, right: 10, top: 10, bottom: 20 },
|
title: '<%:livestats_traffic%> %s',
|
||||||
instances: [ <%=table.concat(interfaces, ", ") %> ] },
|
strokeWidth: 2.5, height: 140,
|
||||||
|
padding: { left: 70, right: 10, top: 10, bottom: 20 },
|
||||||
|
instances: [ <%=table.concat(interfaces, ", ") %> ],
|
||||||
|
instanceNames: {
|
||||||
|
<%- for iface, network in pairs(ifnames) do %>
|
||||||
|
<%-="%q:%q," % {iface, network}-%>
|
||||||
|
<% end %>
|
||||||
|
"0": ""
|
||||||
|
}},
|
||||||
|
|
||||||
// transform function
|
// transform function
|
||||||
function(thisval, lastval) {
|
function (cur, last) {
|
||||||
return ( ( thisval - lastval ) / 2 );
|
return (cur - last) / 2048;
|
||||||
}
|
},
|
||||||
|
'live_graphs'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
<script type="text/javascript" src="<%=resource%>/livestats/JsonRpc.js"></script>
|
<script type="text/javascript" src="<%=resource%>/livestats/JsonRpc.js"></script>
|
||||||
<script type="text/javascript" src="<%=resource%>/livestats/PlotKit.js"></script>
|
<script type="text/javascript" src="<%=resource%>/livestats/PlotKit.js"></script>
|
||||||
<script type="text/javascript" src="<%=resource%>/livestats/GraphRPC.js"></script>
|
<script type="text/javascript" src="<%=resource%>/livestats/GraphRPC.js"></script>
|
||||||
|
<script type="text/javascript" src="<%=resource%>/livestats/Legend.js"></script>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
function initGraphs() {
|
function initGraphs() {
|
||||||
|
@ -14,12 +15,23 @@
|
||||||
1500,
|
1500,
|
||||||
|
|
||||||
// Data sources
|
// Data sources
|
||||||
[ "Noise level", null, "Signal level", null ],
|
[ function(data) {
|
||||||
|
return parseFloat(data["Signal level"])
|
||||||
|
- parseFloat(data["Noise level"]);
|
||||||
|
}, "S/N (dBm)"],
|
||||||
|
|
||||||
// Graph layout options
|
// Graph layout options
|
||||||
{ drawBackground: false, yAxis: [ 0, 150 ],
|
{ drawBackground: false, yAxis: [ 0, 50 ],
|
||||||
title: 'Wifi Interface "%s": Signal and Noise',
|
title: '<%:livestats_wifi%> %s',
|
||||||
padding: { left: 40, right: 10, top: 10, bottom: 20 } }
|
padding: { left: 40, right: 10, top: 10, bottom: 20 },
|
||||||
|
instanceNames: {
|
||||||
|
<%- for k,v in pairs(luci.sys.wifi.getiwconfig()) do %>
|
||||||
|
<%-="%q:%q," % {k, "%s (%s)" % {k, tostring(v.ESSID)}}-%>
|
||||||
|
<% end %>
|
||||||
|
"0": ""
|
||||||
|
}},
|
||||||
|
null,
|
||||||
|
'live_graphs'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -537,8 +537,8 @@ endef
|
||||||
|
|
||||||
define Package/luci-app-livestats
|
define Package/luci-app-livestats
|
||||||
$(call Package/luci/webtemplate)
|
$(call Package/luci/webtemplate)
|
||||||
DEPENDS+=+luci-admin-full +luci-admin-rpc
|
DEPENDS+=+luci-admin-core +luci-admin-rpc
|
||||||
TITLE:=LuCI Realtime Statistics (Experimental)
|
TITLE:=LuCI Realtime Statistics
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Package/luci-app-livestats/install
|
define Package/luci-app-livestats/install
|
||||||
|
|
|
@ -15,7 +15,7 @@ config interface loopback
|
||||||
#### LAN configuration
|
#### LAN configuration
|
||||||
config interface lan
|
config interface lan
|
||||||
option type bridge
|
option type bridge
|
||||||
option ifname "eth0.0"
|
option ifname "eth0"
|
||||||
option proto static
|
option proto static
|
||||||
option ipaddr 192.168.1.1
|
option ipaddr 192.168.1.1
|
||||||
option netmask 255.255.255.0
|
option netmask 255.255.255.0
|
||||||
|
@ -23,5 +23,5 @@ config interface lan
|
||||||
|
|
||||||
#### WAN configuration
|
#### WAN configuration
|
||||||
config interface wan
|
config interface wan
|
||||||
option ifname "eth0.1"
|
option ifname "wlan0"
|
||||||
option proto dhcp
|
option proto dhcp
|
||||||
|
|
Loading…
Reference in New Issue