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 (keepSelection && optCnt == 1 && newOption.value == '@') {
115 newOption.setAttribute('style', 'font-style: italic');
116 newOption.appendChild(document.createTextNode('Meta graph'));
117 } else
118 newOption.appendChild(document.createTextNode(newOption.value));
119 select.appendChild(newOption);
120 }
121 return keepSelection ? select.selectedIndex : -1;
122 }
123 }
125 // Request refresh of host list
126 function ListRefreshHost() {
127 var query = 'action=list_hosts';
128 loadXMLDoc(dhtml_url, query);
129 }
131 // Handle update to host list
132 function ListOfHost(response) {
133 var select = document.getElementById('host_list');
134 var idx = refillSelect(response ? response.getElementsByTagName('option') : null, select);
135 if (idx > 0) {
136 ListRefreshPlugin();
137 } else
138 ListOfPlugin(null);
139 }
141 // Request refresh of plugin list
142 function ListRefreshPlugin() {
143 var host_list = document.getElementById('host_list');
144 var host = host_list.selectedIndex >= 0 ? host_list.options[host_list.selectedIndex].value : '/';
145 if (host != '/') {
146 var query = 'action=list_plugins&host='+encodeURIComponent(host);
147 loadXMLDoc(dhtml_url, query);
148 } else {
149 ListOfPlugin(null);
150 }
151 }
153 // Handle update to plugin list
154 function ListOfPlugin(response) {
155 var select = document.getElementById('plugin_list');
156 var idx = refillSelect(response ? response.getElementsByTagName('option') : null, select);
157 if (idx > 0) {
158 ListRefreshPluginInstance();
159 } else
160 ListOfPluginInstance(null);
161 }
163 // Request refresh of plugin instance list
164 function ListRefreshPluginInstance() {
165 var host_list = document.getElementById('host_list');
166 var host = host_list.selectedIndex >= 0 ? host_list.options[host_list.selectedIndex].value : '/';
167 var plugin_list = document.getElementById('plugin_list');
168 var plugin = plugin_list.selectedIndex >= 0 ? plugin_list.options[plugin_list.selectedIndex].value : '/';
169 if (host != '/' && plugin != '/') {
170 var query = 'action=list_pinsts&host='+encodeURIComponent(host)+'&plugin='+encodeURIComponent(plugin);
171 loadXMLDoc(dhtml_url, query);
172 } else {
173 ListOfPluginInstance(null);
174 }
175 }
177 // Handle update of plugin instance list
178 function ListOfPluginInstance(response) {
179 var select = document.getElementById('pinst_list');
180 var idx = refillSelect(response ? response.getElementsByTagName('option') : null, select);
181 if (idx > 0) {
182 ListRefreshType();
183 } else
184 ListOfType(null);
185 }
187 // Request refresh of type list
188 function ListRefreshType() {
189 var host_list = document.getElementById('host_list');
190 var host = host_list.selectedIndex >= 0 ? host_list.options[host_list.selectedIndex].value : '/';
191 var plugin_list = document.getElementById('plugin_list');
192 var plugin = plugin_list.selectedIndex >= 0 ? plugin_list.options[plugin_list.selectedIndex].value : '/';
193 var pinst_list = document.getElementById('pinst_list');
194 var pinst = pinst_list.selectedIndex >= 0 ? pinst_list.options[pinst_list.selectedIndex].value : '/';
195 if (host != '/' && plugin != '/' && pinst != '/') {
196 var query = 'action=list_types&host='+encodeURIComponent(host)+'&plugin='+encodeURIComponent(plugin)+'&plugin_instance='+encodeURIComponent(pinst);
197 loadXMLDoc(dhtml_url, query);
198 } else {
199 ListOfType(null);
200 }
201 }
203 // Handle update of type list
204 function ListOfType(response) {
205 var select = document.getElementById('type_list');
206 var idx = refillSelect(response ? response.getElementsByTagName('option') : null, select);
207 if (idx > 0) {
208 ListRefreshTypeInstance();
209 } else
210 ListOfTypeInstance(null);
211 }
213 // Request refresh of type instance list
214 function ListRefreshTypeInstance() {
215 var host_list = document.getElementById('host_list');
216 var host = host_list.selectedIndex >= 0 ? host_list.options[host_list.selectedIndex].value : '/';
217 var plugin_list = document.getElementById('plugin_list');
218 var plugin = plugin_list.selectedIndex >= 0 ? plugin_list.options[plugin_list.selectedIndex].value : '/';
219 var pinst_list = document.getElementById('pinst_list');
220 var pinst = pinst_list.selectedIndex >= 0 ? pinst_list.options[pinst_list.selectedIndex].value : '/';
221 var type_list = document.getElementById('type_list');
222 var type = type_list.selectedIndex >= 0 ? type_list.options[type_list.selectedIndex].value : '/';
223 if (host != '/' && plugin != '/' && pinst != '/' && type != '/') {
224 var query = 'action=list_tinsts&host='+encodeURIComponent(host)+'&plugin='+encodeURIComponent(plugin)+'&plugin_instance='+encodeURIComponent(pinst)+'&type='+encodeURIComponent(type);
225 loadXMLDoc(dhtml_url, query);
226 } else {
227 ListOfTypeInstance(null);
228 }
229 }
231 // Handle update of type instance list
232 function ListOfTypeInstance(response) {
233 var select = document.getElementById('tinst_list');
234 var idx = refillSelect(response ? response.getElementsByTagName('option') : null, select);
235 if (idx > 0) {
236 // Enable add button
237 RefreshButtons();
238 } else {
239 // Disable add button
240 RefreshButtons();
241 }
242 }
244 function RefreshButtons() {
245 var host_list = document.getElementById('host_list');
246 var host = host_list.selectedIndex >= 0 ? host_list.options[host_list.selectedIndex].value : '/';
247 var plugin_list = document.getElementById('plugin_list');
248 var plugin = plugin_list.selectedIndex >= 0 ? plugin_list.options[plugin_list.selectedIndex].value : '/';
249 var pinst_list = document.getElementById('pinst_list');
250 var pinst = pinst_list.selectedIndex >= 0 ? pinst_list.options[pinst_list.selectedIndex].value : '/';
251 var type_list = document.getElementById('type_list');
252 var type = type_list.selectedIndex >= 0 ? type_list.options[type_list.selectedIndex].value : '/';
253 var tinst_list = document.getElementById('tinst_list');
254 var tinst = tinst_list.selectedIndex >= 0 ? tinst_list.options[tinst_list.selectedIndex].value : '/';
255 if (host != '/' && plugin != '/' && pinst != '/' && type != '/' && tinst != '/') {
256 document.getElementById('btnAdd').removeAttribute('disabled');
257 } else {
258 document.getElementById('btnAdd').setAttribute('disabled', 'disabled');
259 }
261 var graphs = document.getElementById('graphs');
262 if (graphs.getElementsByTagName('div').length > 1) {
263 document.getElementById('btnClear').removeAttribute('disabled');
264 document.getElementById('btnRefresh').removeAttribute('disabled');
265 } else {
266 document.getElementById('btnClear').setAttribute('disabled', 'disabled');
267 document.getElementById('btnRefresh').setAttribute('disabled', 'disabled');
268 }
269 }
271 var nextGraphId = 1;
272 var graphList = new Array();
274 function GraphAppend() {
275 var host_list = document.getElementById('host_list');
276 var host = host_list.selectedIndex >= 0 ? host_list.options[host_list.selectedIndex].value : '/';
277 var plugin_list = document.getElementById('plugin_list');
278 var plugin = plugin_list.selectedIndex >= 0 ? plugin_list.options[plugin_list.selectedIndex].value : '/';
279 var pinst_list = document.getElementById('pinst_list');
280 var pinst = pinst_list.selectedIndex >= 0 ? pinst_list.options[pinst_list.selectedIndex].value : '/';
281 var type_list = document.getElementById('type_list');
282 var type = type_list.selectedIndex >= 0 ? type_list.options[type_list.selectedIndex].value : '/';
283 var tinst_list = document.getElementById('tinst_list');
284 var tinst = tinst_list.selectedIndex >= 0 ? tinst_list.options[tinst_list.selectedIndex].value : '/';
285 var time_list = document.getElementById('timespan');
286 var timespan = time_list.selectedIndex >= 0 ? time_list.options[time_list.selectedIndex].value : '';
287 var tinyLegend = document.getElementById('tinylegend').checked;
288 var logarithmic = document.getElementById('logarithmic').checked
289 GraphDoAppend(host, plugin, pinst, type, tinst, timespan, tinyLegend, logarithmic);
290 }
292 function GraphDoAppend(host, plugin, pinst, type, tinst, timespan, tinyLegend, logarithmic) {
293 var graphs = document.getElementById('graphs');
295 if (host != '/' && plugin != '/' && pinst != '/' && type != '/') {
296 var graph_id = 'graph_'+nextGraphId++;
297 var graph_src = graph_url+'?host='+encodeURIComponent(host)+'&plugin='+encodeURIComponent(plugin)+'&plugin_instance='+encodeURIComponent(pinst)+'&type='+encodeURIComponent(type);
298 var graph_alt = '';
299 var grap_title = '';
300 if (tinst == '@') {
301 graph_alt = host+'/'+plugin+(pinst.length > 0 ? '-'+pinst : '')+'/'+type;
302 graph_title = type+' of '+plugin+(pinst.length > 0 ? '-'+pinst : '')+' plugin for '+host;
303 } else {
304 graph_alt = host+'/'+plugin+(pinst.length > 0 ? '-'+pinst : '')+'/'+type+(tinst.length > 0 ? '-'+tinst : '');
305 graph_title = type+(tinst.length > 0 ? '-'+tinst : '')+' of '+plugin+(pinst.length > 0 ? '-'+pinst : '')+' plugin for '+host;
306 graph_src += '&type_instance='+encodeURIComponent(tinst);
307 }
308 if (logarithmic)
309 graph_src += '&logarithmic=1';
310 if (tinyLegend)
311 graph_src += '&tinylegend=1';
312 if (timespan)
313 graph_src += '×pan='+encodeURIComponent(timespan);
314 var now = new Date();
315 graph_src += '&ts='+now.getTime();
316 graphList.push(graph_id+' '+encodeURIComponent(graph_alt)+(logarithmic ? '&logarithmic=1' : '')+(tinyLegend ? '&tinylegend=1' : '')+'×pan='+encodeURIComponent(timespan));
318 // Graph container
319 newGraph = document.createElement('div');
320 newGraph.setAttribute('class', 'graph');
321 newGraph.setAttribute('id', graph_id);
322 // Graph cell + graph
323 newImg = document.createElement('img');
324 newImg.setAttribute('src', graph_src);
325 newImg.setAttribute('alt', graph_alt);
326 newImg.setAttribute('title', graph_title);
327 newImg.setAttribute('onclick', 'GraphToggleTools("'+graph_id+'")');
328 newGraph.appendChild(newImg);
329 graphs.appendChild(newGraph);
330 }
331 document.getElementById('nograph').style.display = 'none';
332 RefreshButtons();
333 }
335 function GraphDropAll() {
336 var graphs = document.getElementById('graphs');
337 var childCnt = graphs.childNodes.length;
338 while (childCnt > 0)
339 if (graphs.childNodes[--childCnt].id != 'nograph' && (graphs.childNodes[childCnt].nodeName == 'div' || graphs.childNodes[childCnt].nodeName == 'DIV'))
340 graphs.removeChild(graphs.childNodes[childCnt]);
341 else if (graphs.childNodes[childCnt].id == 'nograph')
342 graphs.childNodes[childCnt].style.display = 'block';
343 graphList = new Array();
344 RefreshButtons();
345 }
347 function GraphToggleTools(graph) {
348 var graphId = document.getElementById('ge_graphid').value;
349 var ref_img = null;
350 if (graphId == graph || graph == '') {
351 ref_img = null;
352 } else {
353 var graphDiv = document.getElementById(graph);
354 var imgs = graphDiv ? graphDiv.getElementsByTagName('img') : null;
355 var imgCnt = imgs ? imgs.length : 0;
356 while (imgCnt > 0)
357 if (imgs[--imgCnt].parentNode.getAttribute('class') == 'graph')
358 ref_img = imgs[imgCnt];
359 }
360 if (ref_img) {
361 var ts_sel = document.getElementById('ge_timespan');
362 var src_url = ref_img.src;
363 var ge = document.getElementById('ge');
364 // Fix field values
365 var ts = src_url.match(/×pan=[^&]*/);
366 ts = ts ? ts[0].substr(10) : '';
367 document.getElementById('ge_graphid').value = graph;
368 document.getElementById('ge_tinylegend').checked = src_url.match(/&tinylegend=1/);
369 document.getElementById('ge_logarithmic').checked = src_url.match(/&logarithmic=1/);
370 for (i = 0; i < ts_sel.options.length; i++)
371 if (ts_sel.options[i].value == ts) {
372 ts_sel.selectedIndex = i;
373 break;
374 }
375 // show tools box and position it properly
376 ge.style.display = 'table';
377 GraphPositionToolbox(ref_img);
378 } else {
379 // hide tools box
380 document.getElementById('ge').style.display = 'none';
381 document.getElementById('ge_graphid').value = '';
382 }
383 }
385 function GraphPositionToolbox(ref_img) {
386 var ge = document.getElementById('ge');
387 if (ge.style.display != 'none') {
388 var wl = 0; var wt = 0;
389 var x = ref_img;
390 if (ref_img == null) {
391 var graphDiv = document.getElementById(document.getElementById('ge_graphid').value);
392 var imgs = graphDiv ? graphDiv.getElementsByTagName('img') : null;
393 var imgCnt = imgs ? imgs.length : 0;
394 while (imgCnt > 0)
395 if (imgs[--imgCnt].parentNode.getAttribute('class') == 'graph')
396 ref_img = imgs[imgCnt];
398 if (ref_img == null) {
399 document.getElementById('ge_graphid').value = '';
400 ge.style.display = 'none';
401 return;
402 } else
403 x = ref_img;
404 }
405 while (x != null) {
406 wl += x.offsetLeft;
407 wt += x.offsetTop;
408 x = x.offsetParent;
409 }
410 ge.style.left = (wl + (ref_img.offsetWidth - ge.offsetWidth) / 2)+'px';
411 ge.style.top = (wt + (ref_img.offsetHeight - ge.offsetHeight) / 2)+'px';
412 }
413 }
415 function GraphRefreshAll() {
416 var imgs = document.getElementById('graphs').getElementsByTagName('img');
417 var imgCnt = imgs.length;
418 var now = new Date();
419 var newTS = '&ts='+now.getTime();
420 while (imgCnt > 0)
421 if (imgs[--imgCnt].parentNode.getAttribute('class') == 'graph') {
422 var oldSrc = imgs[imgCnt].src;
423 var newSrc = oldSrc.replace(/&ts=[0-9]+/, newTS);
424 if (newSrc == oldSrc)
425 newSrc = newSrc + newTS;
426 imgs[imgCnt].setAttribute('src', newSrc);
427 }
428 }
430 function GraphRefresh(graph) {
431 var graphElement = null;
432 if (graph == null) {
433 var graphId = document.getElementById('ge_graphid').value;
434 if (graphId != '')
435 graphElement = document.getElementById(graphId);
436 } else
437 graphElement = document.getElementById(graph);
438 if (graphElement != null) {
439 var imgs = graphElement.getElementsByTagName('img');
440 var imgCnt = imgs.length;
441 while (imgCnt > 0)
442 if (imgs[--imgCnt].parentNode.getAttribute('class') == 'graph') {
443 var now = new Date();
444 var newTS = '&ts='+now.getTime();
445 var oldSrc = imgs[imgCnt].src;
446 var newSrc = oldSrc.replace(/&ts=[0-9]+/, newTS);
447 if (newSrc == oldSrc)
448 newSrc = newSrc+newTS;
449 imgs[imgCnt].setAttribute('src', newSrc);
450 break;
451 }
452 }
453 }
455 function GraphAdjust(graph) {
456 var graphId = graph == null ? document.getElementById('ge_graphid').value : graph;
457 var graphElement = document.getElementById(graphId);
458 if (graphElement != null) {
459 var time_list = document.getElementById('ge_timespan');
460 var timespan = time_list.selectedIndex >= 0 ? time_list.options[time_list.selectedIndex].value : '';
461 var tinyLegend = document.getElementById('ge_tinylegend').checked;
462 var logarithmic = document.getElementById('ge_logarithmic').checked
463 var imgs = graphElement.getElementsByTagName('img');
464 var imgCnt = imgs.length;
465 var ref_img = null;
466 while (imgCnt > 0)
467 if (imgs[--imgCnt].parentNode.getAttribute('class') == 'graph') {
468 var now = new Date();
469 var newTS = '&ts='+now.getTime();
470 var oldSrc = imgs[imgCnt].src;
471 var newSrc = oldSrc.replace(/&ts=[^&]*/, newTS);
472 if (newSrc == oldSrc)
473 newSrc = newSrc+newTS;
474 newSrc = newSrc.replace(/&logarithmic=[^&]*/, '');
475 if (logarithmic)
476 newSrc += '&logarithmic=1';
477 newSrc = newSrc.replace(/&tinylegend=[^&]*/, '');
478 if (tinyLegend)
479 newSrc += '&tinylegend=1';
480 newSrc = newSrc.replace(/×pan=[^&]*/, '');
481 if (timespan)
482 newSrc += '×pan='+encodeURIComponent(timespan);
483 imgs[imgCnt].setAttribute('src', newSrc);
485 var myList = Array();
486 for (i = 0; i < graphList.length; i++)
487 if (graphList[i].substring(0, graphId.length) == graphId && graphList[i].charAt(graphId.length) == ' ') {
488 newSrc = graphList[i];
489 newSrc = newSrc.replace(/&logarithmic=[^&]*/, '');
490 newSrc = newSrc.replace(/&tinylegend=[^&]*/, '');
491 newSrc = newSrc.replace(/×pan=[^&]*/, '');
492 newSrc = newSrc+(logarithmic ? '&logarithmic=1' : '')+(tinyLegend ? '&tinylegend=1' : '')+'×pan='+encodeURIComponent(timespan);
493 myList.push(newSrc);
494 continue;
495 } else
496 myList.push(graphList[i]);
497 graphList = myList;
498 window.setTimeout("GraphPositionToolbox(null)", 10);
499 // GraphPositionToolbox(imgs[imgCnt]);
500 break;
501 }
502 }
503 }
505 function GraphRemove(graph) {
506 var graphs = document.getElementById('graphs');
507 var graphId = graph == null ? document.getElementById('ge_graphid').value : graph;
508 var graphElement = document.getElementById(graphId);
509 if (graphElement) {
510 GraphToggleTools('');
511 graphs.removeChild(graphElement);
512 RefreshButtons();
513 if (graphs.getElementsByTagName('div').length == 1)
514 document.getElementById('nograph').style.display = 'block';
516 var myList = Array();
517 for (i = 0; i < graphList.length; i++)
518 if (graphList[i].substring(0, graphId.length) == graphId && graphList[i].charAt(graphId.length) == ' ')
519 continue;
520 else
521 myList.push(graphList[i]);
522 graphList = myList;
523 }
524 }
526 function GraphMoveUp(graph) {
527 var graphs = document.getElementById('graphs');
528 var graphId = graph == null ? document.getElementById('ge_graphid').value : graph;
529 var childCnt = graphs.childNodes.length;
530 var prevGraph = null;
531 for (i = 0; i < childCnt; i++)
532 if (graphs.childNodes[i].nodeName == 'div' || graphs.childNodes[i].nodeName == 'DIV') {
533 if (graphs.childNodes[i].id == 'nograph') {
534 // Skip
535 } else if (graphs.childNodes[i].id == graphId) {
536 var myGraph = graphs.childNodes[i];
537 if (prevGraph) {
538 graphs.removeChild(myGraph);
539 graphs.insertBefore(myGraph, prevGraph);
540 }
541 break;
542 } else
543 prevGraph = graphs.childNodes[i];
544 }
545 for (i = 0; i < graphList.length; i++)
546 if (graphList[i].substring(0, graphId.length) == graphId && graphList[i].charAt(graphId.length) == ' ') {
547 if (i > 0) {
548 var tmp = graphList[i-1];
549 graphList[i-1] = graphList[i];
550 graphList[i] = tmp;
551 }
552 break;
553 }
554 GraphPositionToolbox(null);
555 }
557 function GraphMoveDown(graph) {
558 var graphs = document.getElementById('graphs');
559 var graphId = graph == null ? document.getElementById('ge_graphid').value : graph;
560 var childCnt = graphs.childNodes.length;
561 var nextGraph = null;
562 var myGraph = null;
563 for (i = 0; i < childCnt; i++)
564 if (graphs.childNodes[i].nodeName == 'div' || graphs.childNodes[i].nodeName == 'DIV') {
565 if (graphs.childNodes[i].id == 'nograph') {
566 // Skip
567 } else if (graphs.childNodes[i].id == graphId) {
568 myGraph = graphs.childNodes[i];
569 } else if (myGraph) {
570 nextGraph = graphs.childNodes[i];
571 graphs.removeChild(nextGraph);
572 graphs.insertBefore(nextGraph, myGraph);
573 break;
574 }
575 }
576 for (i = 0; i < graphList.length; i++)
577 if (graphList[i].substring(0, graphId.length) == graphId && graphList[i].charAt(graphId.length) == ' ') {
578 if (i+1 < graphList.length) {
579 var tmp = graphList[i+1];
580 graphList[i+1] = graphList[i];
581 graphList[i] = tmp;
582 }
583 break;
584 }
585 GraphPositionToolbox(null);
586 }
588 function GraphListFromCookie(lname) {
589 if (document.cookie.length > 0) {
590 var cname= 'graphLst'+lname+'=';
591 var cookies = document.cookie.split('; ');
592 for (i = 0; i < cookies.length; i++)
593 if (cookies[i].substring(0, cname.length) == cname)
594 return cookies[i].substring(cname.length).split('/');
595 }
596 return new Array();
597 }
599 function GraphListNameSort(a, b) {
600 if (a[0] > b[0])
601 return 1
602 else if (a[0] < b[0])
603 return -1;
604 else
605 return 0;
606 }
608 function GraphListRefresh() {
609 var select = document.getElementById('GraphList');
610 var childCnt = select.childNodes.length;
611 var oldValue = select.selectedIndex > 0 ? select.options[select.selectedIndex].value : '/';
612 while (childCnt > 0)
613 select.removeChild(select.childNodes[--childCnt]);
615 // Determine available names
616 var options = new Array();
617 if (document.cookie.length > 0) {
618 var cookies = document.cookie.split('; ');
619 for (i = 0; i < cookies.length; i++)
620 if (cookies[i].substring(0, 8) == 'graphLst') {
621 var p = cookies[i].indexOf('=');
622 if (p < 0)
623 continue;
624 options.push(new Array(cookies[i].substring(8, p), cookies[i].substring(p+1).split('/').length));
625 }
626 }
627 options.sort(GraphListNameSort);
629 var optCnt = options ? options.length : 0;
630 if (optCnt == 0) {
631 select.setAttribute('disabled', 'disabled');
632 return -1;
633 } else {
634 select.removeAttribute('disabled');
635 for (i = 0; i < optCnt; i++) {
636 newOption = document.createElement("option");
637 newOption.value = options[i][0];
638 if (newOption.value == oldValue)
639 newOption.setAttribute('selected', 'selected');
640 if (options[i][1] == 1)
641 newOption.appendChild(document.createTextNode(newOption.value+' (1 graph)'));
642 else
643 newOption.appendChild(document.createTextNode(newOption.value+' ('+options[i][1]+' graphs)'));
644 select.appendChild(newOption);
645 }
646 return select.selectedIndex;
647 }
648 }
650 function GraphListCheckName(doalert) {
651 var lname = document.getElementById('GraphListName');
652 if (lname) {
653 if (lname.value.match(/^[a-zA-Z0-9_-]+$/)) {
654 lname.style.backgroundColor = '';
655 return lname.value;
656 } else {
657 lname.style.backgroundColor = '#ffdddd';
658 if (doalert && lname.value.length == 0)
659 alert('Graph list name is empty.\n\n'+
660 'Please fill in a name and try again.');
661 else if (doalert)
662 alert('Graph list name contains non-permitted character.\n\n'+
663 'Only anlphanumerical characters (a-z, A-Z, 0-9), hyphen (-) and underscore (_) are permitted.\n'+
664 'Please correct and try again.');
665 lname.focus();
666 }
667 }
668 return '';
669 }
671 function GraphSave() {
672 var lstName = GraphListCheckName(true);
673 if (lstName.length == 0)
674 return;
675 if (graphList.length > 0) {
676 // Save graph list to cookie
677 var str = '';
678 for (i = 0; i < graphList.length; i++) {
679 var g = graphList[i].indexOf(' ');
680 if (i > 0)
681 str += '/';
682 str += graphList[i].substring(g+1);
683 }
685 document.cookie = 'graphLst'+lstName+'='+str;
686 if (GraphListFromCookie(lstName).length == 0)
687 alert("Failed to save graph list '"+lstName+"' to cookie.");
688 else
689 alert("Successfully saved current graph list.");
690 } else {
691 document.cookie = 'graphLst'+lstName+'=; expires='+new Date().toGMTString();
692 alert("Cleared saved graph list.");
693 }
694 GraphListRefresh();
695 }
697 function GraphDrop() {
698 var cname = document.getElementById('GraphList');
699 if (cname && cname.selectedIndex >= 0) {
700 cname = cname.options[cname.selectedIndex].value;
701 document.cookie = 'graphLst'+cname+'=; expires='+new Date().toGMTString();
702 GraphListRefresh();
703 } else
704 return;
705 }
707 function GraphLoad() {
708 var cname = document.getElementById('GraphList');
709 if (cname && cname.selectedIndex >= 0)
710 cname = cname.options[cname.selectedIndex].value;
711 else
712 return;
713 // Load graph list from cookie
714 var grLst = GraphListFromCookie(cname);
715 var oldLength = graphList.length;
716 for (i = 0; i < grLst.length; i++) {
717 var host = '';
718 var plugin = '';
719 var pinst = '';
720 var type = '';
721 var tinst = '';
722 var timespan = '';
723 var logarithmic = false;
724 var tinyLegend = false;
725 var graph = grLst[i].split('&');
726 for (j = 0; j < graph.length; j++)
727 if (graph[j] == 'logarithmic=1')
728 logarithmic = true;
729 else if (graph[j] == 'tinylegend=1')
730 tinyLegend = true;
731 else if (graph[j].substring(0, 9) == 'timespan=')
732 timespan = decodeURIComponent(graph[j].substring(9));
733 graph = decodeURIComponent(graph[0]).split('/');
734 host = graph[0];
735 if (graph.length > 1) {
736 var g = graph[1].indexOf('-');
737 if (g >= 0) {
738 plugin = graph[1].substring(0, g);
739 pinst = graph[1].substring(g+1);
740 } else
741 plugin = graph[1];
742 }
743 if (graph.length > 2) {
744 var g = graph[2].indexOf('-');
745 if (g >= 0) {
746 type = graph[2].substring(0, g);
747 tinst = graph[2].substring(g+1);
748 } else
749 type = graph[2];
750 }
752 if (host && plugin && type)
753 GraphDoAppend(host, plugin, pinst, type, tinst, timespan, tinyLegend, logarithmic);
754 }
755 if (grLst.length == 0)
756 alert("No list '"+cname+"' found for loading.");
757 else if (grLst.length + oldLength != graphList.length)
758 alert("Could not load all graphs, probably damaged cookie.");
759 }