Project

General

Profile

« Previous | Next » 

Revision fe5c31bb

Added by Pi Ba over 8 years ago

traffic-graphs, setting to keep updating them while invisible
- allow showing different graphs to be shown on different browser tabs (dont use localstorage for graphs to query)
- show interface name in graph instead of realname

View differences:

src/usr/local/www/js/traffic-graphs.js
16 16
 * limitations under the License.
17 17
 */
18 18

  
19
function draw_graph(refreshInterval, then) {
19
function draw_graph(refreshInterval, then, backgroundupdate) {
20 20

  
21 21
	d3.select("div[id^=nvtooltip-]").remove();
22 22
	d3.select(".interface-label").remove();
......
28 28
	then.setSeconds(then.getSeconds() - startTime);
29 29
	var thenTime = then.getTime();
30 30

  
31
	$.each( JSON.parse(localStorage.getItem('interfaces')), function( key, value ) {
32

  
31
	$.each( window.interfaces, function( key, value ) {
32
		myData[value]['interfacename'] = graph_interfacenames[value];
33 33
		latest[value + 'in'] = 0;
34 34
		latest[value + 'out'] = 0;
35 35

  
......
65 65
					return d3.time.format('%M:%S')(new Date(d));
66 66
				});
67 67

  
68
			//TODO change to localStorage.getItem('sizeLabel');
69 68
			var sizeLabel = $( "#traffic-graph-size option:selected" ).text();
70 69

  
71 70
			d3.select('#traffic-chart-' + value + ' svg')
......
74 73
				.attr("x", 20)             
75 74
				.attr("y", 20)
76 75
				.attr("font-size", 18)
77
				.text(value);
76
				.text(myData[value]['interfacename']);
78 77

  
79 78
			charts[value].yAxis
80 79
		    	.tickFormat(d3.format('.2s'))
......
126 125

  
127 126
	});
128 127

  
129
	//only update the graphs when tab is active in window to save resources and prevent build up
130
	updateIds = Visibility.every(refreshInterval * 1000, function(){
131

  
128
	var refreshGraphFunction = function(){
132 129
		d3.json("ifstats.php")
133 130
		.header("Content-Type", "application/x-www-form-urlencoded")
134
		.post('if='+JSON.parse(localStorage.getItem('interfaces')).join('|'), function(error, json) { //TODO all ifs again
131
		.post('if='+window.interfaces.join('|'), function(error, json) { //TODO all ifs again
135 132

  
136 133
			if (error) {
137 134

  
138 135
				Visibility.stop(updateIds);
136
				clearInterval(updateTimerIds);
139 137
				$(".traffic-widget-chart").remove();
140 138
				$("#traffic-chart-error").show().html('<strong>Error</strong>: ' + error);
141 139
				return console.warn(error);
......
145 143
			if (json.error) {
146 144

  
147 145
				Visibility.stop(updateIds);
146
				clearInterval(updateTimerIds);
148 147
				$(".traffic-widget-chart").remove();
149 148
				$("#traffic-chart-error").show().html('<strong>Error</strong>: ' + json.error);
150 149
				return console.warn(json.error);
......
154 153
			now = new Date(Date.now());
155 154

  
156 155
			$.each(json, function( key, ifVals ) {
156
				label = $('#traffic-chart-' + key + ' svg > .interface-label');
157
				$(label).text(ifVals.name);
157 158

  
158 159
				if(!myData[key][0].first) {
159 160

  
......
202 203

  
203 204
		});
204 205

  
205
	});
206

  
206
	}
207
	
208
	if(backgroundupdate) {
209
		updateTimerIds = setInterval(refreshGraphFunction, refreshInterval * 1000);
210
	} else {
211
		//only update the graphs when tab is active in window to save resources and prevent build up
212
		updateIds = Visibility.every(refreshInterval * 1000, refreshGraphFunction);
213
	}
207 214
}
src/usr/local/www/status_graph.php
104 104
} else {
105 105
	$curhostipformat = "";
106 106
}
107
if ($_POST['backgroundupdate']) {
108
	$curbackgroundupdate = $_POST['backgroundupdate'];
109
} else {
110
	$curbackgroundupdate = "";
111
}
107 112

  
108 113
function iflist() {
109 114
	global $ifdescrs;
......
168 173
	)
169 174
))->setHelp('Display');
170 175

  
176
$group->add(new Form_Select(
177
	'backgroundupdate',
178
	null,
179
	$curbackgroundupdate,
180
	array (
181
		'false'	=> gettext('Clear graphs when not visible.'),
182
		'true'	=> gettext('Keep graphs updated on inactive tab. (increases cpu usage)'),
183
	)
184
))->setHelp('Background updates');
185

  
171 186
$section->add($group);
172 187

  
173 188
$form->add($section);
......
190 205

  
191 206
	//store saved settings in a fresh localstorage
192 207
	localStorage.clear();
193
	localStorage.setItem('interfaces', JSON.stringify(InterfaceString.split("|"))); //TODO see if can be switched to interfaces
194 208
	localStorage.setItem('interval', 1);
195 209
	localStorage.setItem('invert', "true");
196 210
	localStorage.setItem('size', 1);
197

  
211
	window.interfaces = InterfaceString.split("|");
198 212
	window.charts = {};
199 213
    window.myData = {};
200 214
    window.updateIds = 0;
215
    window.updateTimerIds = 0;
201 216
    window.latest = [];
202 217
    var refreshInterval = localStorage.getItem('interval');
203 218

  
......
206 221

  
207 222
    var nowTime = now.getTime();
208 223

  
209
	$.each( JSON.parse(localStorage.getItem('interfaces')), function( key, value ) {
224
	$.each( window.interfaces, function( key, value ) {
210 225

  
211 226
		myData[value] = [];
212 227
		updateIds = 0;
228
		updateTimerIds = 0;
213 229

  
214 230
		var itemIn = new Object();
215 231
		var itemOut = new Object();
......
228 244

  
229 245
	});
230 246

  
231
	draw_graph(refreshInterval, then);
247
    var backgroundupdate = $('#backgroundupdate').val() === "true";
248
	draw_graph(refreshInterval, then, backgroundupdate);
232 249

  
233 250
	//re-draw graph when the page goes from inactive (in it's window) to active
234 251
	Visibility.change(function (e, state) {
252
		if($('#backgroundupdate').val() === "true"){
253
			return;
254
		}
235 255
		if(state === "visible") {
236 256

  
237 257
			now = then = new Date(Date.now());
238 258

  
239 259
			var nowTime = now.getTime();
240 260

  
241
			$.each( JSON.parse(localStorage.getItem('interfaces')), function( key, value ) {
261
			$.each( window.interfaces, function( key, value ) {
242 262

  
243 263
				Visibility.stop(updateIds);
264
				clearInterval(updateTimerIds);
244 265

  
245 266
				myData[value] = [];
246 267

  
......
261 282

  
262 283
			});
263 284

  
264
			draw_graph(refreshInterval, then);
285
			draw_graph(refreshInterval, then, false);
265 286

  
266 287
		}
267 288
	});
268 289

  
269
	// save new config defaults
270
    $( '#traffic-graph-form' ).submit(function(event) {
271

  
272
		var error = false;
273
		$("#traffic-chart-error").hide();
274

  
275
		var interfaces = $( "#traffic-graph-interfaces" ).val();
276
		refreshInterval = parseInt($( "#traffic-graph-interval" ).val());
277
		var invert = $( "#traffic-graph-invert" ).val();
278
		var size = $( "#traffic-graph-size" ).val();
279

  
280
		//TODO validate interfaces data and throw error
281

  
282
		if(!Number.isInteger(refreshInterval) || refreshInterval < 1 || refreshInterval > 10) {
283
			error = 'Refresh Interval is not a valid number between 1 and 10.';
284
		}
285

  
286
		if(invert != "true" && invert != "false") {
287

  
288
			error = 'Invert is not a boolean of true or false.';
289

  
290
		}
291

  
292
		if(!error) {
293

  
294
			var formData = {
295
				'traffic-graph-interfaces' : interfaces,
296
				'traffic-graph-interval'   : refreshInterval,
297
				'traffic-graph-invert'     : invert,
298
				'traffic-graph-size'       : size
299
			};
300

  
301
			$.ajax({
302
				type        : 'POST',
303
				url         : '/widgets/widgets/traffic_graphs.widget.php',
304
				data        : formData,
305
				dataType    : 'json',
306
				encode      : true
307
			})
308
			.done(function(message) {
309

  
310
				if(message.success) {
311

  
312
					Visibility.stop(updateIds);
313

  
314
					//remove all old graphs (divs/svgs)
315
					$( ".traffic-widget-chart" ).remove();
316

  
317
					localStorage.setItem('interfaces', JSON.stringify(interfaces));
318
					localStorage.setItem('interval', refreshInterval);
319
					localStorage.setItem('invert', invert);
320
					localStorage.setItem('size', size);
321

  
322
					//redraw graph with new settings
323
					now = then = new Date(Date.now());
324

  
325
					var freshData = [];
326

  
327
					var nowTime = now.getTime();
328

  
329
					$.each( interfaces, function( key, value ) {
330

  
331
						//create new graphs (divs/svgs)
332
						$("#widget-traffic_graphs_panel-body").append('<div id="traffic-chart-' + value + '" class="d3-chart traffic-widget-chart"><svg></svg></div>');
333

  
334
						myData[value] = [];
335

  
336
						var itemIn = new Object();
337
						var itemOut = new Object();
338

  
339
						itemIn.key = value + " (in)";
340
						if(localStorage.getItem('invert') === "true") { itemIn.area = true; }
341
						itemIn.first = true;
342
						itemIn.values = [{x: nowTime, y: 0}];
343
						myData[value].push(itemIn);
344

  
345
						itemOut.key = value + " (out)";
346
						if(localStorage.getItem('invert') === "true") { itemOut.area = true; }
347
						itemOut.first = true;
348
						itemOut.values = [{x: nowTime, y: 0}];
349
						myData[value].push(itemOut);
350

  
351
					});
352

  
353
					draw_graph(refreshInterval, then);
354

  
355
					$( "#traffic-graph-message" ).removeClass("text-danger").addClass("text-success");
356
					$( "#traffic-graph-message" ).text(message.success);
357

  
358
					setTimeout(function() {
359
						$( "#traffic-graph-message" ).empty();
360
						$( "#traffic-graph-message" ).removeClass("text-success");
361
					}, 5000);
362

  
363
				} else {
364

  
365
					$( "#traffic-graph-message" ).addClass("text-danger");
366
					$( "#traffic-graph-message" ).text(message.error);
367

  
368
					console.warn(message.error);
369

  
370
				}
371

  
372
	        })
373
	        .fail(function() {
374

  
375
			    console.warn( "The Traffic Graphs widget AJAX request failed." );
376

  
377
			});
378

  
379
	    } else {
380

  
381
			$( "#traffic-graph-message" ).addClass("text-danger");
382
			$( "#traffic-graph-message" ).text(error);
383

  
384
			console.warn(error);
385

  
386
	    }
387

  
388
        event.preventDefault();
389
    });
390

  
391 290
});
392 291
//]]>
393 292
</script>
......
397 296
<script type="text/javascript">
398 297
//<![CDATA[
399 298

  
299
var graph_interfacenames = <?php
300
	foreach ($ifdescrs as $ifname => $ifdescr) {
301
		$iflist[$ifname] = $ifdescr;
302
	}
303
	echo json_encode($iflist);
304
?>;
400 305
function updateBandwidth() {
401 306
	$.ajax(
402 307
		'/bandwidth_by_ip.php',
src/usr/local/www/widgets/widgets/traffic_graphs.widget.php
56 56
	$config["widgets"]["trafficgraphs"]["refreshinterval"] = 1;
57 57
	$config["widgets"]["trafficgraphs"]["invert"] = "true";
58 58
	$config["widgets"]["trafficgraphs"]["size"] = 1;
59
	$config["widgets"]["trafficgraphs"]["backgroundupdate"] = "false";
59 60
	$config["widgets"]["trafficgraphs"]["shown"] = array();
60 61
	$config["widgets"]["trafficgraphs"]["shown"]["item"] = array();
61 62

  
......
81 82
	$config["widgets"]["trafficgraphs"]["invert"] = "true";
82 83
}
83 84

  
85
if(!isset($config["widgets"]["trafficgraphs"]["backgroundupdate"])) {
86
	$config["widgets"]["trafficgraphs"]["backgroundupdate"] = "true";
87
}
84 88
$a_config = &$config["widgets"]["trafficgraphs"];
85 89

  
86 90
// save new default config options that have been submitted
......
91 95

  
92 96
	// TODO check if between 1 and 10
93 97
	if (isset($_POST["traffic-graph-interval"]) && is_numericint($_POST["traffic-graph-interval"])) {
94

  
95 98
		$a_config["refreshinterval"] = $_POST["traffic-graph-interval"];
96

  
97 99
	} else {
98

  
99 100
		die('{ "error" : "Refresh Interval is not a valid number between 1 and 10." }');
100

  
101 101
	}
102 102

  
103 103
	if($_POST["traffic-graph-invert"] === "true" || $_POST["traffic-graph-invert"] === "false") {
104

  
105 104
		$a_config["invert"] = $_POST["traffic-graph-invert"];
106

  
107 105
	} else {
108

  
109 106
		die('{ "error" : "Invert is not a boolean of true or false." }');
110

  
111 107
	}
112 108

  
109
	if($_POST["traffic-graph-backgroundupdate"] === "true" || $_POST["traffic-graph-backgroundupdate"] === "false") {
110
		$a_config["backgroundupdate"] = $_POST["traffic-graph-backgroundupdate"];
111
	} else {
112
		die('{ "error" : "Backgroundupdate is not a boolean of true or false." }');
113
	}
114
	
113 115
	//TODO validate data and throw error
114 116
	$a_config["size"] = $_POST["traffic-graph-size"];
115 117

  
......
157 159
	?>
158 160

  
159 161
	<script type="text/javascript">
160

  
161 162
//<![CDATA[
163
var graph_interfacenames = <?php
164
	foreach ($ifdescrs as $ifname => $ifdescr) {
165
		$iflist[$ifname] = $ifdescr;
166
	}
167
	echo json_encode($iflist);
168
?>;
169

  
162 170
events.push(function() {
163 171

  
164 172
	var InterfaceString = "<?=$allifs?>";
165 173

  
166 174
	//store saved settings in a fresh localstorage
167 175
	localStorage.clear();
168
	localStorage.setItem('interfaces', JSON.stringify(InterfaceString.split("|"))); //TODO see if can be switched to interfaces
169 176
	localStorage.setItem('interval', <?=$refreshinterval?>);
170 177
	localStorage.setItem('invert', <?=$a_config["invert"]?>);
171 178
	localStorage.setItem('size', <?=$a_config["size"]?>);
179
	localStorage.setItem('backgroundupdate', <?=$a_config["backgroundupdate"]?>);
172 180

  
181
	window.interfaces = InterfaceString.split("|");
173 182
	window.charts = {};
174 183
    window.myData = {};
175 184
    window.updateIds = 0;
185
    window.updateTimerIds = 0;
176 186
    window.latest = [];
177 187
    var refreshInterval = localStorage.getItem('interval');
188
    var backgroundupdate = localStorage.getItem('backgroundupdate');
178 189

  
190
    var refreshInterval = localStorage.getItem('interval');
179 191
    //TODO make it fall on a second value so it increments better
180 192
    var now = then = new Date(Date.now());
181 193

  
182 194
    var nowTime = now.getTime();
183 195

  
184
	$.each( JSON.parse(localStorage.getItem('interfaces')), function( key, value ) {
196
	$.each(window.interfaces, function( key, value ) {
185 197

  
186 198
		myData[value] = [];
187 199
		updateIds = 0;
200
		updateTimerIds = 0;
188 201

  
189 202
		var itemIn = new Object();
190 203
		var itemOut = new Object();
......
203 216

  
204 217
	});
205 218

  
206
	draw_graph(refreshInterval, then);
219
	draw_graph(refreshInterval, then, backgroundupdate);
207 220

  
208 221
	//re-draw graph when the page goes from inactive (in it's window) to active
209 222
	Visibility.change(function (e, state) {
223
		if($('#traffic-graph-backgroundupdate').val() === "true"){
224
			return;
225
		}
210 226
		if(state === "visible") {
211 227

  
212 228
			now = then = new Date(Date.now());
213 229

  
214 230
			var nowTime = now.getTime();
215 231

  
216
			$.each( JSON.parse(localStorage.getItem('interfaces')), function( key, value ) {
232
			$.each(window.interfaces, function( key, value ) {
217 233

  
218 234
				Visibility.stop(updateIds);
235
				clearInterval(updateTimerIds);
219 236

  
220 237
				myData[value] = [];
221 238

  
......
236 253

  
237 254
			});
238 255

  
239
			draw_graph(refreshInterval, then);
256
			draw_graph(refreshInterval, then, backgroundupdate);
240 257

  
241 258
		}
242 259
	});
......
251 268
		refreshInterval = parseInt($( "#traffic-graph-interval" ).val());
252 269
		var invert = $( "#traffic-graph-invert" ).val();
253 270
		var size = $( "#traffic-graph-size" ).val();
271
		var backgroundupdate = $( "#traffic-graph-backgroundupdate" ).val();
254 272

  
255 273
		//TODO validate interfaces data and throw error
256 274

  
......
267 285
		if(!error) {
268 286

  
269 287
			var formData = {
270
				'traffic-graph-interfaces' : interfaces,
271
				'traffic-graph-interval'   : refreshInterval,
272
				'traffic-graph-invert'     : invert,
273
				'traffic-graph-size'       : size
288
				'traffic-graph-interfaces'       : interfaces,
289
				'traffic-graph-interval'         : refreshInterval,
290
				'traffic-graph-invert'           : invert,
291
				'traffic-graph-size'             : size,
292
				'traffic-graph-backgroundupdate' : backgroundupdate
274 293
			};
275 294

  
276 295
			$.ajax({
......
285 304
				if(message.success) {
286 305

  
287 306
					Visibility.stop(updateIds);
307
					clearInterval(updateTimerIds);
288 308

  
289 309
					//remove all old graphs (divs/svgs)
290 310
					$( ".traffic-widget-chart" ).remove();
291 311

  
292
					localStorage.setItem('interfaces', JSON.stringify(interfaces));
312
					window.interfaces = interfaces;
293 313
					localStorage.setItem('interval', refreshInterval);
294 314
					localStorage.setItem('invert', invert);
295 315
					localStorage.setItem('size', size);
316
					localStorage.setItem('backgroundupdate', backgroundupdate);
296 317

  
297 318
					//redraw graph with new settings
298 319
					now = then = new Date(Date.now());
......
325 346

  
326 347
					});
327 348

  
328
					draw_graph(refreshInterval, then);
349
					draw_graph(refreshInterval, then, backgroundupdate);
329 350

  
330 351
					$( "#traffic-graph-message" ).removeClass("text-danger").addClass("text-success");
331 352
					$( "#traffic-graph-message" ).text(message.success);
......
433 454
			</div>
434 455
		</div>
435 456

  
457
		<div class="form-group">
458
			<label for="traffic-graph-backgroundupdate" class="col-sm-3 control-label"><?=gettext('Background updates')?></label>
459
			<div class="col-sm-9">
460
				<select class="form-control" id="traffic-graph-backgroundupdate" name="traffic-graph-backgroundupdate">
461
				<?php
462
					if($a_config["backgroundupdate"] === "true") {
463
						echo '<option value="true" selected>Keep graphs updated on inactive tab. (increases cpu usage)</option>';
464
						echo '<option value="false">Clear graphs when not visible.</option>';
465
					} else {
466
						echo '<option value="true">Keep graphs updated on inactive tab. (increases cpu usage)</option>';
467
						echo '<option value="false" selected>Clear graphs when not visible.</option>';
468
					}
469
				?>
470
				</select>
471
			</div>
472
		</div>
436 473
		<div class="form-group">
437 474
			<div class="col-sm-3 text-right">
438 475
				<button type="submit" class="btn btn-primary"><i class="fa fa-save icon-embed-btn"></i><?=gettext('Save')?></button>

Also available in: Unified diff