a7a89ffd293823df12e72c67f9813a10c93ba765
[project/luci.git] / applications / luci-livestats / htdocs / luci-static / resources / livestats / GraphRPC.js
1 function Graph(container, id, options, transform) {
2 if( !options ) options = { };
3
4 this.id = id;
5 this.cols = 100;
6 this.type = "line";
7 this.options = options;
8 this.transform = transform;
9 this.dataset = {};
10
11 var graph = document.createElement('div');
12 var label = document.createElement('h2');
13 label.innerHTML = options.title
14 ? options.title.replace("%s", id ) : id;
15
16 container.appendChild( label );
17 container.appendChild( graph );
18
19 this.canvas = document.createElement('canvas');
20 graph.appendChild( this.canvas );
21
22 this.canvas.id = id;
23 this.canvas.width = ( options.width || graph.offsetWidth - 20 );
24 this.canvas.height = ( options.height || 300 );
25 }
26
27 Graph.prototype.addDataset = function(name, ds) {
28 if( !this.layout ) {
29 this.layout = new PlotKit.Layout( this.type, this.options );
30 }
31
32 if( !ds ) {
33 ds = new Array();
34 for( var i = 0; i < this.cols; i++ )
35 ds[i] = new Array( i, 0 );
36 }
37
38 this.dataset[name] = ds;
39 this.layout.addDataset(name, ds);
40 }
41
42 Graph.prototype.updateDataset = function(name, value) {
43 if( this.dataset[name] ) {
44 var ds = this.dataset[name];
45
46 for( var i = 1; i < this.cols; i++ )
47 ds[i-1][1] = ds[i][1];
48
49 value = Math.abs( parseFloat(value) || 0 );
50
51 if( this.transform ) {
52 value = ( ds[this.cols-1][1] > 0 )
53 ? this.transform(value, ds[this.cols-1][1]) : 0.01;
54 }
55
56 ds[this.cols-1][1] = value;
57 this.layout.addDataset(name, ds);
58 }
59 }
60
61 Graph.prototype.draw = function( options ) {
62 if( this.layout ) {
63 this.plotter = new PlotKit.CanvasRenderer(
64 this.canvas, this.layout, this.options || options || {}
65 );
66
67 this.layout.evaluate();
68 this.plotter.render();
69 }
70 }
71
72 Graph.prototype.redraw = function() {
73 if( this.layout && this.plotter ) {
74 this.layout.evaluate();
75 this.plotter.clear();
76 this.plotter.render();
77 }
78 }
79
80
81 function GraphRPC(container, uri, action, interval, datasources, options, transform) {
82 this.ds = datasources;
83 this.uri = uri
84 this.action = action;
85 this.options = options || { };
86 this.container = container;
87 this.transform = transform;
88 this.proxy = new MochiKit.JsonRpc.JsonRpcProxy(uri, [action]);
89 this.graphs = new Object();
90
91 this.requestData();
92
93 if( interval ) {
94 var self = this;
95 window.setInterval(function(){self.requestData()}, interval);
96 }
97 }
98
99 GraphRPC.prototype.requestData = function() {
100 var r = this.proxy[this.action](); var self = this;
101 r.addCallback(function(r){ self.dispatchResponse(r) });
102 r.addErrback(function(e){ throw('Error: ' + e) });
103 }
104
105 GraphRPC.prototype.dispatchResponse = function(response) {
106 var instances;
107 if( this.options.instances ) {
108 instances = this.options.instances;
109 }
110 else {
111 instances = new Array();
112 for( var instance in response ) {
113 instances[instances.length] = instance;
114 }
115 }
116
117 for( var j = 0; j < instances.length; j++ ) {
118 var instance = instances[j];
119
120 if( this.options.separateDS ) {
121 for( var i = 0; i < this.ds.length; i += 2 ) {
122 var name = this.ds[i+1] || this.ds[i];
123 var gid = instance + '-' + name;
124 var otle = this.options.title || instance;
125
126 if( !this.graphs[gid] ) {
127 this.options.title = otle.replace('%s', instance) + ': ' + name;
128 this.graphs[gid] = new Graph(
129 this.container, gid, this.options, this.transform
130 );
131
132 this.graphs[gid].addDataset(name);
133 this.graphs[gid].draw();
134 this.options.title = otle;
135 }
136 else
137 {
138 this.graphs[gid].updateDataset(
139 name, instance
140 ? response[instance][this.ds[i]]
141 : response[this.ds[i]]
142 );
143 this.graphs[gid].redraw();
144 }
145 }
146 }
147 else {
148 var gid = instance || 'livegraph';
149 if( !this.graphs[gid] ) {
150 this.graphs[gid] = new Graph(
151 this.container, gid, this.options, this.transform
152 );
153
154 for( var i = 0; i < this.ds.length; i += 2 ) {
155 var name = this.ds[i+1] || this.ds[i];
156 this.graphs[gid].addDataset(name);
157 }
158
159 this.graphs[gid].draw();
160 }
161 else {
162 for( var i = 0; i < this.ds.length; i += 2 ) {
163 var name = this.ds[i+1] || this.ds[i];
164 this.graphs[gid].updateDataset(
165 name, instance
166 ? response[instance][this.ds[i]]
167 : response[this.ds[i]]
168 );
169 }
170
171 this.graphs[gid].redraw();
172 }
173 }
174 }
175 }