diff options
Diffstat (limited to '')
-rw-r--r-- | js/RrdCmdLine.js | 513 |
1 files changed, 513 insertions, 0 deletions
diff --git a/js/RrdCmdLine.js b/js/RrdCmdLine.js new file mode 100644 index 0000000..fea0753 --- /dev/null +++ b/js/RrdCmdLine.js | |||
@@ -0,0 +1,513 @@ | |||
1 | /** | ||
2 | * | ||
3 | * This program is free software; you can redistribute it and/or modify it | ||
4 | * under the terms of the GNU General Public License as published by the Free | ||
5 | * Software Foundation; either version 2 of the License, or (at your option) | ||
6 | * any later version. | ||
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 | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | |||
13 | * You should have received a copy of the GNU General Public License along | ||
14 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
15 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA | ||
16 | |||
17 | * | ||
18 | * Manuel Sanmartin <manuel.luis at gmail.com> | ||
19 | **/ | ||
20 | |||
21 | "use strict"; | ||
22 | |||
23 | /** | ||
24 | * RrdCmdLine | ||
25 | * @constructor | ||
26 | */ | ||
27 | var RrdCmdLine = function() { | ||
28 | // if (arguments.lenght === 3) // XXX | ||
29 | this.init.apply(this, arguments); | ||
30 | }; | ||
31 | |||
32 | RrdCmdLine.prototype = { | ||
33 | graph: null, | ||
34 | |||
35 | init: function (gfx, fetch, line) | ||
36 | { | ||
37 | this.graph = new RrdGraph(gfx, fetch); | ||
38 | this.cmdline(line); | ||
39 | }, | ||
40 | cmdline: function(line) // FIXME | ||
41 | { | ||
42 | var i = 0; | ||
43 | line = line.replace(/\n/g," "); | ||
44 | var lines = line.match(/[^" ]+|"[^"]+"/g); | ||
45 | var len = lines.length; | ||
46 | |||
47 | while (i < len) { | ||
48 | var arg = lines[i]; | ||
49 | if (arg.charAt(0) === '"' && arg.charAt(arg.length-1) === '"') | ||
50 | arg = arg.substr(1,arg.length-2); | ||
51 | if (/^LINE[0-9.]+:/.test(arg)) { | ||
52 | this.parse_line(arg); | ||
53 | } else if (/^AREA:/.test(arg)) { | ||
54 | this.parse_area(arg); | ||
55 | } else if (/^DEF:/.test(arg)) { | ||
56 | this.parse_def(arg); | ||
57 | } else if (/^CDEF:/.test(arg)) { | ||
58 | this.parse_cdef(arg); | ||
59 | } else if (/^VDEF:/.test(arg)) { | ||
60 | this.parse_vdef(arg); | ||
61 | } else if (/^GPRINT:/.test(arg)) { | ||
62 | this.parse_gprint(arg); | ||
63 | } else if (/^COMMENT:/.test(arg)) { | ||
64 | this.parse_comment(arg); | ||
65 | } else if (/^VRULE:/.test(arg)) { | ||
66 | this.parse_vrule(arg); | ||
67 | } else if (/^HRULE:/.test(arg)) { | ||
68 | this.parse_hrule(arg); | ||
69 | } else if (/^TICK:/.test(arg)) { | ||
70 | this.parse_tick(arg); | ||
71 | } else if (/^TEXTALIGN:/.test(arg)) { | ||
72 | this.parse_textaling(arg); | ||
73 | } else if (/^SHIFT:/.test(arg)) { | ||
74 | this.parse_shift(arg); | ||
75 | } else if (arg.charAt(0) === '-') { | ||
76 | var strip = 1; | ||
77 | if (arg.length > 1 && arg.charAt(1) === '-') { | ||
78 | strip = 2; | ||
79 | } | ||
80 | var option = arg.substr(strip); | ||
81 | var value = undefined; | ||
82 | |||
83 | if (option.indexOf('=') !== -1) { | ||
84 | var index = option.indexOf('='); | ||
85 | value = option.substr(index+1); | ||
86 | option = option.substr(0,index); | ||
87 | } else if (i+1 < len) { | ||
88 | if (lines[i+1].charAt(0) !== '-' && | ||
89 | !/^"?LINE[0-9.]+:/.test(lines[i+1]) && | ||
90 | !/^"?AREA:/.test(lines[i+1]) && | ||
91 | !/^"?DEF:/.test(lines[i+1]) && | ||
92 | !/^"?CDEF:/.test(lines[i+1]) && | ||
93 | !/^"?VDEF:/.test(lines[i+1]) && | ||
94 | !/^"?GPRINT:/.test(lines[i+1]) && | ||
95 | !/^"?COMMENT:/.test(lines[i+1]) && | ||
96 | !/^"?HRULE:/.test(lines[i+1]) && | ||
97 | !/^"?VRULE:/.test(lines[i+1]) && | ||
98 | !/^"?TICK:/.test(lines[i+1]) && | ||
99 | !/^"?TEXTALING:/.test(lines[i+1]) && | ||
100 | !/^"?SHIFT:/.test(lines[i+1]) | ||
101 | ) { | ||
102 | i++; | ||
103 | if (lines[i].charAt(0) === '"' && lines[i].charAt(lines[i].length-1) === '"') | ||
104 | value = lines[i].substr(1,lines[i].length-2); | ||
105 | else | ||
106 | value = lines[i]; | ||
107 | } | ||
108 | } | ||
109 | this.set_option(option, value); | ||
110 | } else { | ||
111 | throw "Unknow argument: "+arg; | ||
112 | } | ||
113 | i++; | ||
114 | } | ||
115 | var start_end = RrdTime.proc_start_end(this.graph.start_t, this.graph.end_t); // FIXME here? | ||
116 | this.graph.start = start_end[0]; | ||
117 | this.graph.end = start_end[1]; | ||
118 | }, | ||
119 | set_option: function(option, value) | ||
120 | { | ||
121 | switch(option) { | ||
122 | case 'alt-autoscale': | ||
123 | case 'A': | ||
124 | this.graph.alt_autoscale = true; | ||
125 | break; | ||
126 | case 'base': | ||
127 | case 'b': | ||
128 | this.graph.base = parseInt(value, 10); | ||
129 | if (this.graph.base !== 1000 && this.graph.base !== 1024) | ||
130 | throw 'the only sensible value for base apart from 1000 is 1024'; | ||
131 | break; | ||
132 | case 'color': | ||
133 | case 'c': | ||
134 | var index = value.indexOf('#'); | ||
135 | if (index === -1) | ||
136 | throw "invalid color def format"; | ||
137 | var name = value.substr(0,index); | ||
138 | if (!this.graph.GRC[name]) | ||
139 | throw "invalid color name '"+name+"'" | ||
140 | this.graph.GRC[name] = value.substr(index); // FIXME check color | ||
141 | break; | ||
142 | case 'full-size-mode': | ||
143 | case 'D': | ||
144 | this.graph.full_size_mode = true; | ||
145 | break; | ||
146 | case 'slope-mode': | ||
147 | case 'E': | ||
148 | this.graph.slopemode = true; | ||
149 | break; | ||
150 | case 'end': | ||
151 | case 'e': | ||
152 | this.graph.end_t = new RrdTime(value); | ||
153 | // this.graph.end = parseInt(value, 10); | ||
154 | break; | ||
155 | case 'force-rules-legend': | ||
156 | case 'F': | ||
157 | this.graph.force_rules_legend = true; | ||
158 | break; | ||
159 | case 'imginfo': | ||
160 | case 'f': | ||
161 | // im->imginfo = optarg; | ||
162 | break; | ||
163 | case 'graph-render-mode': | ||
164 | case 'G': | ||
165 | // im->graph_antialias | ||
166 | break; | ||
167 | case 'no-legend': | ||
168 | case 'g': | ||
169 | this.graph.no_legend = true; | ||
170 | break; | ||
171 | case 'height': | ||
172 | case 'h': | ||
173 | this.graph.ysize = parseInt(value, 10); | ||
174 | break; | ||
175 | case 'no-minor': | ||
176 | case 'I': | ||
177 | this.graph.no_minor = false; | ||
178 | break; | ||
179 | case 'interlaced': | ||
180 | case 'i': | ||
181 | break; | ||
182 | case 'alt-autoscale-min': | ||
183 | case 'J': | ||
184 | this.graph.alt_autoscale_min = true; | ||
185 | break; | ||
186 | case 'only-graph': | ||
187 | case 'j': | ||
188 | this.graph.only_graph = true; | ||
189 | break; | ||
190 | case 'units-length': | ||
191 | case 'L': | ||
192 | this.graph.unitslength = parseInt(value, 10); | ||
193 | this.graph.forceleftspace = true; | ||
194 | break; | ||
195 | case 'lower-limit': | ||
196 | case 'l': | ||
197 | this.graph.setminval = parseFloat(value) | ||
198 | break; | ||
199 | case 'alt-autoscale-max': | ||
200 | case 'M': | ||
201 | this.graph.alt_autoscale_max = true; | ||
202 | break; | ||
203 | case 'zoom': | ||
204 | case 'm': | ||
205 | this.graph.zoom = parseFloat(value); | ||
206 | if (this.graph.zoom <= 0.0) | ||
207 | throw "zoom factor must be > 0"; | ||
208 | break; | ||
209 | case 'no-gridfit': | ||
210 | case 'N': | ||
211 | this.graph.gridfit = true; | ||
212 | break; | ||
213 | case 'font': | ||
214 | case 'n': | ||
215 | var args = value.split(':'); | ||
216 | if (args.length !== 3) | ||
217 | throw "invalid text property format"; | ||
218 | if (!this.graph.TEXT[args[0]]) | ||
219 | throw "invalid fonttag '"+args[0]+"'" | ||
220 | if (args[1] > 0) | ||
221 | this.graph.TEXT[args[0]].size = args[1]; | ||
222 | if (args[2]) | ||
223 | this.graph.TEXT[args[0]].font = args[2]; | ||
224 | break; | ||
225 | case 'logarithmic': | ||
226 | case 'o': | ||
227 | this.graph.logarithmic = true; | ||
228 | break; | ||
229 | case 'pango-markup': | ||
230 | case 'P': | ||
231 | // im->with_markup = 1; | ||
232 | break; | ||
233 | case 'font-render-mode': | ||
234 | case 'R': | ||
235 | // im->font_options: normal light mono | ||
236 | break; | ||
237 | case 'rigid': | ||
238 | case 'r': | ||
239 | this.graph.rigid = true; | ||
240 | break; | ||
241 | case 'step': | ||
242 | this.graph.step = parseInt(value, 10); | ||
243 | break; | ||
244 | case 'start': | ||
245 | case 's': | ||
246 | this.graph.start_t = new RrdTime(value); | ||
247 | //this.graph.start = parseInt(value, 10); | ||
248 | break; | ||
249 | case 'tabwidth': | ||
250 | case 'T': | ||
251 | this.graph.tabwidth = parseFloat(value); | ||
252 | break; | ||
253 | case 'title': | ||
254 | case 't': | ||
255 | this.graph.title = value; | ||
256 | break; | ||
257 | case 'upper-limit': | ||
258 | case 'u': | ||
259 | this.graph.setmaxval = parseFloat(value); | ||
260 | break; | ||
261 | case 'vertical-label': | ||
262 | case 'v': | ||
263 | this.graph.ylegend = value; | ||
264 | break; | ||
265 | case 'watermark': | ||
266 | case 'W': | ||
267 | this.graph.watermark = value; | ||
268 | break; | ||
269 | case 'width': | ||
270 | case 'w': | ||
271 | this.graph.xsize = parseInt(value, 10); | ||
272 | if (this.graph.xsize < 10) | ||
273 | throw "width below 10 pixels"; | ||
274 | break; | ||
275 | case 'units-exponent': | ||
276 | case 'X': | ||
277 | this.graph.unitsexponent = parseInt(value, 10); | ||
278 | break; | ||
279 | case 'x-grid': | ||
280 | case 'x': | ||
281 | if (value === 'none') { | ||
282 | this.graph.draw_x_grid = false; | ||
283 | } else { | ||
284 | var args = value.split(':'); | ||
285 | if (args.length !== 8) | ||
286 | throw "invalid x-grid format"; | ||
287 | this.graph.xlab_user.gridtm = this.graph.tmt_conv(args[0]); | ||
288 | if (this.graph.xlab_user.gridtm < 0) | ||
289 | throw "unknown keyword "+args[0]; | ||
290 | this.graph.xlab_user.gridst = parseInt(args[1], 10); | ||
291 | this.graph.xlab_user.mgridtm = this.graph.tmt_conv(args[2]); | ||
292 | if (this.graph.xlab_user.mgridtm < 2) | ||
293 | throw "unknown keyword "+args[2]; | ||
294 | this.graph.xlab_user.mgridst = parseInt(args[3], 10); | ||
295 | this.graph.xlab_user.labtm = this.graph.tmt_conv(args[4]); | ||
296 | if (this.graph.xlab_user.labtm < 0) | ||
297 | throw "unknown keyword "+args[4]; | ||
298 | this.graph.xlab_user.labst = parseInt(args[5], 10); | ||
299 | this.graph.xlab_user.precis = parseInt(args[6], 10); | ||
300 | this.graph.xlab_user.minsec = 1; | ||
301 | this.graph.xlab_form = args[7]; // FIXME : ? join(:) | ||
302 | this.graph.xlab_user.stst = this.graph.xlab_form; | ||
303 | } | ||
304 | break; | ||
305 | case 'alt-y-grid': | ||
306 | case 'Y': | ||
307 | this.graph.alt_ygrid = true; | ||
308 | break; | ||
309 | case 'y-grid': | ||
310 | case 'y': | ||
311 | if (value === 'none') { | ||
312 | this.graph.draw_y_grid = false; | ||
313 | } else { | ||
314 | var index = value.indexOf(':'); | ||
315 | if (index === -1) | ||
316 | throw "invalid y-grid format"; | ||
317 | this.graph.ygridstep = parseFloat(value.substr(0,index)); | ||
318 | if (this.graph.ygridstep <= 0) | ||
319 | throw "grid step must be > 0"; | ||
320 | this.graph.ylabfact = parseInt(value.substr(index+1), 10); | ||
321 | if (this.graph.ylabfact < 1) | ||
322 | throw "label factor must be > 0"; | ||
323 | } | ||
324 | break; | ||
325 | case 'lazy': | ||
326 | case 'z': | ||
327 | this.graph.lazy = 1; | ||
328 | break; | ||
329 | case 'units': | ||
330 | if (this.graph.force_units) | ||
331 | throw "--units can only be used once!"; | ||
332 | if (value === 'si') | ||
333 | this.graph.force_units_si = true; | ||
334 | else | ||
335 | throw "invalid argument for --units: "+value; | ||
336 | break; | ||
337 | case 'alt-y-mrtg': | ||
338 | break; | ||
339 | case 'disable-rrdtool-tag': | ||
340 | this.graph.no_rrdtool_tag = true; | ||
341 | break; | ||
342 | case 'right-axis': | ||
343 | var index = value.indexOf(':'); | ||
344 | if (index === -1) | ||
345 | throw "invalid right-axis format expected scale:shift"; | ||
346 | this.graph.second_axis_scale = parseFloat(value.substr(0,index)); | ||
347 | if(this.graph.second_axis_scale === 0) | ||
348 | throw "the second_axis_scale must not be 0"; | ||
349 | this.graph.second_axis_shift = parseFloat(value.substr(index+1)); | ||
350 | break; | ||
351 | case 'right-axis-label': | ||
352 | this.graph.second_axis_legend = value; | ||
353 | break; | ||
354 | case 'right-axis-format': | ||
355 | this.graph.second_axis_format = value; | ||
356 | break; | ||
357 | case 'legend-position': | ||
358 | if (value === "north") { | ||
359 | this.graph.legendposition = this.graph.LEGEND_POS.NORTH; | ||
360 | } else if (value === "west") { | ||
361 | this.graph.legendposition = this.graph.LEGEND_POS.WEST; | ||
362 | } else if (value === "south") { | ||
363 | this.graph.legendposition = this.graph.LEGEND_POS.SOUTH; | ||
364 | } else if (value === "east") { | ||
365 | this.graph.legendposition = this.graph.LEGEND_POS.EAST; | ||
366 | } else { | ||
367 | throw "unknown legend-position '"+value+"'"; | ||
368 | } | ||
369 | break; | ||
370 | case 'legend-direction': | ||
371 | if (value === "topdown") { | ||
372 | this.graph.legenddirection = this.graph.LEGEND_DIR.TOP_DOWN; | ||
373 | } else if (value === "bottomup") { | ||
374 | this.graph.legenddirection = this.graph.LEGEND_DIR.BOTTOM_UP; | ||
375 | } else { | ||
376 | throw "unknown legend-position '"+value+"'"; | ||
377 | } | ||
378 | break; | ||
379 | case 'border': | ||
380 | this.graph.draw_3d_border = parseInt(value, 10); | ||
381 | break; | ||
382 | case 'grid-dash': | ||
383 | var index = value.indexOf(':'); | ||
384 | if (index === -1) | ||
385 | throw "expected grid-dash format float:float"; | ||
386 | this.graph.grid_dash_on = parseFloat(value.substr(0,index)); | ||
387 | this.graph.grid_dash_off = parseFloat(value.substr(index+1)); | ||
388 | break; | ||
389 | case 'dynamic-labels': | ||
390 | this.graph.dynamic_labels = true; | ||
391 | break; | ||
392 | default: | ||
393 | throw 'Unknow option "'+option+'"'; | ||
394 | } | ||
395 | |||
396 | }, | ||
397 | // DEF:<vname>=<rrdfile>:<ds-name>:<CF>[:step=<step>][:start=<time>][:end=<time>][:reduce=<CF>] | ||
398 | parse_def: function (line) | ||
399 | { | ||
400 | var args = line.split(/:/); | ||
401 | var n=1; | ||
402 | var vnames = args[n++].split('='); | ||
403 | var vname = vnames[0]; | ||
404 | var rrdfile = vnames[1]; | ||
405 | var name = args[n++]; | ||
406 | var cf = args[n++]; | ||
407 | var step = undefined; | ||
408 | var reduce = undefined; | ||
409 | var start = undefined; | ||
410 | var end = undefined; | ||
411 | if (args.length > n) { | ||
412 | for (var j = n, xlen = args.length ; j < xlen ; j++) { | ||
413 | var opts = args[j].split("="); | ||
414 | if (opts[0] === "step") step = opts[1]; | ||
415 | if (opts[0] === "reduce") reduce = opts[1] | ||
416 | if (opts[0] === "start") start = opts[1]; | ||
417 | if (opts[0] === "end") end = opts[1]; | ||
418 | } | ||
419 | } | ||
420 | this.graph.gdes_add_def(vname, rrdfile, name, cf, step, start, end, reduce) | ||
421 | }, | ||
422 | // CDEF:vname=RPN expression | ||
423 | parse_cdef: function (line) | ||
424 | { | ||
425 | var args = line.split(/:|=/); | ||
426 | this.graph.gdes_add_cdef(args[1], args[2]); | ||
427 | }, | ||
428 | // VDEF:vname=RPN expression | ||
429 | parse_vdef: function (line) | ||
430 | { | ||
431 | var args = line.split(/:|=/); | ||
432 | this.graph.gdes_add_vdef(args[1], args[2]); | ||
433 | }, | ||
434 | // SHIFT:vname:offset | ||
435 | parse_shift: function (line) | ||
436 | { | ||
437 | var args = line.split(':'); | ||
438 | this.graph.gdes_add_shift(args[1], args[2]); | ||
439 | }, | ||
440 | // LINE[width]:value[#color][:[legend][:STACK]][:dashes[=on_s[,off_s[,on_s,off_s]...]][:dash-offset=offset]] | ||
441 | parse_line: function (line) | ||
442 | { | ||
443 | var args = line.split(/#|:/); | ||
444 | var width = parseFloat(args[0].substr(4)); | ||
445 | var stack = args[4] === 'STACK' ? true : undefined; | ||
446 | var color = this.graph.parse_color(args[2]); | ||
447 | this.graph.gdes_add_line(width, args[1], this.graph.color2rgba(color), args[3], stack); | ||
448 | }, | ||
449 | // AREA:value[#color][:[legend][:STACK]] | ||
450 | parse_area: function (line) | ||
451 | { | ||
452 | var args = line.split(/#|:/); | ||
453 | var stack = args[3] === 'STACK' ? true : undefined; | ||
454 | var color = this.graph.parse_color(args[2]); | ||
455 | this.graph.gdes_add_area(args[1], this.graph.color2rgba(color), stack); | ||
456 | }, | ||
457 | // TICK:vname#rrggbb[aa][:fraction[:legend]] | ||
458 | parse_tick: function (line) | ||
459 | { | ||
460 | var args = line.split(/:|#/); | ||
461 | var color = this.graph.parse_color(args[2]); | ||
462 | this.graph.gdes_add_tick(args[1], this.graph.color2rgba(color), args[3], args[4]); | ||
463 | }, | ||
464 | // GPRINT:vname:format | ||
465 | parse_gprint: function(line) | ||
466 | { | ||
467 | var args = line.split(':'); | ||
468 | var strftime = false; | ||
469 | var vname = args[1]; | ||
470 | var cf = args[2]; | ||
471 | var format = ""; | ||
472 | if (args.length > 3) { | ||
473 | var m=0; | ||
474 | for (var j = 3, xlen = args.length ; j < xlen ; j++) { | ||
475 | if (args[j] === 'strftime') { | ||
476 | strftime = true; | ||
477 | } else { | ||
478 | if (m>0) { | ||
479 | format = format + ':'+ args[j]; | ||
480 | } else { | ||
481 | format = args[j]; | ||
482 | } | ||
483 | m++; | ||
484 | } | ||
485 | } | ||
486 | } | ||
487 | this.graph.gdes_add_gprint(vname, cf, format, strftime); | ||
488 | }, | ||
489 | //COMMENT:text | ||
490 | parse_comment: function (line) | ||
491 | { | ||
492 | var index = line.indexOf(':'); | ||
493 | this.graph.gdes_add_comment(line.substr(index+1)); | ||
494 | }, | ||
495 | // TEXTALIGN:{left|right|justified|center} | ||
496 | parse_textaling: function (line) | ||
497 | { | ||
498 | var index = line.indexOf(':'); | ||
499 | this.graph.gdes_add_textaling(line.substr(index+1)); | ||
500 | }, | ||
501 | // VRULE:time#color[:legend][:dashes[=on_s[,off_s[,on_s,off_s]...]][:dash-offset=offset]] | ||
502 | parse_vrule: function (line) | ||
503 | { | ||
504 | var args = line.split(/:|#/); | ||
505 | this.graph.gdes_add_vrule(args[1], '#'+args[2], args[3]); | ||
506 | }, | ||
507 | // HRULE:value#color[:legend][:dashes[=on_s[,off_s[,on_s,off_s]...]][:dash-offset=offset]] | ||
508 | parse_hrule: function (line) | ||
509 | { | ||
510 | var args = line.split(/:|#/); | ||
511 | this.graph.gdes_add_hrule(args[1], '#'+args[2], args[3]); | ||
512 | } | ||
513 | }; | ||