1 /*
2 * Copyright (C) 2009 Bruno Prémont <bonbons AT linux-vserver.org>
3 *
4 * This program is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU General Public License as published by the Free Software
6 * Foundation; only version 2 of the License is applicable.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
11 * details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 */
18 // Toggle visibility of a div
19 function toggleDiv(divID) {
20 var div = document.getElementById(divID);
21 var label = document.getElementById(divID+'_sw');
22 var label_txt = null;
23 if (div) {
24 if (div.style.display == 'none') {
25 div.style.display = 'block';
26 label_txt = 'Hide';
27 } else {
28 div.style.display = 'none';
29 label_txt = 'Show';
30 }
31 }
32 if (label_txt && label) {
33 var childCnt = label.childNodes.length;
34 while (childCnt > 0)
35 label.removeChild(label.childNodes[--childCnt]);
36 label.appendChild(document.createTextNode(label_txt));
37 }
38 GraphPositionToolbox(null);
39 }
41 var req = null;
43 // DHTML helper code to asynchronous loading of content
44 function loadXMLDoc(url, query) {
45 if (window.XMLHttpRequest) {
46 req = new XMLHttpRequest();
47 req.onreadystatechange = processReqChange;
48 req.open('POST', url, true);
49 req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
50 req.send(query);
51 } else if (window.ActiveXObject) {
52 req = new ActiveXObject("Microsoft.XMLHTTP");
53 if (req) {
54 req.onreadystatechange = processReqChange;
55 req.open('POST', url, true);
56 req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
57 req.send(query);
58 }
59 }
60 }
62 // DHTML new-content dispatcher
63 function processReqChange(evt) {
64 if (req.readyState == 4) {
65 if (req.status == 200) {
66 var response = req.responseXML.documentElement;
67 var method = response.getElementsByTagName('method')[0].firstChild.data;
68 var result = response.getElementsByTagName('result')[0];
69 req = null;
70 eval(method + '(result)');
71 }
72 }
73 }
75 // Update contents of a <select> drop-down list
76 function refillSelect(options, select) {
77 if (!select)
78 return -1;
80 var childCnt = select.childNodes.length;
81 var oldValue = select.selectedIndex > 0 ? select.options[select.selectedIndex].value : '/';
82 while (childCnt > 0)
83 select.removeChild(select.childNodes[--childCnt]);
85 var optCnt = options ? options.length : 0;
86 if (optCnt == 0) {
87 select.setAttribute('disabled', 'disabled');
88 return -1;
89 } else {
90 select.removeAttribute('disabled');
91 var keepSelection = false;
92 if (optCnt == 1) {
93 keepSelection = true;
94 oldValue = options[0].firstChild ? options[0].firstChild.data : '';
95 } else if (oldValue != '/') {
96 for (i = 0; i < optCnt && !keepSelection; i++)
97 if (oldValue == (options[i].firstChild ? options[i].firstChild.data : ''))
98 keepSelection = true;
99 }
100 newOption = document.createElement("option");
101 newOption.value = '/';
102 if (keepSelection)
103 newOption.setAttribute('disabled', 'disabled');
104 else
105 newOption.setAttribute('selected', 'selected');
106 newOption.setAttribute('style', 'font-style: italic');
107 newOption.appendChild(document.createTextNode('- please select -'));
108 select.appendChild(newOption);
109 for (i = 0; i < optCnt; i++) {
110 newOption = document.createElement("option");
111 newOption.value = options[i].firstChild ? options[i].firstChild.data : '';
112 if (keepSelection && newOption.value == oldValue)
113 newOption.setAttribute('selected', 'selected');
114 if (newOption.value[0] == '@') {
115 newOption.setAttribute('style', 'font-style: italic');
116 if (newOption.value == '@' || newOption.value == '@merge')
117 newOption.appendChild(document.createTextNode('Meta graph'));
118 else if (newOption.value == '@all')
119 newOption.appendChild(document.createTextNode('All entries'));
120 else if (newOption.value == '@merge_sum')
121 newOption.appendChild(document.createTextNode('Meta summed graph'));
122 else if (newOption.value == '@merge_avg')
123 newOption.appendChild(document.createTextNode('Meta averaged graph'));
124 else if (newOption.value == '@merge_stack')
125 newOption.appendChild(document.createTextNode('Meta stacked graph'));
126 else if (newOption.value == '@merge_line')
127 newOption.appendChild(document.createTextNode('Meta lines graph'));
128 else
129 newOption.appendChild(document.createTextNode(newOption.value));
130 } else
131 newOption.appendChild(document.createTextNode(newOption.value));
132 select.appendChild(newOption);
133 }
134 return keepSelection ? select.selectedIndex : -1;
135 }
136 }
138 // Request refresh of host list
139 function ListRefreshHost() {
140 var query = 'action=list_hosts';
141 loadXMLDoc(dhtml_url, query);
142 }
144 // Handle update to host list
145 function ListOfHost(response) {
146 var select = document.getElementById('host_list');
147 var idx = refillSelect(response ? response.getElementsByTagName('option') : null, select);
148 if (idx > 0) {
149 ListRefreshPlugin();
150 } else
151 ListOfPlugin(null);
152 }
154 // Request refresh of plugin list
155 function ListRefreshPlugin() {
156 var host_list = document.getElementById('host_list');
157 var host = host_list.selectedIndex >= 0 ? host_list.options[host_list.selectedIndex].value : '/';
158 if (host != '/') {
159 var query = 'action=list_plugins&host='+encodeURIComponent(host);
160 loadXMLDoc(dhtml_url, query);
161 } else {
162 ListOfPlugin(null);
163 }
164 }
166 // Handle update to plugin list
167 function ListOfPlugin(response) {
168 var select = document.getElementById('plugin_list');
169 var idx = refillSelect(response ? response.getElementsByTagName('option') : null, select);
170 if (idx > 0) {
171 ListRefreshPluginInstance();
172 } else
173 ListOfPluginInstance(null);
174 }
176 // Request refresh of plugin instance list
177 function ListRefreshPluginInstance() {
178 var host_list = document.getElementById('host_list');
179 var host = host_list.selectedIndex >= 0 ? host_list.options[host_list.selectedIndex].value : '/';
180 var plugin_list = document.getElementById('plugin_list');
181 var plugin = plugin_list.selectedIndex >= 0 ? plugin_list.options[plugin_list.selectedIndex].value : '/';
182 if (host != '/' && plugin != '/') {
183 var query = 'action=list_pinsts&host='+encodeURIComponent(host)+'&plugin='+encodeURIComponent(plugin);
184 loadXMLDoc(dhtml_url, query);
185 } else {
186 ListOfPluginInstance(null);
187 }
188 }
190 // Handle update of plugin instance list
191 function ListOfPluginInstance(response) {
192 var select = document.getElementById('pinst_list');
193 var idx = refillSelect(response ? response.getElementsByTagName('option') : null, select);
194 if (idx > 0) {
195 ListRefreshType();
196 } else
197 ListOfType(null);
198 }
200 // Request refresh of type list
201 function ListRefreshType() {
202 var host_list = document.getElementById('host_list');
203 var host = host_list.selectedIndex >= 0 ? host_list.options[host_list.selectedIndex].value : '/';
204 var plugin_list = document.getElementById('plugin_list');
205 var plugin = plugin_list.selectedIndex >= 0 ? plugin_list.options[plugin_list.selectedIndex].value : '/';
206 var pinst_list = document.getElementById('pinst_list');
207 var pinst = pinst_list.selectedIndex >= 0 ? pinst_list.options[pinst_list.selectedIndex].value : '/';
208 if (host != '/' && plugin != '/' && pinst != '/') {
209 var query = 'action=list_types&host='+encodeURIComponent(host)+'&plugin='+encodeURIComponent(plugin)+'&plugin_instance='+encodeURIComponent(pinst);
210 loadXMLDoc(dhtml_url, query);
211 } else {
212 ListOfType(null);
213 }
214 }
216 // Handle update of type list
217 function ListOfType(response) {
218 var select = document.getElementById('type_list');
219 var idx = refillSelect(response ? response.getElementsByTagName('option') : null, select);
220 if (idx > 0) {
221 ListRefreshTypeInstance();
222 } else
223 ListOfTypeInstance(null);
224 }
226 // Request refresh of type instance list
227 function ListRefreshTypeInstance() {
228 var host_list = document.getElementById('host_list');
229 var host = host_list.selectedIndex >= 0 ? host_list.options[host_list.selectedIndex].value : '/';
230 var plugin_list = document.getElementById('plugin_list');
231 var plugin = plugin_list.selectedIndex >= 0 ? plugin_list.options[plugin_list.selectedIndex].value : '/';
232 var pinst_list = document.getElementById('pinst_list');
233 var pinst = pinst_list.selectedIndex >= 0 ? pinst_list.options[pinst_list.selectedIndex].value : '/';
234 var type_list = document.getElementById('type_list');
235 var type = type_list.selectedIndex >= 0 ? type_list.options[type_list.selectedIndex].value : '/';
236 if (host != '/' && plugin != '/' && pinst != '/' && type != '/') {
237 var query = 'action=list_tinsts&host='+encodeURIComponent(host)+'&plugin='+encodeURIComponent(plugin)+'&plugin_instance='+encodeURIComponent(pinst)+'&type='+encodeURIComponent(type);
238 loadXMLDoc(dhtml_url, query);
239 } else {
240 ListOfTypeInstance(null);
241 }
242 }
244 // Handle update of type instance list
245 function ListOfTypeInstance(response) {
246 var select = document.getElementById('tinst_list');
247 var idx = refillSelect(response ? response.getElementsByTagName('option') : null, select);
248 if (idx > 0) {
249 // Enable add button
250 RefreshButtons();
251 } else {
252 // Disable add button
253 RefreshButtons();
254 }
255 }
257 function RefreshButtons() {
258 var host_list = document.getElementById('host_list');
259 var host = host_list.selectedIndex >= 0 ? host_list.options[host_list.selectedIndex].value : '/';
260 var plugin_list = document.getElementById('plugin_list');
261 var plugin = plugin_list.selectedIndex >= 0 ? plugin_list.options[plugin_list.selectedIndex].value : '/';
262 var pinst_list = document.getElementById('pinst_list');
263 var pinst = pinst_list.selectedIndex >= 0 ? pinst_list.options[pinst_list.selectedIndex].value : '/';
264 var type_list = document.getElementById('type_list');
265 var type = type_list.selectedIndex >= 0 ? type_list.options[type_list.selectedIndex].value : '/';
266 var tinst_list = document.getElementById('tinst_list');
267 var tinst = tinst_list.selectedIndex >= 0 ? tinst_list.options[tinst_list.selectedIndex].value : '/';
268 if (host != '/' && plugin != '/' && pinst != '/' && type != '/' && tinst != '/') {
269 document.getElementById('btnAdd').removeAttribute('disabled');
270 } else {
271 document.getElementById('btnAdd').setAttribute('disabled', 'disabled');
272 }
274 var graphs = document.getElementById('graphs');
275 if (graphs.getElementsByTagName('div').length > 1) {
276 document.getElementById('btnClear').removeAttribute('disabled');
277 document.getElementById('btnRefresh').removeAttribute('disabled');
278 } else {
279 document.getElementById('btnClear').setAttribute('disabled', 'disabled');
280 document.getElementById('btnRefresh').setAttribute('disabled', 'disabled');
281 }
282 }
284 var nextGraphId = 1;
285 var graphList = new Array();
287 function GraphAppend() {
288 var host_list = document.getElementById('host_list');
289 var host = host_list.selectedIndex >= 0 ? host_list.options[host_list.selectedIndex].value : '/';
290 var plugin_list = document.getElementById('plugin_list');
291 var plugin = plugin_list.selectedIndex >= 0 ? plugin_list.options[plugin_list.selectedIndex].value : '/';
292 var pinst_list = document.getElementById('pinst_list');
293 var pinst = pinst_list.selectedIndex >= 0 ? pinst_list.options[pinst_list.selectedIndex].value : '/';
294 var type_list = document.getElementById('type_list');
295 var type = type_list.selectedIndex >= 0 ? type_list.options[type_list.selectedIndex].value : '/';
296 var tinst_list = document.getElementById('tinst_list');
297 var tinst = tinst_list.selectedIndex >= 0 ? tinst_list.options[tinst_list.selectedIndex].value : '/';
298 var time_list = document.getElementById('timespan');
299 var timespan = time_list.selectedIndex >= 0 ? time_list.options[time_list.selectedIndex].value : '';
300 var tinyLegend = document.getElementById('tinylegend').checked;
301 var logarithmic = document.getElementById('logarithmic').checked;
302 if (host[0] == '@' || plugin[0] == '@' || pinst[0] == '@' || type[0] == '@' || (tinst[0] == '@' && tinst.substr(0, 5) != '@merge')) {
303 var query = 'action=list_graphs&host='+encodeURIComponent(host)+'&plugin='+encodeURIComponent(plugin)+'&plugin_instance='+encodeURIComponent(pinst);
304 query = query+'&type='+encodeURIComponent(type)+'&type_instance='+encodeURIComponent(tinst)+'×pan='+encodeURIComponent(timespan);
305 query = query+(logarithmic ? '&logarithmic=1' : '')+(tinyLegend ? '&tinylegend=1' : '');
306 loadXMLDoc(dhtml_url, query);
307 } else
308 GraphDoAppend(host, plugin, pinst, type, tinst, timespan, tinyLegend, logarithmic);
309 }
311 function ListOfGraph(response) {
312 var graphs = response ? response.getElementsByTagName('graph') : null;
313 if (graphs && graphs.length > 0) {
314 for (i = 0; i < graphs.length; i++)
315 GraphDoAppend(graphs[i].getAttribute('host'), graphs[i].getAttribute('plugin'), graphs[i].getAttribute('plugin_instance'),
316 graphs[i].getAttribute('type'), graphs[i].getAttribute('type_instance'), graphs[i].getAttribute('timespan'),
317 graphs[i].getAttribute('tinyLegend') == '1', graphs[i].getAttribute('logarithmic') == '1');
318 } else
319 alert('No graph found for adding');
320 }
322 function GraphDoAppend(host, plugin, pinst, type, tinst, timespan, tinyLegend, logarithmic) {
323 var graphs = document.getElementById('graphs');
325 if (host != '/' && plugin != '/' && pinst != '/' && type != '/') {
326 var graph_id = 'graph_'+nextGraphId++;
327 var graph_src = graph_url+'?host='+encodeURIComponent(host)+'&plugin='+encodeURIComponent(plugin)+'&plugin_instance='+encodeURIComponent(pinst)+'&type='+encodeURIComponent(type);
328 var graph_alt = '';
329 var grap_title = '';
330 if (tinst == '@') {
331 graph_alt = host+'/'+plugin+(pinst.length > 0 ? '-'+pinst : '')+'/'+type;
332 graph_title = type+' of '+plugin+(pinst.length > 0 ? '-'+pinst : '')+' plugin for '+host;
333 } else {
334 graph_alt = host+'/'+plugin+(pinst.length > 0 ? '-'+pinst : '')+'/'+type+(tinst.length > 0 ? '-'+tinst : '');
335 graph_title = type+(tinst.length > 0 ? '-'+tinst : '')+' of '+plugin+(pinst.length > 0 ? '-'+pinst : '')+' plugin for '+host;
336 graph_src += '&type_instance='+encodeURIComponent(tinst);
337 }
338 if (logarithmic)
339 graph_src += '&logarithmic=1';
340 if (tinyLegend)
341 graph_src += '&tinylegend=1';
342 if (timespan)
343 graph_src += '×pan='+encodeURIComponent(timespan);
344 var now = new Date();
345 graph_src += '&ts='+now.getTime();
346 graphList.push(graph_id+' '+encodeURIComponent(graph_alt)+(logarithmic ? '&logarithmic=1' : '')+(tinyLegend ? '&tinylegend=1' : '')+'×pan='+encodeURIComponent(timespan));
348 // Graph container
349 newGraph = document.createElement('div');
350 newGraph.setAttribute('class', 'graph');
351 newGraph.setAttribute('id', graph_id);
352 // Graph cell + graph
353 newImg = document.createElement('img');
354 newImg.setAttribute('src', graph_src);
355 newImg.setAttribute('alt', graph_alt);
356 newImg.setAttribute('title', graph_title);
357 newImg.setAttribute('onclick', 'GraphToggleTools("'+graph_id+'")');
358 newGraph.appendChild(newImg);
359 graphs.appendChild(newGraph);
360 }
361 document.getElementById('nograph').style.display = 'none';
362 RefreshButtons();
363 }
365 function GraphDropAll() {
366 var graphs = document.getElementById('graphs');
367 var childCnt = graphs.childNodes.length;
368 while (childCnt > 0)
369 if (graphs.childNodes[--childCnt].id != 'nograph' && (graphs.childNodes[childCnt].nodeName == 'div' || graphs.childNodes[childCnt].nodeName == 'DIV'))
370 graphs.removeChild(graphs.childNodes[childCnt]);
371 else if (graphs.childNodes[childCnt].id == 'nograph')
372 graphs.childNodes[childCnt].style.display = 'block';
373 graphList = new Array();
374 RefreshButtons();
375 }
377 function GraphToggleTools(graph) {
378 var graphId = document.getElementById('ge_graphid').value;
379 var ref_img = null;
380 if (graphId == graph || graph == '') {
381 ref_img = null;
382 } else {
383 var graphDiv = document.getElementById(graph);
384 var imgs = graphDiv ? graphDiv.getElementsByTagName('img') : null;
385 var imgCnt = imgs ? imgs.length : 0;
386 while (imgCnt > 0)
387 if (imgs[--imgCnt].parentNode.getAttribute('class') == 'graph')
388 ref_img = imgs[imgCnt];
389 }
390 if (ref_img) {
391 var ts_sel = document.getElementById('ge_timespan');
392 var src_url = ref_img.src;
393 var ge = document.getElementById('ge');
394 // Fix field values
395 var ts = src_url.match(/×pan=[^&]*/);
396 ts = ts ? ts[0].substr(10) : '';
397 document.getElementById('ge_graphid').value = graph;
398 document.getElementById('ge_tinylegend').checked = src_url.match(/&tinylegend=1/);
399 document.getElementById('ge_logarithmic').checked = src_url.match(/&logarithmic=1/);
400 for (i = 0; i < ts_sel.options.length; i++)
401 if (ts_sel.options[i].value == ts) {
402 ts_sel.selectedIndex = i;
403 break;
404 }
405 // show tools box and position it properly
406 ge.style.display = 'table';
407 GraphPositionToolbox(ref_img);
408 } else {
409 // hide tools box
410 document.getElementById('ge').style.display = 'none';
411 document.getElementById('ge_graphid').value = '';
412 }
413 }
415 function GraphPositionToolbox(ref_img) {
416 var ge = document.getElementById('ge');
417 if (ge.style.display != 'none') {
418 var wl = 0; var wt = 0;
419 var x = ref_img;
420 if (ref_img == null) {
421 var graphDiv = document.getElementById(document.getElementById('ge_graphid').value);
422 var imgs = graphDiv ? graphDiv.getElementsByTagName('img') : null;
423 var imgCnt = imgs ? imgs.length : 0;
424 while (imgCnt > 0)
425 if (imgs[--imgCnt].parentNode.getAttribute('class') == 'graph')
426 ref_img = imgs[imgCnt];
428 if (ref_img == null) {
429 document.getElementById('ge_graphid').value = '';
430 ge.style.display = 'none';
431 return;
432 } else
433 x = ref_img;
434 }
435 while (x != null) {
436 wl += x.offsetLeft;
437 wt += x.offsetTop;
438 x = x.offsetParent;
439 }
440 ge.style.left = (wl + (ref_img.offsetWidth - ge.offsetWidth) / 2)+'px';
441 ge.style.top = (wt + (ref_img.offsetHeight - ge.offsetHeight) / 2)+'px';
442 }
443 }
445 function GraphRefreshAll() {
446 var imgs = document.getElementById('graphs').getElementsByTagName('img');
447 var imgCnt = imgs.length;
448 var now = new Date();
449 var newTS = '&ts='+now.getTime();
450 while (imgCnt > 0)
451 if (imgs[--imgCnt].parentNode.getAttribute('class') == 'graph') {
452 var oldSrc = imgs[imgCnt].src;
453 var newSrc = oldSrc.replace(/&ts=[0-9]+/, newTS);
454 if (newSrc == oldSrc)
455 newSrc = newSrc + newTS;
456 imgs[imgCnt].setAttribute('src', newSrc);
457 }
458 }
460 function GraphRefresh(graph) {
461 var graphElement = null;
462 if (graph == null) {
463 var graphId = document.getElementById('ge_graphid').value;
464 if (graphId != '')
465 graphElement = document.getElementById(graphId);
466 } else
467 graphElement = document.getElementById(graph);
468 if (graphElement != null) {
469 var imgs = graphElement.getElementsByTagName('img');
470 var imgCnt = imgs.length;
471 while (imgCnt > 0)
472 if (imgs[--imgCnt].parentNode.getAttribute('class') == 'graph') {
473 var now = new Date();
474 var newTS = '&ts='+now.getTime();
475 var oldSrc = imgs[imgCnt].src;
476 var newSrc = oldSrc.replace(/&ts=[0-9]+/, newTS);
477 if (newSrc == oldSrc)
478 newSrc = newSrc+newTS;
479 imgs[imgCnt].setAttribute('src', newSrc);
480 break;
481 }
482 }
483 }
485 function GraphAdjust(graph) {
486 var graphId = graph == null ? document.getElementById('ge_graphid').value : graph;
487 var graphElement = document.getElementById(graphId);
488 if (graphElement != null) {
489 var time_list = document.getElementById('ge_timespan');
490 var timespan = time_list.selectedIndex >= 0 ? time_list.options[time_list.selectedIndex].value : '';
491 var tinyLegend = document.getElementById('ge_tinylegend').checked;
492 var logarithmic = document.getElementById('ge_logarithmic').checked
493 var imgs = graphElement.getElementsByTagName('img');
494 var imgCnt = imgs.length;
495 var ref_img = null;
496 while (imgCnt > 0)
497 if (imgs[--imgCnt].parentNode.getAttribute('class') == 'graph') {
498 var now = new Date();
499 var newTS = '&ts='+now.getTime();
500 var oldSrc = imgs[imgCnt].src;
501 var newSrc = oldSrc.replace(/&ts=[^&]*/, newTS);
502 if (newSrc == oldSrc)
503 newSrc = newSrc+newTS;
504 newSrc = newSrc.replace(/&logarithmic=[^&]*/, '');
505 if (logarithmic)
506 newSrc += '&logarithmic=1';
507 newSrc = newSrc.replace(/&tinylegend=[^&]*/, '');
508 if (tinyLegend)
509 newSrc += '&tinylegend=1';
510 newSrc = newSrc.replace(/×pan=[^&]*/, '');
511 if (timespan)
512 newSrc += '×pan='+encodeURIComponent(timespan);
513 imgs[imgCnt].setAttribute('src', newSrc);
515 var myList = Array();
516 for (i = 0; i < graphList.length; i++)
517 if (graphList[i].substring(0, graphId.length) == graphId && graphList[i].charAt(graphId.length) == ' ') {
518 newSrc = graphList[i];
519 newSrc = newSrc.replace(/&logarithmic=[^&]*/, '');
520 newSrc = newSrc.replace(/&tinylegend=[^&]*/, '');
521 newSrc = newSrc.replace(/×pan=[^&]*/, '');
522 newSrc = newSrc+(logarithmic ? '&logarithmic=1' : '')+(tinyLegend ? '&tinylegend=1' : '')+'×pan='+encodeURIComponent(timespan);
523 myList.push(newSrc);
524 continue;
525 } else
526 myList.push(graphList[i]);
527 graphList = myList;
528 window.setTimeout("GraphPositionToolbox(null)", 10);
529 // GraphPositionToolbox(imgs[imgCnt]);
530 break;
531 }
532 }
533 }
535 function GraphRemove(graph) {
536 var graphs = document.getElementById('graphs');
537 var graphId = graph == null ? document.getElementById('ge_graphid').value : graph;
538 var graphElement = document.getElementById(graphId);
539 if (graphElement) {
540 GraphToggleTools('');
541 graphs.removeChild(graphElement);
542 RefreshButtons();
543 if (graphs.getElementsByTagName('div').length == 1)
544 document.getElementById('nograph').style.display = 'block';
546 var myList = Array();
547 for (i = 0; i < graphList.length; i++)
548 if (graphList[i].substring(0, graphId.length) == graphId && graphList[i].charAt(graphId.length) == ' ')
549 continue;
550 else
551 myList.push(graphList[i]);
552 graphList = myList;
553 }
554 }
556 function GraphMoveUp(graph) {
557 var graphs = document.getElementById('graphs');
558 var graphId = graph == null ? document.getElementById('ge_graphid').value : graph;
559 var childCnt = graphs.childNodes.length;
560 var prevGraph = null;
561 for (i = 0; i < childCnt; i++)
562 if (graphs.childNodes[i].nodeName == 'div' || graphs.childNodes[i].nodeName == 'DIV') {
563 if (graphs.childNodes[i].id == 'nograph') {
564 // Skip
565 } else if (graphs.childNodes[i].id == graphId) {
566 var myGraph = graphs.childNodes[i];
567 if (prevGraph) {
568 graphs.removeChild(myGraph);
569 graphs.insertBefore(myGraph, prevGraph);
570 }
571 break;
572 } else
573 prevGraph = graphs.childNodes[i];
574 }
575 for (i = 0; i < graphList.length; i++)
576 if (graphList[i].substring(0, graphId.length) == graphId && graphList[i].charAt(graphId.length) == ' ') {
577 if (i > 0) {
578 var tmp = graphList[i-1];
579 graphList[i-1] = graphList[i];
580 graphList[i] = tmp;
581 }
582 break;
583 }
584 GraphPositionToolbox(null);
585 }
587 function GraphMoveDown(graph) {
588 var graphs = document.getElementById('graphs');
589 var graphId = graph == null ? document.getElementById('ge_graphid').value : graph;
590 var childCnt = graphs.childNodes.length;
591 var nextGraph = null;
592 var myGraph = null;
593 for (i = 0; i < childCnt; i++)
594 if (graphs.childNodes[i].nodeName == 'div' || graphs.childNodes[i].nodeName == 'DIV') {
595 if (graphs.childNodes[i].id == 'nograph') {
596 // Skip
597 } else if (graphs.childNodes[i].id == graphId) {
598 myGraph = graphs.childNodes[i];
599 } else if (myGraph) {
600 nextGraph = graphs.childNodes[i];
601 graphs.removeChild(nextGraph);
602 graphs.insertBefore(nextGraph, myGraph);
603 break;
604 }
605 }
606 for (i = 0; i < graphList.length; i++)
607 if (graphList[i].substring(0, graphId.length) == graphId && graphList[i].charAt(graphId.length) == ' ') {
608 if (i+1 < graphList.length) {
609 var tmp = graphList[i+1];
610 graphList[i+1] = graphList[i];
611 graphList[i] = tmp;
612 }
613 break;
614 }
615 GraphPositionToolbox(null);
616 }
618 function GraphListFromCookie(lname) {
619 if (document.cookie.length > 0) {
620 var cname= 'graphLst'+lname+'=';
621 var cookies = document.cookie.split('; ');
622 for (i = 0; i < cookies.length; i++)
623 if (cookies[i].substring(0, cname.length) == cname)
624 return cookies[i].substring(cname.length).split('/');
625 }
626 return new Array();
627 }
629 function GraphListNameSort(a, b) {
630 if (a[0] > b[0])
631 return 1
632 else if (a[0] < b[0])
633 return -1;
634 else
635 return 0;
636 }
638 function GraphListRefresh() {
639 var select = document.getElementById('GraphList');
640 var childCnt = select.childNodes.length;
641 var oldValue = select.selectedIndex > 0 ? select.options[select.selectedIndex].value : '/';
642 while (childCnt > 0)
643 select.removeChild(select.childNodes[--childCnt]);
645 // Determine available names
646 var options = new Array();
647 if (document.cookie.length > 0) {
648 var cookies = document.cookie.split('; ');
649 for (i = 0; i < cookies.length; i++)
650 if (cookies[i].substring(0, 8) == 'graphLst') {
651 var p = cookies[i].indexOf('=');
652 if (p < 0)
653 continue;
654 options.push(new Array(cookies[i].substring(8, p), cookies[i].substring(p+1).split('/').length));
655 }
656 }
657 options.sort(GraphListNameSort);
659 var optCnt = options ? options.length : 0;
660 if (optCnt == 0) {
661 select.setAttribute('disabled', 'disabled');
662 return -1;
663 } else {
664 select.removeAttribute('disabled');
665 for (i = 0; i < optCnt; i++) {
666 newOption = document.createElement("option");
667 newOption.value = options[i][0];
668 if (newOption.value == oldValue)
669 newOption.setAttribute('selected', 'selected');
670 if (options[i][1] == 1)
671 newOption.appendChild(document.createTextNode(newOption.value+' (1 graph)'));
672 else
673 newOption.appendChild(document.createTextNode(newOption.value+' ('+options[i][1]+' graphs)'));
674 select.appendChild(newOption);
675 }
676 return select.selectedIndex;
677 }
678 }
680 function GraphListCheckName(doalert) {
681 var lname = document.getElementById('GraphListName');
682 if (lname) {
683 if (lname.value.match(/^[a-zA-Z0-9_-]+$/)) {
684 lname.style.backgroundColor = '';
685 return lname.value;
686 } else {
687 lname.style.backgroundColor = '#ffdddd';
688 if (doalert && lname.value.length == 0)
689 alert('Graph list name is empty.\n\n'+
690 'Please fill in a name and try again.');
691 else if (doalert)
692 alert('Graph list name contains non-permitted character.\n\n'+
693 'Only anlphanumerical characters (a-z, A-Z, 0-9), hyphen (-) and underscore (_) are permitted.\n'+
694 'Please correct and try again.');
695 lname.focus();
696 }
697 }
698 return '';
699 }
701 function GraphSave() {
702 var lstName = GraphListCheckName(true);
703 if (lstName.length == 0)
704 return;
705 if (graphList.length > 0) {
706 // Save graph list to cookie
707 var str = '';
708 for (i = 0; i < graphList.length; i++) {
709 var g = graphList[i].indexOf(' ');
710 if (i > 0)
711 str += '/';
712 str += graphList[i].substring(g+1);
713 }
715 document.cookie = 'graphLst'+lstName+'='+str;
716 if (GraphListFromCookie(lstName).length == 0)
717 alert("Failed to save graph list '"+lstName+"' to cookie.");
718 else
719 alert("Successfully saved current graph list.");
720 } else {
721 document.cookie = 'graphLst'+lstName+'=; expires='+new Date().toGMTString();
722 alert("Cleared saved graph list.");
723 }
724 GraphListRefresh();
725 }
727 function GraphDrop() {
728 var cname = document.getElementById('GraphList');
729 if (cname && cname.selectedIndex >= 0) {
730 cname = cname.options[cname.selectedIndex].value;
731 document.cookie = 'graphLst'+cname+'=; expires='+new Date().toGMTString();
732 GraphListRefresh();
733 } else
734 return;
735 }
737 function GraphLoad() {
738 var cname = document.getElementById('GraphList');
739 if (cname && cname.selectedIndex >= 0)
740 cname = cname.options[cname.selectedIndex].value;
741 else
742 return;
743 // Load graph list from cookie
744 var grLst = GraphListFromCookie(cname);
745 var oldLength = graphList.length;
746 for (i = 0; i < grLst.length; i++) {
747 var host = '';
748 var plugin = '';
749 var pinst = '';
750 var type = '';
751 var tinst = '';
752 var timespan = '';
753 var logarithmic = false;
754 var tinyLegend = false;
755 var graph = grLst[i].split('&');
756 for (j = 0; j < graph.length; j++)
757 if (graph[j] == 'logarithmic=1')
758 logarithmic = true;
759 else if (graph[j] == 'tinylegend=1')
760 tinyLegend = true;
761 else if (graph[j].substring(0, 9) == 'timespan=')
762 timespan = decodeURIComponent(graph[j].substring(9));
763 graph = decodeURIComponent(graph[0]).split('/');
764 host = graph[0];
765 if (graph.length > 1) {
766 var g = graph[1].indexOf('-');
767 if (g >= 0) {
768 plugin = graph[1].substring(0, g);
769 pinst = graph[1].substring(g+1);
770 } else
771 plugin = graph[1];
772 }
773 if (graph.length > 2) {
774 var g = graph[2].indexOf('-');
775 if (g >= 0) {
776 type = graph[2].substring(0, g);
777 tinst = graph[2].substring(g+1);
778 } else
779 type = graph[2];
780 }
782 if (host && plugin && type)
783 GraphDoAppend(host, plugin, pinst, type, tinst, timespan, tinyLegend, logarithmic);
784 }
785 if (grLst.length == 0)
786 alert("No list '"+cname+"' found for loading.");
787 else if (grLst.length + oldLength != graphList.length)
788 alert("Could not load all graphs, probably damaged cookie.");
789 }