]> arthur.barton.de Git - netdata.git/blob - web/dashboard.js
added jsonwrap api option to allow javascript get information about the result set...
[netdata.git] / web / dashboard.js
1 // You can set the following variables before loading this script:
2 //
3 // var netdataStopDygraph = 1;                  // do not use dygraph
4 // var netdataStopSparkline = 1;                // do not use sparkline
5 // var netdataStopPeity = 1;                    // do not use peity
6 // var netdataStopGoogleCharts = 1;             // do not use google
7 // var netdataStopMorris = 1;                   // do not use morris
8 //
9 // You can also set the default netdata server, using the following.
10 // When this variable is not set, we assume the page is hosted on your
11 // netdata server already.
12 // var netdataServer = "http://yourhost:19999"; // set your NetData server
13
14 (function(window)
15 {
16         // fix IE bug with console
17         if(!window.console){ window.console = {log: function(){} }; }
18
19         var NETDATA = window.NETDATA || {};
20
21         // ----------------------------------------------------------------------------------------------------------------
22         // Detect the netdata server
23
24         // http://stackoverflow.com/questions/984510/what-is-my-script-src-url
25         // http://stackoverflow.com/questions/6941533/get-protocol-domain-and-port-from-url
26         NETDATA._scriptSource = function(scripts) {
27                 var script = null, base = null;
28
29                 if(typeof document.currentScript != 'undefined') {
30                         script = document.currentScript;
31                 }
32                 else {
33                         var all_scripts = document.getElementsByTagName('script');
34                         script = all_scripts[all_scripts.length - 1];
35                 }
36
37                 if (script.getAttribute.length != 'undefined')
38                         script = script.src;
39                 else
40                         script = script.getAttribute('src', -1);
41
42                 var link = document.createElement('a');
43                 link.setAttribute('href', script);
44
45                 if(!link.protocol || !link.hostname) return null;
46
47                 base = link.protocol;
48                 if(base) base += "//";
49                 base += link.hostname;
50
51                 if(link.port) base += ":" + link.port;
52                 base += "/";
53
54                 return base;
55         };
56
57         if(typeof netdataServer != 'undefined')
58                 NETDATA.serverDefault = netdataServer + "/";
59         else
60                 NETDATA.serverDefault = NETDATA._scriptSource();
61
62         NETDATA.jQuery       = NETDATA.serverDefault + 'lib/jquery-1.11.3.min.js';
63         NETDATA.peity_js     = NETDATA.serverDefault + 'lib/jquery.peity.min.js';
64         NETDATA.sparkline_js = NETDATA.serverDefault + 'lib/jquery.sparkline.min.js';
65         NETDATA.dygraph_js   = NETDATA.serverDefault + 'lib/dygraph-combined.js';
66         NETDATA.raphael_js   = NETDATA.serverDefault + 'lib/raphael-min.js';
67         NETDATA.morris_js    = NETDATA.serverDefault + 'lib/morris.min.js';
68         NETDATA.morris_css   = NETDATA.serverDefault + 'css/morris.css';
69         NETDATA.google_js    = 'https://www.google.com/jsapi';
70         NETDATA.colors  = [ '#3366CC', '#DC3912', '#FF9900', '#109618', '#990099', '#3B3EAC', '#0099C6',
71                                                 '#DD4477', '#66AA00', '#B82E2E', '#316395', '#994499', '#22AA99', '#AAAA11',
72                                                 '#6633CC', '#E67300', '#8B0707', '#329262', '#5574A6', '#3B3EAC' ];
73
74         // ----------------------------------------------------------------------------------------------------------------
75         // the defaults for all charts
76
77         NETDATA.chartDefaults = {
78                 host: NETDATA.serverDefault,    // the server to get data from
79                 width: '100%',                                  // the chart width
80                 height: '100%',                                 // the chart height
81                 library: 'dygraph',                             // the graphing library to use
82                 method: 'average',                              // the grouping method
83                 before: 0,                                              // panning
84                 after: -600,                                    // panning
85                 pixels_per_point: 1                             // the detail of the chart
86         }
87
88         NETDATA.options = {
89                 targets: null,                          
90                 updated_dom: 1,
91                 last_paused: 0,
92                 page_is_visible: 1,
93
94                 current: {
95                         pixels_per_point: 1,
96                         idle_between_charts: 100,
97                         idle_between_loops: 500,
98                         idle_lost_focus: 500,
99                         fast_render_timeframe: 200 // render continously for these many ms
100                 },
101
102                 debug: {
103                         show_boxes:             0,
104                         main_loop:                      0,
105                         focus:                          1,
106                         visibility:             0,
107                         chart_data_url:         1,
108                         chart_errors:           1,
109                         chart_timing:           0,
110                         chart_calls:            0,
111                 }
112         }
113
114         if(NETDATA.options.debug.main_loop) console.log('welcome to NETDATA');
115
116
117         // ----------------------------------------------------------------------------------------------------------------
118         // Error Handling
119
120         NETDATA.errorCodes = {
121                 100: { message: "Cannot load chart library", alert: true },
122                 101: { message: "Cannot load jQuery", alert: true },
123                 402: { message: "Chart library not found", alert: false },
124                 403: { message: "Chart library not enabled/is failed", alert: false },
125                 404: { message: "Chart not found", alert: false }
126         };
127         NETDATA.errorLast = {
128                 code: 0,
129                 message: "",
130                 datetime: 0
131         };
132
133         NETDATA.error = function(code, msg) {
134                 NETDATA.errorLast.code = code;
135                 NETDATA.errorLast.message = msg;
136                 NETDATA.errorLast.datetime = new Date().getTime();
137
138                 console.log("ERROR " + code + ": " + NETDATA.errorCodes[code].message + ": " + msg);
139
140                 if(NETDATA.errorCodes[code].alert)
141                         alert("ERROR " + code + ": " + NETDATA.errorCodes[code].message + ": " + msg);
142         }
143
144         NETDATA.errorReset = function() {
145                 NETDATA.errorLast.code = 0;
146                 NETDATA.errorLast.message = "You are doing fine!";
147                 NETDATA.errorLast.datetime = 0;
148         }
149
150         NETDATA.messageInABox = function(element, message) {
151                 self = $(element);
152
153                 bgcolor = ""
154                 if(NETDATA.options.debug.show_boxes)
155                         bgcolor = " background-color: lightgrey;";
156
157                 element.innerHTML = '<div style="font-size: xx-small; overflow: hidden;' + bgcolor + ' width: 100%; height: 100%;"><small>'
158                         + message
159                         + '</small></div>';
160
161                 self.data('created', false);
162         }
163
164         // ----------------------------------------------------------------------------------------------------------------
165         // Library functions
166
167         // Load a script without jquery
168         // This is used to load jquery - after it is loaded, we use jquery
169         NETDATA._loadjQuery = function(callback) {
170                 if(typeof jQuery == 'undefined') {
171                         var script = document.createElement('script');
172                         script.type = 'text/javascript';
173                         script.async = true;
174                         script.src = NETDATA.jQuery;
175
176                         // script.onabort = onError;
177                         script.onerror = function(err, t) { NETDATA.error(101, NETDATA.jQuery); };
178                         if(typeof callback == "function")
179                                 script.onload = callback;
180
181                         var s = document.getElementsByTagName('script')[0];
182                         s.parentNode.insertBefore(script, s);
183                 }
184                 else if(typeof callback == "function")
185                         callback();
186         }
187
188         NETDATA.ColorLuminance = function(hex, lum) {
189                 // validate hex string
190                 hex = String(hex).replace(/[^0-9a-f]/gi, '');
191                 if (hex.length < 6)
192                         hex = hex[0]+hex[0]+hex[1]+hex[1]+hex[2]+hex[2];
193
194                 lum = lum || 0;
195
196                 // convert to decimal and change luminosity
197                 var rgb = "#", c, i;
198                 for (i = 0; i < 3; i++) {
199                         c = parseInt(hex.substr(i*2,2), 16);
200                         c = Math.round(Math.min(Math.max(0, c + (c * lum)), 255)).toString(16);
201                         rgb += ("00"+c).substr(c.length);
202                 }
203
204                 return rgb;
205         }
206
207         NETDATA.guid = function() {
208                 function s4() {
209                         return Math.floor((1 + Math.random()) * 0x10000)
210                                         .toString(16)
211                                         .substring(1);
212                         }
213
214                         return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
215         }
216
217         // this is the main function - where everything starts
218         NETDATA.init = function() {
219                 // this should be called only once
220
221                 $(window).blur(function() {
222                         NETDATA.options.page_is_visible = 0;
223                         if(NETDATA.options.debug.focus) console.log('Lost Focus!');
224                 });
225
226                 $(window).focus(function() {
227                         NETDATA.options.page_is_visible = 1;
228                         if(NETDATA.options.debug.focus) console.log('Focus restored!');
229                 });
230
231                 NETDATA.getDomCharts(function() {
232                         NETDATA.chartRefresher(0);
233                 });
234         }
235
236         // user function to signal us the DOM has been
237         // updated.
238         NETDATA.updatedDom = function() {
239                 NETDATA.options.updated_dom = 1;
240         }
241
242         // ----------------------------------------------------------------------------------------------------------------
243
244         NETDATA.generateChartDataURL = function() {
245                 self = $(this);
246
247                 var chart = self.data('chart');
248                 var host = self.data('host') || NETDATA.chartDefaults.host;
249                 var width = self.width();
250                 var height = self.height();
251                 var method = self.data('method') || NETDATA.chartDefaults.method;
252                 var after = self.data('after') || NETDATA.chartDefaults.after;
253                 var before = self.data('before') || NETDATA.chartDefaults.before;
254                 var library = self.data('chart-library') || NETDATA.chartDefaults.library;
255                 var dimensions = self.data('dimensions') || null;
256                 var pixels_per_point = self.data('pixels-per-point') || NETDATA.chartLibraries[library].pixels_per_point;
257
258                 // force an options provided detail
259                 if(pixels_per_point < NETDATA.options.current.pixels_per_point)
260                         pixels_per_point = NETDATA.options.current.pixels_per_point
261
262                 var points = self.data('points') || Math.round(width / pixels_per_point);
263                 var format = self.data('format') || NETDATA.chartLibraries[library].format;
264                 var options = self.data('options') || NETDATA.chartLibraries[library].options;
265
266                 // build the data URL
267                 var url = host + chart.data_url;
268                 url += "&format="  + format;
269                 url += "&points="  + points.toString();
270                 url += "&options=" + options;
271                 url += "&group="   + method;
272
273                 if(after)
274                         url += "&after="  + after.toString();
275
276                 if(before)
277                         url += "&before=" + before.toString();
278
279                 if(dimensions)
280                         url += "&dimensions=" + dimensions;
281
282                 self.data('calculated-width', width)
283                         .data('calculated-height', height)
284                         .data('calculated-points', points)
285                         .data('calculated-url', url);
286
287                 if(NETDATA.options.debug.chart_data_url) console.log('generateChartDataURL(): ' + url + ' WxH:' + width + 'x' + height + ' points: ' + points + ' library: ' + library);
288                 return url;
289         }
290
291         NETDATA.validateDomCharts = function(targets, index, callback) {
292                 if(NETDATA.options.debug.main_loop) console.log('validateDomCharts() working on ' + index);
293
294                 var target = targets.get(index);
295                 if(target == null) {
296                         if(NETDATA.options.debug.main_loop) console.log('validateDomCharts(): all ' + (index - 1) + ' charts parsed.');
297                         if(typeof callback == 'function') callback();
298                 }
299                 else {
300                         var self = $(target);
301                         if(!self.data('prepared')) {
302                                 self.data('prepared', true)
303                                         .data('updated', 0)
304                                         .data('created', false)
305                                         .data('enabled', false);
306
307                                 var id = self.data('netdata');
308                                 var host = self.data('host') || NETDATA.chartDefaults.host;
309                                 var library = self.data('chart-library') || NETDATA.chartDefaults.library;
310
311                                 if(NETDATA.options.debug.main_loop) console.log('validateDomCharts() parsing ' + id + ' of type ' + library);
312
313                                 if(typeof NETDATA.chartLibraries[library] == 'undefined') {
314                                         NETDATA.error(402, library);
315                                         NETDATA.messageInABox(target, 'chart library "' + library + '" is not found');
316                                         NETDATA.validateDomCharts(targets, ++index, callback);
317                                 }
318                                 else if(!NETDATA.chartLibraries[library].enabled) {
319                                         NETDATA.error(403, library);
320                                         NETDATA.messageInABox(target, 'chart library "' + library + '" is not enabled');
321                                         NETDATA.validateDomCharts(targets, ++index, callback);
322                                 }
323                                 else if(!NETDATA.chartLibraries[library].initialized) {
324                                         self.data('prepared', false);
325                                         NETDATA.chartLibraries[library].initialize(function() {
326                                                 NETDATA.validateDomCharts(targets, index, callback);
327                                         });
328                                 }
329                                 else {
330                                         var url = host + "/api/v1/chart?chart=" + id;
331
332                                         $.ajax( {
333                                                 url:  url,
334                                                 crossDomain: true
335                                         })
336                                         .done(function(chart) {
337                                                 self.data('chart', chart)
338                                                         .data('update-every', chart.update_every * 1000)
339                                                         .data('enabled', true)
340                                                         .data('host', host)
341                                                         .data('chart-library', library);
342                                         })
343                                         .fail(function() {
344                                                 NETDATA.error(404, url);
345                                                 NETDATA.messageInABox(target, 'chart "' + id + '" not found on url "' + url + '"');
346                                         })
347                                         .always(function() {
348                                                 NETDATA.validateDomCharts(targets, ++index, callback);
349                                         });
350                                 }
351                         }
352                         else {
353                                 NETDATA.validateDomCharts(targets, ++index, callback);
354                         }
355                 }
356         }
357
358         NETDATA.sizeDomCharts = function(targets, index, callback) {
359                 // this is used to quickly size all charts to their size
360
361                 if(NETDATA.options.debug.main_loop) console.log('sizeDomCharts() working on ' + index);
362
363                 var target = targets.get(index);
364                 if(target == null) {
365                         if(NETDATA.options.debug.main_loop) console.log('sizeDomCharts(): all ' + (index - 1) + ' charts sized.');
366                         if(typeof callback == 'function') callback();
367                 }
368                 else {
369                         var self = $(target);
370
371                         var id = self.data('netdata');
372                         var width = self.data('width') || NETDATA.chartDefaults.width;
373                         var height = self.data('height') || NETDATA.chartDefaults.height;
374
375                         self.css('width', width)
376                                 .css('height', height)
377                                 .css('display', 'inline-block')
378                                 .css('overflow', 'hidden');
379
380                         NETDATA.messageInABox(target, 'chart "' + id + '" is loading...');
381                         NETDATA.sizeDomCharts(targets, ++index, callback);
382                 }
383         }
384
385         NETDATA.getDomCharts = function(callback) {
386                 NETDATA.options.updated_dom = 0;
387
388                 NETDATA.options.targets = $('div[data-netdata]').filter(':visible')
389                         .bind('create', function(event, data) {
390                                 var self = $(this);
391
392                                 if(NETDATA.options.debug.chart_errors)
393                                         NETDATA.chartLibraries[self.data('chart-library')].create(this, data);
394                                 else {
395                                         try {
396                                                 NETDATA.chartLibraries[self.data('chart-library')].create(this, data);
397                                         }
398                                         catch(err) {
399                                                 NETDATA.messageInABox(this, 'chart "' + self.data('netdata') + '" failed to be created as ' + self.data('chart-library'));
400                                                 self.data('created', false);
401                                         }
402                                 }
403                         })
404                         .bind('update', function(event, data) {
405                                 var self = $(this);
406                                 if(NETDATA.options.debug.chart_errors)
407                                         NETDATA.chartLibraries[self.data('chart-library')].update(this, data);
408                                 else {
409                                         try {
410                                                 NETDATA.chartLibraries[self.data('chart-library')].update(this, data);
411                                         }
412                                         catch(err) {
413                                                 NETDATA.messageInABox(this, 'chart "' + self.data('netdata') + '" failed to be updated as ' + self.data('chart-library'));
414                                                 self.data('created', false);
415                                         }
416                                 }
417                         });
418
419                 if(NETDATA.options.debug.main_loop)
420                         console.log('DOM updated - there are ' + NETDATA.options.targets.length + ' charts on page.');
421
422                 NETDATA.sizeDomCharts(NETDATA.options.targets, 0, function() {
423                         NETDATA.validateDomCharts(NETDATA.options.targets, 0, callback);
424                 });
425         }
426
427         // ----------------------------------------------------------------------------------------------------------------
428
429         //var chart = function() {
430         //}
431
432         //chart.prototype.color = function() {
433         //      return 'red';
434         //}
435
436         //var c = new chart();
437         //c.color();
438
439         NETDATA.chartValuesDownloader = function(element, callback) {
440                 var self = $(element);
441                 var last = self.data('updated') || 0;
442                 var every = self.data('update-every') || 1;
443
444                 // check if this chart has to be refreshed now
445                 var now = new Date().getTime();
446                 if(last + every > now) {
447                         if(NETDATA.options.debug.chart_timing) console.log(self.data('netdata') + ' too soon - skipping.');
448                         if(typeof callback == 'function') callback();
449                 }
450                 else if(!self.visible(true)) {
451                         if(NETDATA.options.debug.visibility) console.log(self.data('netdata') + ' is NOT visible.');
452                         if(typeof callback == 'function') callback();
453                 }
454                 else {
455                         if(NETDATA.options.debug.visibility) console.log(self.data('netdata') + ' is visible, downloading data...');
456                         $.ajax( {
457                                 url: NETDATA.generateChartDataURL.call(element), // self.data('chart-url'),
458                                 crossDomain: true
459                         })
460                         .then(function(data) {
461                                 var started = new Date().getTime();
462
463                                 // if the result is JSON, find the latest update-every
464                                 if(NETDATA.chartLibraries[self.data('chart-library')].jsonWrapper &&
465                                         typeof data.update_every != 'undefined')
466                                                 self.data('update-every', data.update_every * 1000);
467
468                                 if(self.data('created')) {
469                                         if(NETDATA.options.debug.chart_calls) console.log('updating ' + self.data('chart-library') + ' chart ' + self.data('netdata'));
470                                         self.trigger('update', [data]);
471                                         // NETDATA.chartLibraries[self.data('chart-library')].update(element, data);
472                                 }
473                                 else {
474                                         if(NETDATA.options.debug.chart_calls) console.log('creating ' + self.data('chart-library') + ' chart ' + self.data('netdata'));
475                                         self.trigger('create', [data]);
476                                         //NETDATA.chartLibraries[self.data('chart-library')].create(element, data);
477                                         self.data('created', true);
478                                 }
479
480                                 var ended = new Date().getTime();
481                                 self.data('updated', ended);
482
483                                 var dt = ended - started;
484
485                                 self.data('refresh-dt', dt);
486                                 var element_name = self.data('dt-element-name') || null;
487                                 if(element_name) {
488                                         var element = document.getElementById(element_name) || null;
489                                         if(element) {
490                                                 element.innerHTML = dt.toString();
491                                         }
492                                 }
493                         })
494                         .fail(function() {
495                                 NETDATA.messageInABox(element, 'cannot download chart "' + self.data('netdata') + '" values from url "' + self.data('chart-url') + '"');
496                         })
497                         .always(function() {
498                                 if(typeof callback == 'function') callback();
499                         });
500                 }
501         };
502
503         NETDATA.chartRefresher = function(index) {
504                 // if(NETDATA.options.debug.mail_loop) console.log('NETDATA.chartRefresher(<targets, ' + index + ')');
505
506                 if(!NETDATA.options.page_is_visible) {
507                         if(NETDATA.options.debug.main_loop) console.log('waiting focus...');
508                         setTimeout(function() {
509                                         NETDATA.chartRefresher(index);
510                                 }, NETDATA.options.current.idle_lost_focus);
511                 }
512                 else {
513                         now = new Date().getTime();
514
515                         if(NETDATA.options.updated_dom) {
516                                 // the dom has been updated
517                                 // get the dom parts again
518                                 NETDATA.getDomCharts(function() {
519                                         NETDATA.chartRefresher(0);
520                                 });
521                         }
522                         else {
523                                 var target = NETDATA.options.targets.get(index);
524                                 if(target == null) {
525                                         if(NETDATA.options.debug.main_loop) console.log('waiting to restart main loop...');
526                                         NETDATA.options.last_paused = now;
527
528                                         setTimeout(function() {
529                                                 NETDATA.chartRefresher(0);
530                                         }, NETDATA.options.current.idle_between_loops);
531                                 }
532                                 else {
533                                         var self = $(target);
534                                         if(!self.data('enabled')) {
535                                                 NETDATA.chartRefresher(++index);
536                                         }
537                                         else {
538                                                 if(now - NETDATA.options.last_paused < NETDATA.options.current.fast_render_timeframe) {
539                                                         if(NETDATA.options.debug.main_loop) console.log('fast rendering...');
540
541                                                         NETDATA.chartValuesDownloader(target, function() {
542                                                                 NETDATA.chartRefresher(++index);
543                                                         });
544                                                 }
545                                                 else {
546                                                         if(NETDATA.options.debug.main_loop) console.log('waiting for next refresh...');
547                                                         NETDATA.options.last_paused = now;
548
549                                                         setTimeout(function() {
550                                                                 NETDATA.chartValuesDownloader(target, function() {
551                                                                         NETDATA.chartRefresher(++index);
552                                                                 });
553                                                         }, NETDATA.options.current.idle_between_charts);
554                                                 }
555                                         }
556                                 }
557                         }
558                 }
559         }
560
561         // ----------------------------------------------------------------------------------------------------------------
562         // peity
563
564         NETDATA.peityInitialize = function(callback) {
565                 if(typeof netdataStopPeity == 'undefined') {
566                         $.getScript(NETDATA.peity_js)
567                                 .done(function() {
568                                         NETDATA.registerChartLibrary('peity', NETDATA.peity_js);
569                                 })
570                                 .fail(function() {
571                                         NETDATA.error(100, NETDATA.peity_js);
572                                 })
573                                 .always(function() {
574                                         if(typeof callback == "function")
575                                                 callback();
576                                 })
577                 }
578                 else {
579                         NETDATA.chartLibraries.peity.enabled = false;
580                         if(typeof callback == "function")
581                                 callback();
582                 }
583         };
584
585         NETDATA.peityChartUpdate = function(element, data) {
586                 var self = $(element);
587                 var instance = self.data('peity-instance');
588                 var ins = $(instance);
589                 ins.html(data.result);
590
591                 // peity.change() does not accept options
592                 // to pass width and height
593                 //ins.change();
594                 ins.peity('line', { width: self.data('calculated-width'), height: self.data('calculated-height') })
595         }
596
597         NETDATA.peityChartCreate = function(element, data) {
598                 var self = $(element);
599
600                 var uuid = NETDATA.guid();
601                 element.innerHTML = '<div id="' + uuid + '">' + data.result + '</div>';
602                 var instance = document.getElementById(uuid);
603                 var ins = $(instance);
604
605                 ins.peity('line', { width: self.data('calculated-width'), height: self.data('calculated-height') })
606
607                 self.data('peity-uuid', uuid)
608                         .data('peity-instance', instance)
609                         .data('created', true);
610         }
611
612         // ----------------------------------------------------------------------------------------------------------------
613         // sparkline
614
615         NETDATA.sparklineInitialize = function(callback) {
616                 if(typeof netdataStopSparkline == 'undefined') {
617                         $.getScript(NETDATA.sparkline_js)
618                                 .done(function() {
619                                         NETDATA.registerChartLibrary('sparkline', NETDATA.sparkline_js);
620                                 })
621                                 .fail(function() {
622                                         NETDATA.error(100, NETDATA.sparkline_js);
623                                 })
624                                 .always(function() {
625                                         if(typeof callback == "function")
626                                                 callback();
627                                 })
628                 }
629                 else {
630                         NETDATA.chartLibraries.sparkline.enabled = false;
631                         if(typeof callback == "function") 
632                                 callback();
633                 }
634         };
635
636         NETDATA.sparklineChartUpdate = function(element, data) {
637                 var self = $(element);
638                 var options = self.data('sparkline-options');
639                 options.width = self.data('calculated-width');
640                 options.height = self.data('calculated-height');
641                 self.sparkline(data.result, options);
642         }
643
644         NETDATA.sparklineChartCreate = function(element, data) {
645                 var self = $(element);
646                 var chart = self.data('chart');
647                 var type = self.data('sparkline-type') || 'line';
648                 var lineColor = self.data('sparkline-linecolor') || NETDATA.colors[0];
649                 var fillColor = self.data('sparkline-fillcolor') || (chart.chart_type == 'line')?'#FFF':NETDATA.ColorLuminance(lineColor, 0.8);
650                 var chartRangeMin = self.data('sparkline-chartrangemin') || undefined;
651                 var chartRangeMax = self.data('sparkline-chartrangemax') || undefined;
652                 var composite = self.data('sparkline-composite') || undefined;
653                 var enableTagOptions = self.data('sparkline-enabletagoptions') || undefined;
654                 var tagOptionPrefix = self.data('sparkline-tagoptionprefix') || undefined;
655                 var tagValuesAttribute = self.data('sparkline-tagvaluesattribute') || undefined;
656                 var disableHiddenCheck = self.data('sparkline-disablehiddencheck') || undefined;
657                 var defaultPixelsPerValue = self.data('sparkline-defaultpixelspervalue') || undefined;
658                 var spotColor = self.data('sparkline-spotcolor') || undefined;
659                 var minSpotColor = self.data('sparkline-minspotcolor') || undefined;
660                 var maxSpotColor = self.data('sparkline-maxspotcolor') || undefined;
661                 var spotRadius = self.data('sparkline-spotradius') || undefined;
662                 var valueSpots = self.data('sparkline-valuespots') || undefined;
663                 var highlightSpotColor = self.data('sparkline-highlightspotcolor') || undefined;
664                 var highlightLineColor = self.data('sparkline-highlightlinecolor') || undefined;
665                 var lineWidth = self.data('sparkline-linewidth') || undefined;
666                 var normalRangeMin = self.data('sparkline-normalrangemin') || undefined;
667                 var normalRangeMax = self.data('sparkline-normalrangemax') || undefined;
668                 var drawNormalOnTop = self.data('sparkline-drawnormalontop') || undefined;
669                 var xvalues = self.data('sparkline-xvalues') || undefined;
670                 var chartRangeClip = self.data('sparkline-chartrangeclip') || undefined;
671                 var xvalues = self.data('sparkline-xvalues') || undefined;
672                 var chartRangeMinX = self.data('sparkline-chartrangeminx') || undefined;
673                 var chartRangeMaxX = self.data('sparkline-chartrangemaxx') || undefined;
674                 var disableInteraction = self.data('sparkline-disableinteraction') || false;
675                 var disableTooltips = self.data('sparkline-disabletooltips') || false;
676                 var disableHighlight = self.data('sparkline-disablehighlight') || false;
677                 var highlightLighten = self.data('sparkline-highlightlighten') || 1.4;
678                 var highlightColor = self.data('sparkline-highlightcolor') || undefined;
679                 var tooltipContainer = self.data('sparkline-tooltipcontainer') || undefined;
680                 var tooltipClassname = self.data('sparkline-tooltipclassname') || undefined;
681                 var tooltipFormat = self.data('sparkline-tooltipformat') || undefined;
682                 var tooltipPrefix = self.data('sparkline-tooltipprefix') || undefined;
683                 var tooltipSuffix = self.data('sparkline-tooltipsuffix') || ' ' + chart.units;
684                 var tooltipSkipNull = self.data('sparkline-tooltipskipnull') || true;
685                 var tooltipValueLookups = self.data('sparkline-tooltipvaluelookups') || undefined;
686                 var tooltipFormatFieldlist = self.data('sparkline-tooltipformatfieldlist') || undefined;
687                 var tooltipFormatFieldlistKey = self.data('sparkline-tooltipformatfieldlistkey') || undefined;
688                 var numberFormatter = self.data('sparkline-numberformatter') || function(n){ return n.toFixed(2); };
689                 var numberDigitGroupSep = self.data('sparkline-numberdigitgroupsep') || undefined;
690                 var numberDecimalMark = self.data('sparkline-numberdecimalmark') || undefined;
691                 var numberDigitGroupCount = self.data('sparkline-numberdigitgroupcount') || undefined;
692                 var animatedZooms = self.data('sparkline-animatedzooms') || false;
693
694                 var options = {
695                         type: type,
696                         lineColor: lineColor,
697                         fillColor: fillColor,
698                         chartRangeMin: chartRangeMin,
699                         chartRangeMax: chartRangeMax,
700                         composite: composite,
701                         enableTagOptions: enableTagOptions,
702                         tagOptionPrefix: tagOptionPrefix,
703                         tagValuesAttribute: tagValuesAttribute,
704                         disableHiddenCheck: disableHiddenCheck,
705                         defaultPixelsPerValue: defaultPixelsPerValue,
706                         spotColor: spotColor,
707                         minSpotColor: minSpotColor,
708                         maxSpotColor: maxSpotColor,
709                         spotRadius: spotRadius,
710                         valueSpots: valueSpots,
711                         highlightSpotColor: highlightSpotColor,
712                         highlightLineColor: highlightLineColor,
713                         lineWidth: lineWidth,
714                         normalRangeMin: normalRangeMin,
715                         normalRangeMax: normalRangeMax,
716                         drawNormalOnTop: drawNormalOnTop,
717                         xvalues: xvalues,
718                         chartRangeClip: chartRangeClip,
719                         chartRangeMinX: chartRangeMinX,
720                         chartRangeMaxX: chartRangeMaxX,
721                         disableInteraction: disableInteraction,
722                         disableTooltips: disableTooltips,
723                         disableHighlight: disableHighlight,
724                         highlightLighten: highlightLighten,
725                         highlightColor: highlightColor,
726                         tooltipContainer: tooltipContainer,
727                         tooltipClassname: tooltipClassname,
728                         tooltipChartTitle: chart.title,
729                         tooltipFormat: tooltipFormat,
730                         tooltipPrefix: tooltipPrefix,
731                         tooltipSuffix: tooltipSuffix,
732                         tooltipSkipNull: tooltipSkipNull,
733                         tooltipValueLookups: tooltipValueLookups,
734                         tooltipFormatFieldlist: tooltipFormatFieldlist,
735                         tooltipFormatFieldlistKey: tooltipFormatFieldlistKey,
736                         numberFormatter: numberFormatter,
737                         numberDigitGroupSep: numberDigitGroupSep,
738                         numberDecimalMark: numberDecimalMark,
739                         numberDigitGroupCount: numberDigitGroupCount,
740                         animatedZooms: animatedZooms,
741                         width: self.data('calculated-width'),
742                         height: self.data('calculated-height')
743                 };
744
745                 var uuid = NETDATA.guid();
746                 element.innerHTML = '<div style="display: inline-block; position: relative;" id="' + uuid + '"></div>';
747                 var div = document.getElementById(uuid);
748
749                 self.sparkline(data.result, options);
750                 self.data('sparkline-options', options)
751                         .data('uuid', uuid)
752                         .data('created', true);
753         };
754
755         // ----------------------------------------------------------------------------------------------------------------
756         // dygraph
757
758         NETDATA.dygraphAllCharts = [];
759         NETDATA.dygraphInitSync = function(callback) {
760                 //$.getScript(NETDATA.serverDefault + 'dygraph-synchronizer.js')
761                 //      .always(function() {
762                                 if(typeof callback == "function")
763                                         callback();
764                 //      })
765         }
766
767         NETDATA.dygraphSync = null;
768         NETDATA.dygraphSyncAll = function() {
769                 if(NETDATA.dygraphSync) {
770                         NETDATA.dygraphSync.detach();
771                         NETDATA.dygraphSync = null;
772                 }
773
774                 NETDATA.dygraphSync = Dygraph.synchronize(NETDATA.dygraphAllCharts, {
775                         selection: true,
776                         zoom: false
777                 });
778         }
779
780         NETDATA.dygraphInitialize = function(callback) {
781                 if(typeof netdataStopDygraph == 'undefined') {
782                         $.getScript(NETDATA.dygraph_js)
783                                 .done(function() {
784                                         NETDATA.registerChartLibrary('dygraph', NETDATA.dygraph_js);
785                                 })
786                                 .fail(function() {
787                                         NETDATA.error(100, NETDATA.dygraph_js);
788                                 })
789                                 .always(function() {
790                                         NETDATA.dygraphInitSync(callback);
791                                 })
792                 }
793                 else {
794                         NETDATA.chartLibraries.dygraph.enabled = false;
795                         if(typeof callback == "function")
796                                 callback();
797                 }
798         };
799
800         NETDATA.dygraphChartUpdate = function(element, data) {
801                 var self = $(element);
802                 var dygraph = self.data('dygraph-instance');
803
804                 dygraph.updateOptions({
805                         file: data.result.data,
806                         labels: data.result.labels,
807                         labelsDivWidth: self.width() - 70
808                 });
809         };
810
811         NETDATA.dygraphChartCreate = function(element, data) {
812                 var self = $(element);
813                 var chart = self.data('chart');
814                 var title = self.data('dygraph-title') || chart.title;
815                 var titleHeight = self.data('dygraph-titleheight') || 20;
816                 var labelsDiv = self.data('dygraph-labelsdiv') || undefined;
817                 var connectSeparatedPoints = self.data('dygraph-connectseparatedpoints') || false;
818                 var yLabelWidth = self.data('dygraph-ylabelwidth') || 12;
819                 var stackedGraph = self.data('dygraph-stackedgraph') || (chart.chart_type == 'stacked')?true:false;
820                 var stackedGraphNaNFill = self.data('dygraph-stackedgraphnanfill') || 'none';
821                 var hideOverlayOnMouseOut = self.data('dygraph-hideoverlayonmouseout') || true;
822                 var fillGraph = self.data('dygraph-fillgraph') || (chart.chart_type == 'area')?true:false;
823                 var drawPoints = self.data('dygraph-drawpoints') || false;
824                 var labelsDivStyles = self.data('dygraph-labelsdivstyles') || { 'fontSize':'10px' };
825                 var labelsDivWidth = self.data('dygraph-labelsdivwidth') || self.width() - 70;
826                 var labelsSeparateLines = self.data('dygraph-labelsseparatelines') || false;
827                 var labelsShowZeroValues = self.data('dygraph-labelsshowzerovalues') || true;
828                 var legend = self.data('dygraph-legend') || 'onmouseover';
829                 var showLabelsOnHighlight = self.data('dygraph-showlabelsonhighlight') || true;
830                 var gridLineColor = self.data('dygraph-gridlinecolor') || '#EEE';
831                 var axisLineColor = self.data('dygraph-axislinecolor') || '#EEE';
832                 var maxNumberWidth = self.data('dygraph-maxnumberwidth') || 8;
833                 var sigFigs = self.data('dygraph-sigfigs') || null;
834                 var digitsAfterDecimal = self.data('dygraph-digitsafterdecimal') || 2;
835                 var axisLabelFontSize = self.data('dygraph-axislabelfontsize') || 10;
836                 var axisLineWidth = self.data('dygraph-axislinewidth') || 0.3;
837                 var drawAxis = self.data('dygraph-drawaxis') || true;
838                 var strokeWidth = self.data('dygraph-strokewidth') || 1.0;
839                 var drawGapEdgePoints = self.data('dygraph-drawgapedgepoints') || true;
840                 var colors = self.data('dygraph-colors') || NETDATA.colors;
841                 var pointSize = self.data('dygraph-pointsize') || 1;
842                 var stepPlot = self.data('dygraph-stepplot') || false;
843                 var strokeBorderColor = self.data('dygraph-strokebordercolor') || 'white';
844                 var strokeBorderWidth = self.data('dygraph-strokeborderwidth') || (chart.chart_type == 'stacked')?1.0:0.0;
845                 var strokePattern = self.data('dygraph-strokepattern') || undefined;
846                 var highlightCircleSize = self.data('dygraph-highlightcirclesize') || 3;
847                 var highlightSeriesOpts = self.data('dygraph-highlightseriesopts') || { strokeWidth: 1.5 };
848                 var highlightSeriesBackgroundAlpha = self.data('dygraph-highlightseriesbackgroundalpha') || (chart.chart_type == 'stacked')?0.7:0.5;
849                 var pointClickCallback = self.data('dygraph-pointclickcallback') || undefined;
850                 var showRangeSelector = self.data('dygraph-showrangeselector') || false;
851                 var showRoller = self.data('dygraph-showroller') || false;
852                 var valueFormatter = self.data('dygraph-valueformatter') || undefined; //function(x){ return x.toFixed(2); };
853                 var rightGap = self.data('dygraph-rightgap') || 5;
854                 var drawGrid = self.data('dygraph-drawgrid') || true;
855                 var drawXGrid = self.data('dygraph-drawxgrid') || undefined;
856                 var drawYGrid = self.data('dygraph-drawygrid') || undefined;
857                 var gridLinePattern = self.data('dygraph-gridlinepattern') || null;
858                 var gridLineWidth = self.data('dygraph-gridlinewidth') || 0.3;
859
860                 var options = {
861                         title: title,
862                         titleHeight: titleHeight,
863                         ylabel: chart.units,
864                         yLabelWidth: yLabelWidth,
865                         connectSeparatedPoints: connectSeparatedPoints,
866                         drawPoints: drawPoints,
867                         fillGraph: fillGraph,
868                         stackedGraph: stackedGraph,
869                         stackedGraphNaNFill: stackedGraphNaNFill,
870                         drawGrid: drawGrid,
871                         drawXGrid: drawXGrid,
872                         drawYGrid: drawYGrid,
873                         gridLinePattern: gridLinePattern,
874                         gridLineWidth: gridLineWidth,
875                         gridLineColor: gridLineColor,
876                         axisLineColor: axisLineColor,
877                         axisLineWidth: axisLineWidth,
878                         drawAxis: drawAxis,
879                         hideOverlayOnMouseOut: hideOverlayOnMouseOut,
880                         labelsDiv: labelsDiv,
881                         labelsDivStyles: labelsDivStyles,
882                         labelsDivWidth: labelsDivWidth,
883                         labelsSeparateLines: labelsSeparateLines,
884                         labelsShowZeroValues: labelsShowZeroValues,
885                         labelsKMB: false,
886                         labelsKMG2: false,
887                         legend: legend,
888                         showLabelsOnHighlight: showLabelsOnHighlight,
889                         maxNumberWidth: maxNumberWidth,
890                         sigFigs: sigFigs,
891                         digitsAfterDecimal: digitsAfterDecimal,
892                         axisLabelFontSize: axisLabelFontSize,
893                         colors: colors,
894                         strokeWidth: strokeWidth,
895                         drawGapEdgePoints: drawGapEdgePoints,
896                         pointSize: pointSize,
897                         stepPlot: stepPlot,
898                         strokeBorderColor: strokeBorderColor,
899                         strokeBorderWidth: strokeBorderWidth,
900                         strokePattern: strokePattern,
901                         highlightCircleSize: highlightCircleSize,
902                         highlightSeriesOpts: highlightSeriesOpts,
903                         highlightSeriesBackgroundAlpha: highlightSeriesBackgroundAlpha,
904                         pointClickCallback: pointClickCallback,
905                         showRangeSelector: showRangeSelector,
906                         showRoller: showRoller,
907                         valueFormatter: valueFormatter,
908                         rightGap: rightGap,
909                         labels: data.result.labels,
910                         axes: {
911                                 x: {
912                                         pixelsPerLabel: 50,
913                                         ticker: Dygraph.dateTicker,
914                                         axisLabelFormatter: function (d, gran) {
915                                                 return Dygraph.zeropad(d.getHours()) + ":" + Dygraph.zeropad(d.getMinutes()) + ":" + Dygraph.zeropad(d.getSeconds());
916                                         },
917                                         valueFormatter :function (ms) {
918                                                 var d = new Date(ms);
919                                                 return Dygraph.zeropad(d.getHours()) + ":" + Dygraph.zeropad(d.getMinutes()) + ":" + Dygraph.zeropad(d.getSeconds());
920                                         }
921                                 },
922                                 y: {
923                                         pixelsPerLabel: 15
924                                 }
925                         }
926                 };
927
928                 var uuid = NETDATA.guid();
929                 self.html('<div id="' + uuid + '" style="width: 100%; height: 100%;"></div>');
930
931                 var dchart = new Dygraph(document.getElementById(uuid),
932                         data.result.data, options);
933
934                 self.data('dygraph-instance', dchart)
935                         .data('dygraph-options', options)
936                         .data('uuid', uuid)
937                         .data('created', true);
938
939                 //NETDATA.dygraphAllCharts.push(dchart);
940                 //if(NETDATA.dygraphAllCharts.length > 1)
941                 //      NETDATA.dygraphSyncAll();
942         };
943
944         // ----------------------------------------------------------------------------------------------------------------
945         // morris
946
947         NETDATA.morrisInitialize = function(callback) {
948                 if(typeof netdataStopMorris == 'undefined') {
949
950                         // morris requires raphael
951                         if(!NETDATA.chartLibraries.raphael.initialized) {
952                                 if(NETDATA.chartLibraries.raphael.enabled) {
953                                         NETDATA.raphaelInitialize(function() {
954                                                 NETDATA.morrisInitialize(callback);
955                                         });
956                                 }
957                                 else {
958                                         NETDATA.chartLibraries.morris.enabled = false;
959                                         if(typeof callback == "function")
960                                                 callback();
961                                 }
962                         }
963
964                         var fileref = document.createElement("link");
965                         fileref.setAttribute("rel", "stylesheet");
966                         fileref.setAttribute("type", "text/css");
967                         fileref.setAttribute("href", NETDATA.morris_css);
968
969                         if (typeof fileref != "undefined")
970                                 document.getElementsByTagName("head")[0].appendChild(fileref);
971
972                         $.getScript(NETDATA.morris_js)
973                                 .done(function() {
974                                         NETDATA.registerChartLibrary('morris', NETDATA.morris_js);
975                                 })
976                                 .fail(function() {
977                                         NETDATA.error(100, NETDATA.morris_js);
978                                 })
979                                 .always(function() {
980                                         if(typeof callback == "function")
981                                                 callback();
982                                 })
983                 }
984                 else {
985                         NETDATA.chartLibraries.morris.enabled = false;
986                         if(typeof callback == "function")
987                                 callback();
988                 }
989         };
990
991         NETDATA.morrisChartUpdate = function(element, data) {
992                 var self = $(element);
993                 var morris = self.data('morris-instance');
994
995                 if(morris != null) {
996                         console.log('updating morris');
997                         morris.setData(data.result.data);
998                 }
999                 else
1000                         console.log('not updating morris');
1001         };
1002
1003         NETDATA.morrisChartCreate = function(element, data) {
1004                 var self = $(element);
1005                 var chart = self.data('chart');
1006
1007                 var uuid = NETDATA.guid();
1008                 self.html('<div id="' + uuid + '" style="width: ' + self.data('calculated-width') + 'px; height: ' + self.data('calculated-height') + 'px;"></div>');
1009
1010                 var options = {
1011                                 element: uuid,
1012                                 data: data.result.data,
1013                                 xkey: 'time',
1014                                 ykeys: data.dimension_names,
1015                                 labels: data.dimension_names,
1016                                 lineWidth: 2,
1017                                 pointSize: 2,
1018                                 smooth: true,
1019                                 hideHover: 'auto',
1020                                 parseTime: true,
1021                                 continuousLine: false,
1022                                 behaveLikeLine: false
1023                 };
1024
1025                 var morris;
1026                 if(chart.chart_type == 'line')
1027                         morris = new Morris.Line(options);
1028
1029                 else if(chart.chart_type == 'area') {
1030                         options.behaveLikeLine = true;
1031                         morris = new Morris.Area(options);
1032                 }
1033                 else // stacked
1034                         morris = new Morris.Area(options);
1035
1036                 self.data('morris-instance', morris)
1037                         .data('created', true);
1038         };
1039
1040         // ----------------------------------------------------------------------------------------------------------------
1041         // raphael
1042
1043         NETDATA.raphaelInitialize = function(callback) {
1044                 if(typeof netdataStopRaphael == 'undefined') {
1045                         $.getScript(NETDATA.raphael_js)
1046                                 .done(function() {
1047                                         NETDATA.registerChartLibrary('raphael', NETDATA.raphael_js);
1048                                 })
1049                                 .fail(function() {
1050                                         NETDATA.error(100, NETDATA.raphael_js);
1051                                 })
1052                                 .always(function() {
1053                                         if(typeof callback == "function")
1054                                                 callback();
1055                                 })
1056                 }
1057                 else {
1058                         NETDATA.chartLibraries.raphael.enabled = false;
1059                         if(typeof callback == "function")
1060                                 callback();
1061                 }
1062         };
1063
1064         NETDATA.raphaelChartUpdate = function(element, data) {
1065                 var self = $(element);
1066
1067                 self.raphael(data, {
1068                         width: self.data('calculated-width'),
1069                         height: self.data('calculated-height')
1070                 })
1071         };
1072
1073         NETDATA.raphaelChartCreate = function(element, data) {
1074                 var self = $(element);
1075
1076                 self.raphael(data, {
1077                         width: self.data('calculated-width'),
1078                         height: self.data('calculated-height')
1079                 })
1080                 .data('created', true);
1081         };
1082
1083         // ----------------------------------------------------------------------------------------------------------------
1084         // google charts
1085
1086         NETDATA.googleInitialize = function(callback) {
1087                 if(typeof netdataStopGoogleCharts == 'undefined') {
1088                         $.getScript(NETDATA.google_js)
1089                                 .done(function() {
1090                                         NETDATA.registerChartLibrary('google', NETDATA.google_js);
1091
1092                                         google.load('visualization', '1.1', {
1093                                                 'packages': ['corechart', 'controls'],
1094                                                 'callback': callback
1095                                         });
1096                                 })
1097                                 .fail(function() {
1098                                         NETDATA.error(100, NETDATA.google_js);
1099                                         if(typeof callback == "function")
1100                                                 callback();
1101                                 })
1102                 }
1103                 else {
1104                         NETDATA.chartLibraries.google.enabled = false;
1105                         if(typeof callback == "function")
1106                                 callback();
1107                 }
1108         };
1109
1110         NETDATA.googleChartUpdate = function(element, data) {
1111                 var self = $(element);
1112                 var gchart = self.data('google-instance');
1113                 var options = self.data('google-options');
1114
1115                 var datatable = new google.visualization.DataTable(data.result);
1116
1117                 gchart.draw(datatable, options);
1118         };
1119
1120         NETDATA.googleChartCreate = function(element, data) {
1121                 var self = $(element);
1122                 var chart = self.data('chart');
1123
1124                 var datatable = new google.visualization.DataTable(data.result);
1125                 var gchart;
1126
1127                 var options = {
1128                         // do not set width, height - the chart resizes itself
1129                         //width: self.data('calculated-width'),
1130                         //height: self.data('calculated-height'),
1131                         lineWidth: 1,
1132                         title: chart.title,
1133                         fontSize: 11,
1134                         hAxis: {
1135                         //      title: "Time of Day",
1136                         //      format:'HH:mm:ss',
1137                                 viewWindowMode: 'maximized',
1138                                 slantedText: false,
1139                                 format:'HH:mm:ss',
1140                                 textStyle: {
1141                                         fontSize: 9
1142                                 },
1143                                 gridlines: {
1144                                         color: '#EEE'
1145                                 }
1146                         },
1147                         vAxis: {
1148                                 title: chart.units,
1149                                 viewWindowMode: 'pretty',
1150                                 minValue: -0.1,
1151                                 maxValue: 0.1,
1152                                 direction: 1,
1153                                 textStyle: {
1154                                         fontSize: 9
1155                                 },
1156                                 gridlines: {
1157                                         color: '#EEE'
1158                                 }
1159                         },
1160                         chartArea: {
1161                                 width: '65%',
1162                                 height: '80%'
1163                         },
1164                         focusTarget: 'category',
1165                         annotation: {
1166                                 '1': {
1167                                         style: 'line'
1168                                 }
1169                         },
1170                         pointsVisible: 0,
1171                         titlePosition: 'out',
1172                         titleTextStyle: {
1173                                 fontSize: 11
1174                         },
1175                         tooltip: {
1176                                 isHtml: false,
1177                                 ignoreBounds: true,
1178                                 textStyle: {
1179                                         fontSize: 9
1180                                 }
1181                         },
1182                         curveType: 'function',
1183                         areaOpacity: 0.3,
1184                         isStacked: false
1185                 };
1186
1187                 var uuid = NETDATA.guid();
1188                 self.html('<div id="' + uuid + '" style="width: 100%; height: 100%;"></div>');
1189
1190                 switch(chart.chart_type) {
1191                         case "area":
1192                                 options.vAxis.viewWindowMode = 'maximized';
1193                                 gchart = new google.visualization.AreaChart(document.getElementById(uuid));
1194                                 break;
1195
1196                         case "stacked":
1197                                 options.isStacked = true;
1198                                 options.areaOpacity = 0.85;
1199                                 options.vAxis.viewWindowMode = 'maximized';
1200                                 options.vAxis.minValue = null;
1201                                 options.vAxis.maxValue = null;
1202                                 gchart = new google.visualization.AreaChart(document.getElementById(uuid));
1203                                 break;
1204
1205                         default:
1206                         case "line":
1207                                 options.lineWidth = 2;
1208                                 gchart = new google.visualization.LineChart(document.getElementById(uuid));
1209                                 break;
1210                 }
1211
1212                 gchart.draw(datatable, options);
1213
1214                 self.data('google-instance', gchart)
1215                         .data('google-options', options)
1216                         .data('uuid', uuid)
1217                         .data('created', true);
1218         };
1219
1220         // ----------------------------------------------------------------------------------------------------------------
1221         // Charts Libraries Registration
1222
1223         NETDATA.chartLibraries = {
1224                 "dygraph": {
1225                         initialize: NETDATA.dygraphInitialize,
1226                         create: NETDATA.dygraphChartCreate,
1227                         update: NETDATA.dygraphChartUpdate,
1228                         initialized: false,
1229                         enabled: true,
1230                         format: 'json',
1231                         options: 'ms|flip|jsonwrap',
1232                         jsonWrapper: true,
1233                         pixels_per_point: 2,
1234                         detects_dimensions_on_update: false
1235                 },
1236                 "sparkline": {
1237                         initialize: NETDATA.sparklineInitialize,
1238                         create: NETDATA.sparklineChartCreate,
1239                         update: NETDATA.sparklineChartUpdate,
1240                         initialized: false,
1241                         enabled: true,
1242                         format: 'array',
1243                         options: 'flip|min2max|jsonwrap',
1244                         jsonWrapper: true,
1245                         pixels_per_point: 2,
1246                         detects_dimensions_on_update: false
1247                 },
1248                 "peity": {
1249                         initialize: NETDATA.peityInitialize,
1250                         create: NETDATA.peityChartCreate,
1251                         update: NETDATA.peityChartUpdate,
1252                         initialized: false,
1253                         enabled: true,
1254                         format: 'ssvcomma',
1255                         options: 'null2zero|flip|min2max|jsonwrap',
1256                         jsonWrapper: true,
1257                         pixels_per_point: 2,
1258                         detects_dimensions_on_update: false
1259                 },
1260                 "morris": {
1261                         initialize: NETDATA.morrisInitialize,
1262                         create: NETDATA.morrisChartCreate,
1263                         update: NETDATA.morrisChartUpdate,
1264                         initialized: false,
1265                         enabled: true,
1266                         format: 'json',
1267                         options: 'objectrows|ms|jsonwrap',
1268                         jsonWrapper: true,
1269                         pixels_per_point: 10,
1270                         detects_dimensions_on_update: false
1271                 },
1272                 "google": {
1273                         initialize: NETDATA.googleInitialize,
1274                         create: NETDATA.googleChartCreate,
1275                         update: NETDATA.googleChartUpdate,
1276                         initialized: false,
1277                         enabled: true,
1278                         format: 'datatable',
1279                         options: 'jsonwrap',
1280                         jsonWrapper: true,
1281                         pixels_per_point: 2,
1282                         detects_dimensions_on_update: true
1283                 },
1284                 "raphael": {
1285                         initialize: NETDATA.raphaelInitialize,
1286                         create: NETDATA.raphaelChartCreate,
1287                         update: NETDATA.raphaelChartUpdate,
1288                         initialized: false,
1289                         enabled: true,
1290                         format: 'json',
1291                         options: '',
1292                         jsonWrapper: false,
1293                         pixels_per_point: 1,
1294                         detects_dimensions_on_update: false
1295                 }
1296         };
1297
1298         NETDATA.registerChartLibrary = function(library, url) {
1299                 console.log("registering chart library: " + library);
1300
1301                 NETDATA.chartLibraries[library].url = url;
1302                 NETDATA.chartLibraries[library].initialized = true;
1303                 NETDATA.chartLibraries[library].enabled = true;
1304
1305                 console.log(NETDATA.chartLibraries);
1306         }
1307
1308         // ----------------------------------------------------------------------------------------------------------------
1309         // load all libraries and initialize
1310
1311         NETDATA.errorReset();
1312
1313         NETDATA._loadjQuery(function() {
1314                 $.getScript(NETDATA.serverDefault + 'lib/visible.js').then(function() {
1315                         NETDATA.init();
1316                 })
1317         });
1318
1319 })(window);