2 * Copyright (C) 2009 Bruno Prémont <bonbons AT linux-vserver.org>
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.
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
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.
18 // Toggle visibility of a div
19 function toggleDiv(divID) {
20 var div = document.getElementById(divID);
21 var label = document.getElementById(divID+'_sw');
24 if (div.style.display == 'none') {
25 div.style.display = 'block';
28 div.style.display = 'none';
32 if (label_txt && label) {
33 var childCnt = label.childNodes.length;
35 label.removeChild(label.childNodes[--childCnt]);
36 label.appendChild(document.createTextNode(label_txt));
38 GraphPositionToolbox(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');
51 } else if (window.ActiveXObject) {
52 req = new ActiveXObject("Microsoft.XMLHTTP");
54 req.onreadystatechange = processReqChange;
55 req.open('POST', url, true);
56 req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
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];
70 eval(method + '(result)');
75 // Update contents of a <select> drop-down list
76 function refillSelect(options, select) {
80 var childCnt = select.childNodes.length;
81 var oldValue = select.selectedIndex > 0 ? select.options[select.selectedIndex].value : '/';
83 select.removeChild(select.childNodes[--childCnt]);
85 var optCnt = options ? options.length : 0;
87 select.setAttribute('disabled', 'disabled');
90 select.removeAttribute('disabled');
91 var keepSelection = false;
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 : ''))
100 newOption = document.createElement("option");
101 newOption.value = '/';
103 newOption.setAttribute('disabled', 'disabled');
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'));
129 newOption.appendChild(document.createTextNode(newOption.value));
131 newOption.appendChild(document.createTextNode(newOption.value));
132 select.appendChild(newOption);
134 return keepSelection ? select.selectedIndex : -1;
138 // Request refresh of host list
139 function ListRefreshHost() {
140 var query = 'action=list_hosts';
141 loadXMLDoc(dhtml_url, query);
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);
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 : '/';
159 var query = 'action=list_plugins&host='+encodeURIComponent(host);
160 loadXMLDoc(dhtml_url, query);
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);
171 ListRefreshPluginInstance();
173 ListOfPluginInstance(null);
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);
186 ListOfPluginInstance(null);
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);
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);
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);
221 ListRefreshTypeInstance();
223 ListOfTypeInstance(null);
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);
240 ListOfTypeInstance(null);
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);
252 // Disable add button
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');
271 document.getElementById('btnAdd').setAttribute('disabled', 'disabled');
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');
279 document.getElementById('btnClear').setAttribute('disabled', 'disabled');
280 document.getElementById('btnRefresh').setAttribute('disabled', 'disabled');
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);
308 GraphDoAppend(host, plugin, pinst, type, tinst, timespan, tinyLegend, logarithmic);
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');
319 alert('No graph found for adding');
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);
331 graph_alt = host+'/'+plugin+(pinst.length > 0 ? '-'+pinst : '')+'/'+type;
332 graph_title = type+' of '+plugin+(pinst.length > 0 ? '-'+pinst : '')+' plugin for '+host;
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);
339 graph_src += '&logarithmic=1';
341 graph_src += '&tinylegend=1';
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));
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);
361 document.getElementById('nograph').style.display = 'none';
365 function GraphDropAll() {
366 var graphs = document.getElementById('graphs');
367 var childCnt = graphs.childNodes.length;
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();
377 function GraphToggleTools(graph) {
378 var graphId = document.getElementById('ge_graphid').value;
380 if (graphId == graph || graph == '') {
383 var graphDiv = document.getElementById(graph);
384 var imgs = graphDiv ? graphDiv.getElementsByTagName('img') : null;
385 var imgCnt = imgs ? imgs.length : 0;
387 if (imgs[--imgCnt].parentNode.getAttribute('class') == 'graph')
388 ref_img = imgs[imgCnt];
391 var ts_sel = document.getElementById('ge_timespan');
392 var src_url = ref_img.src;
393 var ge = document.getElementById('ge');
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;
405 // show tools box and position it properly
406 ge.style.display = 'table';
407 GraphPositionToolbox(ref_img);
410 document.getElementById('ge').style.display = 'none';
411 document.getElementById('ge_graphid').value = '';
415 function GraphPositionToolbox(ref_img) {
416 var ge = document.getElementById('ge');
417 if (ge.style.display != 'none') {
418 var wl = 0; var wt = 0;
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;
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';
440 ge.style.left = (wl + (ref_img.offsetWidth - ge.offsetWidth) / 2)+'px';
441 ge.style.top = (wt + (ref_img.offsetHeight - ge.offsetHeight) / 2)+'px';
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();
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);
460 function GraphRefresh(graph) {
461 var graphElement = null;
463 var graphId = document.getElementById('ge_graphid').value;
465 graphElement = document.getElementById(graphId);
467 graphElement = document.getElementById(graph);
468 if (graphElement != null) {
469 var imgs = graphElement.getElementsByTagName('img');
470 var imgCnt = imgs.length;
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);
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;
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=[^&]*/, '');
506 newSrc += '&logarithmic=1';
507 newSrc = newSrc.replace(/&tinylegend=[^&]*/, '');
509 newSrc += '&tinylegend=1';
510 newSrc = newSrc.replace(/×pan=[^&]*/, '');
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);
526 myList.push(graphList[i]);
528 window.setTimeout("GraphPositionToolbox(null)", 10);
529 // GraphPositionToolbox(imgs[imgCnt]);
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);
540 GraphToggleTools('');
541 graphs.removeChild(graphElement);
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) == ' ')
551 myList.push(graphList[i]);
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') {
565 } else if (graphs.childNodes[i].id == graphId) {
566 var myGraph = graphs.childNodes[i];
568 graphs.removeChild(myGraph);
569 graphs.insertBefore(myGraph, prevGraph);
573 prevGraph = graphs.childNodes[i];
575 for (i = 0; i < graphList.length; i++)
576 if (graphList[i].substring(0, graphId.length) == graphId && graphList[i].charAt(graphId.length) == ' ') {
578 var tmp = graphList[i-1];
579 graphList[i-1] = graphList[i];
584 GraphPositionToolbox(null);
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;
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') {
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);
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];
615 GraphPositionToolbox(null);
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('/');
629 function GraphListNameSort(a, b) {
632 else if (a[0] < b[0])
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 : '/';
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('=');
654 options.push(new Array(cookies[i].substring(8, p), cookies[i].substring(p+1).split('/').length));
657 options.sort(GraphListNameSort);
659 var optCnt = options ? options.length : 0;
661 select.setAttribute('disabled', 'disabled');
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)'));
673 newOption.appendChild(document.createTextNode(newOption.value+' ('+options[i][1]+' graphs)'));
674 select.appendChild(newOption);
676 return select.selectedIndex;
680 function GraphListCheckName(doalert) {
681 var lname = document.getElementById('GraphListName');
683 if (lname.value.match(/^[a-zA-Z0-9_-]+$/)) {
684 lname.style.backgroundColor = '';
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.');
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.');
701 function GraphSave() {
702 var lstName = GraphListCheckName(true);
703 if (lstName.length == 0)
705 if (graphList.length > 0) {
706 // Save graph list to cookie
708 for (i = 0; i < graphList.length; i++) {
709 var g = graphList[i].indexOf(' ');
712 str += graphList[i].substring(g+1);
715 document.cookie = 'graphLst'+lstName+'='+str;
716 if (GraphListFromCookie(lstName).length == 0)
717 alert("Failed to save graph list '"+lstName+"' to cookie.");
719 alert("Successfully saved current graph list.");
721 document.cookie = 'graphLst'+lstName+'=; expires='+new Date().toGMTString();
722 alert("Cleared saved graph list.");
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();
737 function GraphLoad() {
738 var cname = document.getElementById('GraphList');
739 if (cname && cname.selectedIndex >= 0)
740 cname = cname.options[cname.selectedIndex].value;
743 // Load graph list from cookie
744 var grLst = GraphListFromCookie(cname);
745 var oldLength = graphList.length;
746 for (i = 0; i < grLst.length; i++) {
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')
759 else if (graph[j] == 'tinylegend=1')
761 else if (graph[j].substring(0, 9) == 'timespan=')
762 timespan = decodeURIComponent(graph[j].substring(9));
763 graph = decodeURIComponent(graph[0]).split('/');
765 if (graph.length > 1) {
766 var g = graph[1].indexOf('-');
768 plugin = graph[1].substring(0, g);
769 pinst = graph[1].substring(g+1);
773 if (graph.length > 2) {
774 var g = graph[2].indexOf('-');
776 type = graph[2].substring(0, g);
777 tinst = graph[2].substring(g+1);
782 if (host && plugin && type)
783 GraphDoAppend(host, plugin, pinst, type, tinst, timespan, tinyLegend, logarithmic);
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.");