]> arthur.barton.de Git - netdata.git/blob - web/dashboard.js
generated html elements now get a uuid
[netdata.git] / web / dashboard.js
1 // You can set the following variables before loading this script:\r
2 //\r
3 // var netdataStopDygraph = 1;                  // do not use dygraph\r
4 // var netdataStopSparkline = 1;                // do not use sparkline\r
5 // var netdataStopPeity = 1;                    // do not use peity\r
6 //\r
7 // You can also set the default netdata server, using the following.\r
8 // When this variable is not set, we assume the page is hosted on your\r
9 // netdata server already.\r
10 // var netdataServer = "http://yourhost:19999"; // set your NetData server\r
11 \r
12 // --------------------------------------------------------------------------------------------------------------------\r
13 // For google charts you need this in your page:\r
14 //      <script type="text/javascript" src="https://www.google.com/jsapi"></script>\r
15 //      <script type='text/javascript'>google.load('visualization', '1.1', {'packages':['corechart', 'controls']});</script>\r
16 \r
17 (function(window)\r
18 {\r
19         var NETDATA = window.NETDATA || {};\r
20 \r
21         // ----------------------------------------------------------------------------------------------------------------\r
22         // Detect the netdata server\r
23 \r
24         // http://stackoverflow.com/questions/984510/what-is-my-script-src-url\r
25         // http://stackoverflow.com/questions/6941533/get-protocol-domain-and-port-from-url\r
26         NETDATA._scriptSource = function(scripts) {\r
27                 var script = null, base = null;\r
28 \r
29                 if(typeof document.currentScript != 'undefined') {\r
30                         script = document.currentScript;\r
31                 }\r
32                 else {\r
33                         var all_scripts = document.getElementsByTagName('script');\r
34                         script = all_scripts[all_scripts.length - 1];\r
35                 }\r
36 \r
37                 if (script.getAttribute.length != 'undefined')\r
38                         script = script.src;\r
39                 else\r
40                         script = script.getAttribute('src', -1);\r
41 \r
42                 var link = document.createElement('a');\r
43                 link.setAttribute('href', script);\r
44 \r
45                 if(!link.protocol || !link.hostname) return null;\r
46 \r
47                 base = link.protocol;\r
48                 if(base) base += "//";\r
49                 base += link.hostname;\r
50 \r
51                 if(link.port) base += ":" + link.port;\r
52                 base += "/";\r
53 \r
54                 return base;\r
55         };\r
56 \r
57         if(typeof netdataServer != 'undefined')\r
58                 NETDATA.serverDefault = netdataServer + "/";\r
59         else\r
60                 NETDATA.serverDefault = NETDATA._scriptSource();\r
61 \r
62         NETDATA.jQuery       = NETDATA.serverDefault + 'lib/jquery-1.11.3.min.js';\r
63         NETDATA.peity_js     = NETDATA.serverDefault + 'lib/jquery.peity.min.js';\r
64         NETDATA.sparkline_js = NETDATA.serverDefault + 'lib/jquery.sparkline.min.js';\r
65         NETDATA.dygraph_js   = NETDATA.serverDefault + 'lib/dygraph-combined.js';\r
66         NETDATA.raphael_js   = NETDATA.serverDefault + 'lib/raphael-min.js';\r
67         NETDATA.morris_js    = NETDATA.serverDefault + 'lib/morris.min.js';\r
68         NETDATA.morris_css   = NETDATA.serverDefault + 'css/morris.css';\r
69         NETDATA.google_js    = 'https://www.google.com/jsapi';\r
70         NETDATA.colors  = [ '#3366CC', '#DC3912', '#FF9900', '#109618', '#990099', '#3B3EAC', '#0099C6', '#DD4477',\r
71                 '#66AA00', '#B82E2E', '#316395', '#994499', '#22AA99', '#AAAA11', '#6633CC', '#E67300', '#8B0707',\r
72                 '#329262', '#5574A6', '#3B3EAC' ];\r
73 \r
74         // ----------------------------------------------------------------------------------------------------------------\r
75         // the defaults for all charts\r
76 \r
77         NETDATA.chartDefaults = {\r
78                 host: NETDATA.serverDefault,    // the server to get data from\r
79                 width: 100,                                             // the chart width\r
80                 height: 20,                                             // the chart height\r
81                 library: 'peity',                               // the graphing library to use\r
82                 method: 'average',                              // the grouping method\r
83                 before: 0,                                              // panning\r
84                 after: -600,                                    // panning\r
85                 point_width: 1,                                 // the detail of the chart\r
86         }\r
87 \r
88         NETDATA.all_url = 'all2.js';\r
89         NETDATA.idle_between_charts = 50;\r
90         NETDATA.idle_between_loops = 100;\r
91         NETDATA.debug = 1;\r
92 \r
93         if(NETDATA.debug) console.log('welcome to NETDATA');\r
94 \r
95 \r
96         // ----------------------------------------------------------------------------------------------------------------\r
97         // Error Handling\r
98 \r
99         NETDATA.errorCodes = {\r
100                 100: { message: "Cannot load chart library", alert: true },\r
101                 101: { message: "Cannot load jQuery", alert: true },\r
102                 402: { message: "Chart library not found", alert: false },\r
103                 404: { message: "Chart not found", alert: false },\r
104         };\r
105         NETDATA.errorLast = {\r
106                 code: 0,\r
107                 message: "",\r
108                 datetime: 0,\r
109         };\r
110 \r
111         NETDATA.error = function(code, msg) {\r
112                 NETDATA.errorLast.code = code;\r
113                 NETDATA.errorLast.message = msg;\r
114                 NETDATA.errorLast.datetime = new Date().getTime();\r
115 \r
116                 console.log("ERROR " + code + ": " + NETDATA.errorCodes[code].message + ": " + msg);\r
117 \r
118                 if(NETDATA.errorCodes[code].alert)\r
119                         alert("ERROR " + code + ": " + NETDATA.errorCodes[code].message + ": " + msg);\r
120         }\r
121 \r
122         NETDATA.errorReset = function() {\r
123                 NETDATA.errorLast.code = 0;\r
124                 NETDATA.errorLast.message = "You are doing fine!";\r
125                 NETDATA.errorLast.datetime = 0;\r
126         }\r
127 \r
128         NETDATA.messageInABox = function(div, width, height, message) {\r
129                 div.innerHTML = '<table border="0"><tr><td width="' + width + '" height="' + height\r
130                         + '" valign="middle" align="center">'\r
131                         + message\r
132                         + '</td></tr></table>';\r
133         }\r
134 \r
135         // ----------------------------------------------------------------------------------------------------------------\r
136         // Load a script without jquery\r
137         // This is used to load jquery - after it is loaded, we use jquery\r
138 \r
139         NETDATA._loadjQuery = function(callback) {\r
140                 if(typeof jQuery == 'undefined') {\r
141                         var script = document.createElement('script');\r
142                         script.type = 'text/javascript';\r
143                         script.async = true;            \r
144                         script.src = NETDATA.jQuery;\r
145                         \r
146                         // script.onabort = onError;\r
147                         script.onerror = function(err, t) { NETDATA.error(101, NETDATA.jQuery); };\r
148                         if(typeof callback == "function")\r
149                                 script.onload = callback;\r
150                         \r
151                         var s = document.getElementsByTagName('script')[0];\r
152                         s.parentNode.insertBefore(script, s);\r
153                 }\r
154                 else if(typeof callback == "function")\r
155                         callback();\r
156         }\r
157 \r
158         NETDATA.generateDataURL = function(args) {\r
159                 // build the data URL\r
160                 var url = args.host + args.url;\r
161                 url += "&points=";\r
162                 url += args.points.toString();\r
163                 url += "&group=";\r
164                 url += args.method;\r
165                 url += "&after=";\r
166                 url += args.after || "0";\r
167                 url += "&before=";\r
168                 url += args.before || "0";\r
169                 url += "&options=" + NETDATA.chartLibraries[args.library].options + '|';\r
170                 url += (args.non_zero)?"nonzero":"";\r
171                 url += "&format=" + NETDATA.chartLibraries[args.library].format;\r
172 \r
173                 if(args.dimensions)\r
174                         url += "&dimensions=" + args.dimensions;\r
175 \r
176                 if(NETDATA.debug) console.log('generateDataURL(' + args + ') = ' + url );\r
177                 return url;\r
178         }\r
179 \r
180         NETDATA.loadCharts = function(targets, index, callback) {\r
181                 if(NETDATA.debug) console.log('loadCharts(<targets, ' + index + ')');\r
182 \r
183                 var target = targets.get(index);\r
184 \r
185                 if(target == null) {\r
186                         console.log('loaded all charts');\r
187                         callback();\r
188                 }\r
189                 else {\r
190                         var self = $(target);\r
191 \r
192                         if(!self.data('loaded')) {\r
193                                 var id = self.data('netdata');\r
194 \r
195                                 var host = self.data('host') || NETDATA.chartDefaults.host;\r
196                                 var width = self.data('width') || NETDATA.chartDefaults.width;\r
197                                 var height = self.data('height') || NETDATA.chartDefaults.height;\r
198                                 var method = self.data('method') || NETDATA.chartDefaults.method;\r
199                                 var after = self.data('after') || NETDATA.chartDefaults.after;\r
200                                 var before = self.data('before') || NETDATA.chartDefaults.before;\r
201                                 var host = self.data('host') || NETDATA.chartDefaults.host;\r
202                                 var library = self.data('chart-library') || NETDATA.chartDefaults.library;\r
203                                 var dimensions = self.data('dimensions') || null;\r
204 \r
205                                 if(typeof NETDATA.chartLibraries[library] == 'undefined') {\r
206                                         NETDATA.error(402, library);\r
207                                         NETDATA.messageInABox(target, width, height, 'chart library "' + library + '" is not found');\r
208                                         self.data('enabled', false);\r
209                                         NETDATA.loadCharts(targets, ++index, callback);\r
210                                 }\r
211                                 else {\r
212                                         var url = host + "/api/v1/chart?chart=" + id; \r
213 \r
214                                         $.ajax( {\r
215                                                 url:  url,\r
216                                                 crossDomain: true\r
217                                         })\r
218                                         .done(function(chart) {\r
219 \r
220                                                 var point_width = self.data('point-width') || NETDATA.chartLibraries[library].pixels;\r
221                                                 var points = self.data('points') || Math.round(width / point_width);\r
222 \r
223                                                 var url = NETDATA.generateDataURL({\r
224                                                         host: host,\r
225                                                         url: chart.data_url,\r
226                                                         dimensions: dimensions,\r
227                                                         library: library,\r
228                                                         method: method,\r
229                                                         before: before,\r
230                                                         points: points,\r
231                                                         after: after,\r
232                                                         non_zero: null\r
233                                                 });\r
234 \r
235                                                 // done processing of this DIV\r
236                                                 // store the processing result, in\r
237                                                 // 'data' sections in the DIV\r
238                                                 self\r
239                                                         .data('chart', chart)\r
240                                                         .data('chart-url', url)\r
241                                                         .data('last-updated', 0)\r
242                                                         .data('update-every', chart.update_every * 1000)\r
243                                                         .data('enabled', true);\r
244                                         })\r
245                                         .fail(function() {\r
246                                                 NETDATA.error(404, url);\r
247                                                 NETDATA.messageInABox(target, width, height, 'chart "' + id + '" not found on url "' + url + '"');\r
248                                                 self.data('enabled', false);\r
249                                         })\r
250                                         .always(function() {\r
251                                                 NETDATA.loadCharts(targets, ++index, callback);\r
252                                         });\r
253                                 }\r
254                         }\r
255                 }\r
256         }\r
257 \r
258         function netdataParsePageCharts() {\r
259                 if(NETDATA.debug) console.log('processing web page defined charts');\r
260 \r
261                 // targets\r
262                 // a list of all DIVs containing netdata charts\r
263 \r
264                 var targets = $('div[data-netdata]')\r
265                 .bind('create', function(event, data) {\r
266                         var self = $(this);\r
267                         var lib = self.data('chart-library') || 'dygraph';\r
268                         var method = lib + 'ChartCreate';\r
269                         \r
270                         console.log('Calling ' + method + '()');\r
271                         NETDATA[method].apply(this, arguments);\r
272                 })\r
273                 .bind('update', function() {\r
274                         var self = $(this);\r
275                         var lib = self.data('chart-library') || 'dygraph';\r
276                         var method = lib + 'ChartUpdate';\r
277                         \r
278                         console.log('Calling ' + method + '()');\r
279                         NETDATA[method].apply(this, arguments);\r
280                 });\r
281 \r
282                 NETDATA.loadCharts(targets, 0, function() {\r
283                         // done processing all netdata DIVs in this page\r
284                         // call the refresh handler\r
285                         netdataRefreshTargets(targets, 0);\r
286                 });\r
287         }\r
288 \r
289         // ----------------------------------------------------------------------------------------------------------------\r
290         // Charts Libraries Registration\r
291 \r
292         NETDATA.chartLibraries = {};\r
293 \r
294         NETDATA.registerChartLibrary = function(library, url, format, options, min_pixels_per_point) {\r
295                 console.log("registering chart library: " + library);\r
296 \r
297                 NETDATA.chartLibraries[library] = {\r
298                         initialized: new Date().getTime(),\r
299                         url: url,\r
300                         format: format,\r
301                         options: options,\r
302                         pixels: min_pixels_per_point\r
303                 };\r
304 \r
305                 console.log(NETDATA.chartLibraries);\r
306         }\r
307 \r
308         // ----------------------------------------------------------------------------------------------------------------\r
309 \r
310         //var chart = function() {\r
311         //}\r
312 \r
313         //chart.prototype.color = function() {\r
314         //      return 'red';\r
315         //}\r
316 \r
317         //var c = new chart();\r
318         //c.color();\r
319 \r
320         function netdataDownloadChartData(callback) {\r
321                 var self = $(this);\r
322                 var last = self.data('last-updated') || 0;\r
323                 var every = self.data('update-every') || 1;\r
324 \r
325                 // check if this chart has to be refreshed now\r
326                 var now = new Date().getTime();\r
327                 if(last + every > now) {\r
328                         if(typeof callback == 'function')\r
329                                 callback();\r
330                 }\r
331                 else {\r
332                         var url = self.data('chart-url');\r
333 \r
334                         if(NETDATA.debug) console.log('netdataDownloadChartData(): downloading ' + url);\r
335 \r
336                         $.ajax( {\r
337                                 url: url,\r
338                                 crossDomain: true\r
339                         })\r
340                         .then(function(data) {\r
341                                 //var result = $.map(data.rows, function(item) {\r
342                                         // get from the 3rd column the 'v' member\r
343                                         //return item.c[3].v;\r
344                                 //});\r
345                                 \r
346                                 // since we downloaded the data\r
347                                 // update the last-updated time to prevent\r
348                                 // another download too soon\r
349                                 self.data('last-updated', new Date().getTime());\r
350 \r
351                                 // render it\r
352                                 var created = self.data('created');\r
353                                 self.trigger((created ? 'update' : 'create'), [data]).data('created', true)\r
354                         })\r
355                         .fail(function() {\r
356                                 console.log('failed to download chart data');\r
357                         })\r
358                         .always(function() {\r
359                                 var last = self.data('last-updated');\r
360                                 var now = new Date().getTime();\r
361                                 var dt = now - last;\r
362                                 self.data('refresh-dt', dt);\r
363 \r
364                                 var element_name = self.data('dt-element-name') || null;\r
365                                 if(element_name) {\r
366                                         var element = document.getElementById(element_name) || null;\r
367                                         if(element) {\r
368                                                 element.innerHTML = dt.toString();\r
369                                         }\r
370                                 }\r
371 \r
372                                 if(typeof callback == 'function')\r
373                                         callback();\r
374                         });\r
375                 }\r
376         };\r
377 \r
378         function netdataRefreshTargets(targets, index) {\r
379                 // if(NETDATA.debug) console.log('netdataRefreshTargets(<targets, ' + index + ')');\r
380 \r
381                 var target = targets.get(index);\r
382 \r
383                 if(target == null) {\r
384                         console.log('restart');\r
385 \r
386                         // finished, restart\r
387                         setTimeout(function() {\r
388                                 netdataRefreshTargets(targets, 0);\r
389                         }, NETDATA.idle_between_loops);\r
390                 }\r
391                 else {\r
392                         var self = $(target);\r
393 \r
394                         if(!self.data('enabled')) {\r
395                                 netdataRefreshTargets(targets, ++index);\r
396                         }\r
397                         else {\r
398                                 setTimeout(function() {\r
399                                         netdataDownloadChartData.call(target, function() {\r
400                                                 netdataRefreshTargets(targets, ++index);\r
401                                         });\r
402                                 }, NETDATA.idle_between_charts);\r
403                         }\r
404                 }\r
405         }\r
406 \r
407         NETDATA.guid = function() {\r
408                 function s4() {\r
409                         return Math.floor((1 + Math.random()) * 0x10000)\r
410                                         .toString(16)\r
411                                         .substring(1);\r
412                         }\r
413 \r
414                         return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();\r
415         }\r
416 \r
417         // ----------------------------------------------------------------------------------------------------------------\r
418         // piety\r
419 \r
420         NETDATA.peityInitialize = function(callback) {\r
421                 if(typeof netdataStopPeity == 'undefined') {\r
422                         $.getScript(NETDATA.peity_js)\r
423                                 .done(function() {\r
424                                         NETDATA.registerChartLibrary('peity', NETDATA.peity_js, 'ssvcomma', 'null2zero|flip|min2max', 2);\r
425                                 })\r
426                                 .fail(function() {\r
427                                         NETDATA.error(100, NETDATA.peity_js);\r
428                                 })\r
429                                 .always(function() {\r
430                                         if(typeof callback == "function")\r
431                                                 callback();\r
432                                 })\r
433                 }\r
434                 else if(typeof callback == "function")\r
435                         callback();\r
436         };\r
437 \r
438         NETDATA.peityChartUpdate = function(event, data) {\r
439                 var self = $(this);\r
440                 var instance = self.html(data).not('[data-created]');\r
441                 instance.change();\r
442         }\r
443 \r
444         NETDATA.peityChartCreate = function(event, data) {\r
445                 var self = $(this);\r
446                 var width = self.data('width') || NETDATA.chartDefaults.width;\r
447                 var height = self.data('height') || NETDATA.chartDefaults.height;\r
448                 var instance = self.html(data).not('[data-created]');\r
449 \r
450                 instance.peity('line', {\r
451                         width: width,\r
452                         height: height\r
453                 })\r
454                 .data('created', true);\r
455         }\r
456 \r
457         // ----------------------------------------------------------------------------------------------------------------\r
458         // sparkline\r
459 \r
460         NETDATA.sparklineInitialize = function(callback) {\r
461                 if(typeof netdataStopSparkline == 'undefined') {\r
462                         $.getScript(NETDATA.sparkline_js)\r
463                                 .done(function() {\r
464                                         NETDATA.registerChartLibrary('sparkline', NETDATA.sparkline_js, 'array', 'flip|min2max', 2);\r
465                                 })\r
466                                 .fail(function() {\r
467                                         NETDATA.error(100, NETDATA.sparkline_js);\r
468                                 })\r
469                                 .always(function() {\r
470                                         if(typeof callback == "function")\r
471                                                 callback();\r
472                                 })\r
473                 }\r
474                 else if(typeof callback == "function")\r
475                         callback();\r
476         };\r
477 \r
478         NETDATA.sparklineChartUpdate = function(event, data) {\r
479                 var self = $(this);\r
480                 var options = self.data('sparkline-options');\r
481                 self.sparkline(data, options);\r
482         }\r
483 \r
484         NETDATA.sparklineChartCreate = function(event, data) {\r
485                 var self = $(this);\r
486                 var chart = self.data('chart');\r
487                 var width = self.data('width') || NETDATA.chartDefaults.width;\r
488                 var height = self.data('height') || NETDATA.chartDefaults.height;\r
489                 var type = self.data('sparkline-type') || 'line';\r
490                 var lineColor = self.data('sparkline-lineColor') || undefined;\r
491                 var fillColor = self.data('sparkline-fillColor') || (chart.chart_type == 'line')?'#FFF':undefined;\r
492                 var chartRangeMin = self.data('sparkline-chartRangeMin') || undefined;\r
493                 var chartRangeMax = self.data('sparkline-chartRangeMax') || undefined;\r
494                 var composite = self.data('sparkline-composite') || undefined;\r
495                 var enableTagOptions = self.data('sparkline-enableTagOptions') || undefined;\r
496                 var tagOptionPrefix = self.data('sparkline-tagOptionPrefix') || undefined;\r
497                 var tagValuesAttribute = self.data('sparkline-tagValuesAttribute') || undefined;\r
498                 var disableHiddenCheck = self.data('sparkline-disableHiddenCheck') || undefined;\r
499                 var defaultPixelsPerValue = self.data('sparkline-defaultPixelsPerValue') || undefined;\r
500                 var spotColor = self.data('sparkline-spotColor') || undefined;\r
501                 var minSpotColor = self.data('sparkline-minSpotColor') || undefined;\r
502                 var maxSpotColor = self.data('sparkline-maxSpotColor') || undefined;\r
503                 var spotRadius = self.data('sparkline-spotRadius') || undefined;\r
504                 var valueSpots = self.data('sparkline-valueSpots') || undefined;\r
505                 var highlightSpotColor = self.data('sparkline-highlightSpotColor') || undefined;\r
506                 var highlightLineColor = self.data('sparkline-highlightLineColor') || undefined;\r
507                 var lineWidth = self.data('sparkline-lineWidth') || undefined;\r
508                 var normalRangeMin = self.data('sparkline-normalRangeMin') || undefined;\r
509                 var normalRangeMax = self.data('sparkline-normalRangeMax') || undefined;\r
510                 var drawNormalOnTop = self.data('sparkline-drawNormalOnTop') || undefined;\r
511                 var xvalues = self.data('sparkline-xvalues') || undefined;\r
512                 var chartRangeClip = self.data('sparkline-chartRangeClip') || undefined;\r
513                 var xvalues = self.data('sparkline-xvalues') || undefined;\r
514                 var chartRangeMinX = self.data('sparkline-chartRangeMinX') || undefined;\r
515                 var chartRangeMaxX = self.data('sparkline-chartRangeMaxX') || undefined;\r
516                 var disableInteraction = self.data('sparkline-disableInteraction') || false;\r
517                 var disableTooltips = self.data('sparkline-disableTooltips') || false;\r
518                 var disableHighlight = self.data('sparkline-disableHighlight') || false;\r
519                 var highlightLighten = self.data('sparkline-highlightLighten') || 1.4;\r
520                 var highlightColor = self.data('sparkline-highlightColor') || undefined;\r
521                 var tooltipContainer = self.data('sparkline-tooltipContainer') || undefined;\r
522                 var tooltipClassname = self.data('sparkline-tooltipClassname') || undefined;\r
523                 var tooltipFormat = self.data('sparkline-tooltipFormat') || undefined;\r
524                 var tooltipPrefix = self.data('sparkline-tooltipPrefix') || undefined;\r
525                 var tooltipSuffix = self.data('sparkline-tooltipSuffix') || ' ' + chart.units;\r
526                 var tooltipSkipNull = self.data('sparkline-tooltipSkipNull') || true;\r
527                 var tooltipValueLookups = self.data('sparkline-tooltipValueLookups') || undefined;\r
528                 var tooltipFormatFieldlist = self.data('sparkline-tooltipFormatFieldlist') || undefined;\r
529                 var tooltipFormatFieldlistKey = self.data('sparkline-tooltipFormatFieldlistKey') || undefined;\r
530                 var numberFormatter = self.data('sparkline-numberFormatter') || function(n){ return n.toFixed(2); };\r
531                 var numberDigitGroupSep = self.data('sparkline-numberDigitGroupSep') || undefined;\r
532                 var numberDecimalMark = self.data('sparkline-numberDecimalMark') || undefined;\r
533                 var numberDigitGroupCount = self.data('sparkline-numberDigitGroupCount') || undefined;\r
534                 var animatedZooms = self.data('sparkline-animatedZooms') || false;\r
535  \r
536                 var options = {\r
537                         type: type,\r
538                         lineColor: lineColor,\r
539                         fillColor: fillColor,\r
540                         chartRangeMin: chartRangeMin,\r
541                         chartRangeMax: chartRangeMax,\r
542                         composite: composite,\r
543                         enableTagOptions: enableTagOptions,\r
544                         tagOptionPrefix: tagOptionPrefix,\r
545                         tagValuesAttribute: tagValuesAttribute,\r
546                         disableHiddenCheck: disableHiddenCheck,\r
547                         defaultPixelsPerValue: defaultPixelsPerValue,\r
548                         spotColor: spotColor,\r
549                         minSpotColor: minSpotColor,\r
550                         maxSpotColor: maxSpotColor,\r
551                         spotRadius: spotRadius,\r
552                         valueSpots: valueSpots,\r
553                         highlightSpotColor: highlightSpotColor,\r
554                         highlightLineColor: highlightLineColor,\r
555                         lineWidth: lineWidth,\r
556                         normalRangeMin: normalRangeMin,\r
557                         normalRangeMax: normalRangeMax,\r
558                         drawNormalOnTop: drawNormalOnTop,\r
559                         xvalues: xvalues,\r
560                         chartRangeClip: chartRangeClip,\r
561                         chartRangeMinX: chartRangeMinX,\r
562                         chartRangeMaxX: chartRangeMaxX,\r
563                         disableInteraction: disableInteraction,\r
564                         disableTooltips: disableTooltips,\r
565                         disableHighlight: disableHighlight,\r
566                         highlightLighten: highlightLighten,\r
567                         highlightColor: highlightColor,\r
568                         tooltipContainer: tooltipContainer,\r
569                         tooltipClassname: tooltipClassname,\r
570                         tooltipChartTitle: chart.title,\r
571                         tooltipFormat: tooltipFormat,\r
572                         tooltipPrefix: tooltipPrefix,\r
573                         tooltipSuffix: tooltipSuffix,\r
574                         tooltipSkipNull: tooltipSkipNull,\r
575                         tooltipValueLookups: tooltipValueLookups,\r
576                         tooltipFormatFieldlist: tooltipFormatFieldlist,\r
577                         tooltipFormatFieldlistKey: tooltipFormatFieldlistKey,\r
578                         numberFormatter: numberFormatter,\r
579                         numberDigitGroupSep: numberDigitGroupSep,\r
580                         numberDecimalMark: numberDecimalMark,\r
581                         numberDigitGroupCount: numberDigitGroupCount,\r
582                         animatedZooms: animatedZooms,\r
583                         width: width,\r
584                         height: height\r
585                 };\r
586 \r
587                 var uuid = NETDATA.guid();\r
588                 this.innerHTML = '<div style="display: inline-block; position: relative;" id="' + uuid + '"></div>';\r
589                 var div = document.getElementById(uuid);\r
590 \r
591                 self.sparkline(data, options);\r
592                 self.data('sparkline-options', options)\r
593                 .data('uuid', uuid)\r
594                 .data('created', true);\r
595         };\r
596 \r
597         // ----------------------------------------------------------------------------------------------------------------\r
598         // dygraph\r
599 \r
600         NETDATA.dygraphAllCharts = [];\r
601         NETDATA.dygraphInitSync = function(callback) {\r
602                 //$.getScript(NETDATA.serverDefault + 'dygraph-synchronizer.js')\r
603                 //      .always(function() {\r
604                                 if(typeof callback == "function")\r
605                                         callback();\r
606                 //      })\r
607         }\r
608 \r
609         NETDATA.dygraphSync = null;\r
610         NETDATA.dygraphSyncAll = function() {\r
611                 if(NETDATA.dygraphSync) {\r
612                         NETDATA.dygraphSync.detach();\r
613                         NETDATA.dygraphSync = null;\r
614                 }\r
615 \r
616                 NETDATA.dygraphSync = Dygraph.synchronize(NETDATA.dygraphAllCharts, {\r
617                         selection: true,\r
618                         zoom: false\r
619                 });\r
620         }\r
621 \r
622         NETDATA.dygraphInitialize = function(callback) {\r
623                 if(typeof netdataStopDygraph == 'undefined') {\r
624                         $.getScript(NETDATA.dygraph_js)\r
625                                 .done(function() {\r
626                                         NETDATA.registerChartLibrary('dygraph', NETDATA.dygraph_js, 'json', 'ms|flip', 2);\r
627                                 })\r
628                                 .fail(function() {\r
629                                         NETDATA.error(100, NETDATA.dygraph_js);\r
630                                 })\r
631                                 .always(function() {\r
632                                         NETDATA.dygraphInitSync(callback);\r
633                                 })\r
634                 }\r
635                 else if(typeof callback == "function")\r
636                         callback();\r
637         };\r
638 \r
639         NETDATA.dygraphChartUpdate = function(event, data) {\r
640                 var self = $(this);\r
641                 var dygraph = self.data('dygraph-instance');\r
642 \r
643                 if(typeof data.update_every != 'undefined')\r
644                         self.data('update-every', data.update_every * 1000);\r
645 \r
646                 if(dygraph != null) {\r
647                         console.log('updating dygraphs');\r
648                         dygraph.updateOptions( { 'file': data.data, 'labels': data.labels } );\r
649                 }\r
650                 else\r
651                         console.log('not updating dygraphs');\r
652         };\r
653  \r
654         NETDATA.dygraphChartCreate = function(event, data) {\r
655                 var self = $(this);\r
656                 var width = self.data('width') || NETDATA.chartDefaults.width;\r
657                 var height = self.data('height') || NETDATA.chartDefaults.height;\r
658                 var chart = self.data('chart');\r
659                 var title = self.data('dygraph-title') || chart.title;\r
660                 var titleHeight = self.data('dygraph-titleHeight') || 20;\r
661                 var labelsDiv = self.data('dygraph-labelsDiv') || undefined;\r
662                 var connectSeparatedPoints = self.data('dygraph-connectSeparatedPoints') || false;\r
663                 var yLabelWidth = self.data('dygraph-yLabelWidth') || 12;\r
664                 var stackedGraph = self.data('dygraph-stackedGraph') || (chart.chart_type == 'stacked')?true:false;\r
665                 var stackedGraphNaNFill = self.data('dygraph-stackedGraphNaNFill') || 'none';\r
666                 var hideOverlayOnMouseOut = self.data('dygraph-hideOverlayOnMouseOut') || true;\r
667                 var fillGraph = self.data('dygraph-fillGraph') || (chart.chart_type == 'area')?true:false;\r
668                 var drawPoints = self.data('dygraph-drawPoints') || false;\r
669                 var labelsDivStyles = self.data('dygraph-labelsDivStyles') || { 'fontSize':'10' };\r
670                 var labelsDivWidth = self.data('dygraph-labelsDivWidth') || 250;\r
671                 var labelsSeparateLines = self.data('dygraph-labelsSeparateLines') || false;\r
672                 var labelsShowZeroValues = self.data('dygraph-labelsShowZeroValues') || true;\r
673                 var legend = self.data('dygraph-legend') || 'onmouseover';\r
674                 var showLabelsOnHighlight = self.data('dygraph-showLabelsOnHighlight') || true;\r
675                 var gridLineColor = self.data('dygraph-gridLineColor') || '#EEE';\r
676                 var axisLineColor = self.data('dygraph-axisLineColor') || '#EEE';\r
677                 var maxNumberWidth = self.data('dygraph-maxNumberWidth') || 8;\r
678                 var sigFigs = self.data('dygraph-sigFigs') || null;\r
679                 var digitsAfterDecimal = self.data('dygraph-digitsAfterDecimal') || 2;\r
680                 var axisLabelFontSize = self.data('dygraph-axisLabelFontSize') || 10;\r
681                 var axisLineWidth = self.data('dygraph-axisLineWidth') || 0.3;\r
682                 var drawAxis = self.data('dygraph-drawAxis') || true;\r
683                 var strokeWidth = self.data('dygraph-strokeWidth') || 1.0;\r
684                 var drawGapEdgePoints = self.data('dygraph-drawGapEdgePoints') || true;\r
685                 var colors = self.data('dygraph-colors') || NETDATA.colors;\r
686                 var pointSize = self.data('dygraph-pointSize') || 1;\r
687                 var stepPlot = self.data('dygraph-stepPlot') || false;\r
688                 var strokeBorderColor = self.data('dygraph-strokeBorderColor') || 'white';\r
689                 var strokeBorderWidth = self.data('dygraph-strokeBorderWidth') || (chart.chart_type == 'stacked')?1.0:0.0;\r
690                 var strokePattern = self.data('dygraph-strokePattern') || undefined;\r
691                 var highlightCircleSize = self.data('dygraph-highlightCircleSize') || 3;\r
692                 var highlightSeriesOpts = self.data('dygraph-highlightSeriesOpts') || { strokeWidth: 1.5 };\r
693                 var highlightSeriesBackgroundAlpha = self.data('dygraph-highlightSeriesBackgroundAlpha') || (chart.chart_type == 'stacked')?0.7:0.5;\r
694                 var pointClickCallback = self.data('dygraph-pointClickCallback') || undefined;\r
695                 var showRangeSelector = self.data('dygraph-showRangeSelector') || false;\r
696                 var showRoller = self.data('dygraph-showRoller') || false;\r
697                 var valueFormatter = self.data('dygraph-valueFormatter') || undefined; //function(x){ return x.toFixed(2); };\r
698                 var rightGap = self.data('dygraph-rightGap') || 5;\r
699                 var drawGrid = self.data('dygraph-drawGrid') || true;\r
700                 var drawXGrid = self.data('dygraph-drawXGrid') || undefined;\r
701                 var drawYGrid = self.data('dygraph-drawYGrid') || undefined;\r
702                 var gridLinePattern = self.data('dygraph-gridLinePattern') || null;\r
703                 var gridLineWidth = self.data('dygraph-gridLineWidth') || 0.3;\r
704   \r
705                 var options = {\r
706                         title: title,\r
707                         titleHeight: titleHeight,\r
708                         ylabel: chart.units,\r
709                         yLabelWidth: yLabelWidth,\r
710                         connectSeparatedPoints: connectSeparatedPoints,\r
711                         drawPoints: drawPoints,\r
712                         fillGraph: fillGraph,\r
713                         stackedGraph: stackedGraph,\r
714                         stackedGraphNaNFill: stackedGraphNaNFill,\r
715                         drawGrid: drawGrid,\r
716                         drawXGrid: drawXGrid,\r
717                         drawYGrid: drawYGrid,\r
718                         gridLinePattern: gridLinePattern,\r
719                         gridLineWidth: gridLineWidth,\r
720                         gridLineColor: gridLineColor,\r
721                         axisLineColor: axisLineColor,\r
722                         axisLineWidth: axisLineWidth,\r
723                         drawAxis: drawAxis,\r
724                         hideOverlayOnMouseOut: hideOverlayOnMouseOut,\r
725                         labelsDiv: labelsDiv,\r
726                         labelsDivStyles: labelsDivStyles,\r
727                         labelsDivWidth: labelsDivWidth,\r
728                         labelsSeparateLines: labelsSeparateLines,\r
729                         labelsShowZeroValues: labelsShowZeroValues,\r
730                         labelsKMB: false,\r
731                         labelsKMG2: false,\r
732                         legend: legend,\r
733                         showLabelsOnHighlight: showLabelsOnHighlight,\r
734                         maxNumberWidth: maxNumberWidth,\r
735                         sigFigs: sigFigs,\r
736                         digitsAfterDecimal: digitsAfterDecimal,\r
737                         axisLabelFontSize: axisLabelFontSize,\r
738                         colors: colors,\r
739                         strokeWidth: strokeWidth,\r
740                         drawGapEdgePoints: drawGapEdgePoints,\r
741                         pointSize: pointSize,\r
742                         stepPlot: stepPlot,\r
743                         strokeBorderColor: strokeBorderColor,\r
744                         strokeBorderWidth: strokeBorderWidth,\r
745                         strokePattern: strokePattern,\r
746                         highlightCircleSize: highlightCircleSize,\r
747                         highlightSeriesOpts: highlightSeriesOpts,\r
748                         highlightSeriesBackgroundAlpha: highlightSeriesBackgroundAlpha,\r
749                         pointClickCallback: pointClickCallback,\r
750                         showRangeSelector: showRangeSelector,\r
751                         showRoller: showRoller,\r
752                         valueFormatter: valueFormatter,\r
753                         rightGap: rightGap,\r
754                         width: width,\r
755                         height: height,\r
756                         labels: data.labels,\r
757                         axes: {\r
758                                 x: {\r
759                                         pixelsPerLabel: 50,\r
760                                         ticker: Dygraph.dateTicker,\r
761                                         axisLabelFormatter: function (d, gran) {\r
762                                                 return Dygraph.zeropad(d.getHours()) + ":" + Dygraph.zeropad(d.getMinutes()) + ":" + Dygraph.zeropad(d.getSeconds());\r
763                                         },\r
764                                         valueFormatter :function (ms) {\r
765                                                 var d = new Date(ms);\r
766                                                 return Dygraph.zeropad(d.getHours()) + ":" + Dygraph.zeropad(d.getMinutes()) + ":" + Dygraph.zeropad(d.getSeconds());\r
767                                         }\r
768                                 },\r
769                                 y: {\r
770                                         pixelsPerLabel: 15,\r
771                                 }\r
772                         }\r
773                 };\r
774 \r
775                 var uuid = NETDATA.guid();\r
776                 self.html('<div id="' + uuid + '"></div>');\r
777 \r
778                 var dchart = new Dygraph(document.getElementById(uuid),\r
779                         data.data, options);\r
780 \r
781                 self.data('dygraph-instance', dchart)\r
782                 .data('dygraph-options', options)\r
783                 .data('uuid', uuid)\r
784                 .data('created', true);\r
785 \r
786                 //NETDATA.dygraphAllCharts.push(dchart);\r
787                 //if(NETDATA.dygraphAllCharts.length > 1)\r
788                 //      NETDATA.dygraphSyncAll();\r
789         };\r
790 \r
791         // ----------------------------------------------------------------------------------------------------------------\r
792         // morris\r
793 \r
794         NETDATA.morrisInitialize = function(callback) {\r
795                 if(typeof netdataStopMorris == 'undefined') {\r
796                         var fileref = document.createElement("link");\r
797                         fileref.setAttribute("rel", "stylesheet");\r
798                         fileref.setAttribute("type", "text/css");\r
799                         fileref.setAttribute("href", NETDATA.morris_css);\r
800 \r
801                         if (typeof fileref != "undefined")\r
802                                 document.getElementsByTagName("head")[0].appendChild(fileref);\r
803 \r
804                         $.getScript(NETDATA.morris_js)\r
805                                 .done(function() {\r
806                                         NETDATA.registerChartLibrary('morris', NETDATA.morris_js, 'json', 'objectrows|ms', 10);\r
807                                 })\r
808                                 .fail(function() {\r
809                                         NETDATA.error(100, NETDATA.morris_js);\r
810                                 })\r
811                                 .always(function() {\r
812                                         if(typeof callback == "function")\r
813                                                 callback();\r
814                                 })\r
815                 }\r
816                 else if(typeof callback == "function")\r
817                         callback();\r
818         };\r
819 \r
820         NETDATA.morrisChartUpdate = function(event, data) {\r
821                 var self = $(this);\r
822                 var width = self.data('width') || NETDATA.chartDefaults.width;\r
823                 var height = self.data('height') || NETDATA.chartDefaults.height;\r
824                 var morris = self.data('morris-instance');\r
825 \r
826                 if(typeof data.update_every != 'undefined')\r
827                         self.data('update-every', data.update_every * 1000);\r
828 \r
829                 if(morris != null) {\r
830                         console.log('updating morris');\r
831                         morris.setData(data.data);\r
832                 }\r
833                 else\r
834                         console.log('not updating morris');\r
835         };\r
836 \r
837         NETDATA.morrisChartCreate = function(event, data) {\r
838                 var self = $(this);\r
839                 var width = self.data('width') || NETDATA.chartDefaults.width;\r
840                 var height = self.data('height') || NETDATA.chartDefaults.height;\r
841                 var chart = self.data('chart');\r
842                 \r
843                 self.html('<div id="morris-' + chart.id + '" style="width: ' + width + 'px; height: ' + height + 'px;"></div>');\r
844 \r
845                 // remove the 'time' element from the labels\r
846                 data.labels.splice(0, 1);\r
847 \r
848                 var options = {\r
849                                 element: 'morris-' + chart.id,\r
850                                 data: data.data,\r
851                                 xkey: 'time',\r
852                                 ykeys: data.labels,\r
853                                 labels: data.labels,\r
854                                 lineWidth: 2,\r
855                                 pointSize: 2,\r
856                                 smooth: true,\r
857                                 hideHover: 'auto',\r
858                                 parseTime: true,\r
859                                 continuousLine: false,\r
860                                 behaveLikeLine: false,\r
861                                 width: width,\r
862                                 height: height\r
863                 };\r
864 \r
865                 var morris;\r
866                 if(chart.chart_type == 'line')\r
867                         morris = new Morris.Line(options);\r
868 \r
869                 else if(chart.chart_type == 'area') {\r
870                         options.behaveLikeLine = true;\r
871                         morris = new Morris.Area(options);\r
872                 }\r
873                 else // stacked\r
874                         morris = new Morris.Area(options);\r
875 \r
876                 self.data('morris-instance', morris)\r
877                 .data('created', true);\r
878         };\r
879 \r
880         // ----------------------------------------------------------------------------------------------------------------\r
881         // raphael\r
882 \r
883         NETDATA.raphaelInitialize = function(callback) {\r
884                 if(typeof netdataStopRaphael == 'undefined') {\r
885                         $.getScript(NETDATA.raphael_js)\r
886                                 .done(function() {\r
887                                         NETDATA.registerChartLibrary('raphael', NETDATA.raphael_js, 'json', 'flip|min2max', 1);\r
888                                 })\r
889                                 .fail(function() {\r
890                                         NETDATA.error(100, NETDATA.raphael_js);\r
891                                 })\r
892                                 .always(function() {\r
893                                         if(typeof callback == "function")\r
894                                                 callback();\r
895                                 })\r
896                 }\r
897                 else if(typeof callback == "function")\r
898                         callback();\r
899         };\r
900 \r
901         NETDATA.raphaelChartUpdate = function(event, data) {\r
902                 var self = $(this);\r
903                 var width = self.data('width') || NETDATA.chartDefaults.width;\r
904                 var height = self.data('height') || NETDATA.chartDefaults.height;\r
905                 \r
906                 self.raphael(data, {\r
907                         width: width,\r
908                         height: height\r
909                 })\r
910         };\r
911 \r
912         NETDATA.raphaelChartCreate = function(event, data) {\r
913                 var self = $(this);\r
914                 var width = self.data('width') || NETDATA.chartDefaults.width;\r
915                 var height = self.data('height') || NETDATA.chartDefaults.height;\r
916                 \r
917                 self.raphael(data, {\r
918                         width: width,\r
919                         height: height\r
920                 })\r
921                 .data('created', true);\r
922         };\r
923 \r
924         // ----------------------------------------------------------------------------------------------------------------\r
925         // google charts\r
926 \r
927         NETDATA.googleInitialize = function(callback) {\r
928                 if(typeof netdataStopGoogleCharts == 'undefined' && typeof google != 'undefined') {\r
929                         NETDATA.registerChartLibrary('google', NETDATA.google_js, 'datatable', '', 3);\r
930                         if(typeof callback == "function")\r
931                                 callback();\r
932                 }\r
933                 else if(typeof callback == "function")\r
934                         callback();\r
935         };\r
936 \r
937         NETDATA.googleChartUpdate = function(event, data) {\r
938                 var self = $(this);\r
939                 var width = self.data('width') || NETDATA.chartDefaults.width;\r
940                 var height = self.data('height') || NETDATA.chartDefaults.height;\r
941                 var gchart = self.data('google-instance');\r
942                 var options = self.data('google-options');\r
943 \r
944                 if(typeof data.update_every != 'undefined')\r
945                         self.data('update-every', data.update_every * 1000);\r
946 \r
947                 var datatable = new google.visualization.DataTable(data);\r
948 \r
949                 gchart.draw(datatable, options);\r
950         };\r
951 \r
952         NETDATA.googleChartCreate = function(event, data) {\r
953                 var self = $(this);\r
954                 var width = self.data('width') || NETDATA.chartDefaults.width;\r
955                 var height = self.data('height') || NETDATA.chartDefaults.height;\r
956                 var chart = self.data('chart');\r
957                 \r
958                 var datatable = new google.visualization.DataTable(data);\r
959                 var gchart;\r
960 \r
961                 var options = {\r
962                         width: width,\r
963                         height: height,\r
964                         lineWidth: 1,\r
965                         title: chart.title,\r
966                         fontSize: 11,\r
967                         hAxis: {\r
968                         //      title: "Time of Day",\r
969                         //      format:'HH:mm:ss',\r
970                                 viewWindowMode: 'maximized',\r
971                                 slantedText: false,\r
972                                 format:'HH:mm:ss',\r
973                                 textStyle: {\r
974                                         fontSize: 9\r
975                                 },\r
976                                 gridlines: {\r
977                                         color: '#EEE'\r
978                                 }\r
979                         },\r
980                         vAxis: {\r
981                                 title: chart.units,\r
982                                 viewWindowMode: 'pretty',\r
983                                 minValue: -0.1,\r
984                                 maxValue: 0.1,\r
985                                 direction: 1,\r
986                                 textStyle: {\r
987                                         fontSize: 9\r
988                                 },\r
989                                 gridlines: {\r
990                                         color: '#EEE'\r
991                                 }\r
992                         },\r
993                         chartArea: {\r
994                                 width: '65%',\r
995                                 height: '80%'\r
996                         },\r
997                         focusTarget: 'category',\r
998                         annotation: {\r
999                                 '1': {\r
1000                                         style: 'line'\r
1001                                 }\r
1002                         },\r
1003                         pointsVisible: 0,\r
1004                         titlePosition: 'out',\r
1005                         titleTextStyle: {\r
1006                                 fontSize: 11\r
1007                         },\r
1008                         tooltip: {\r
1009                                 isHtml: false,\r
1010                                 ignoreBounds: true,\r
1011                                 textStyle: {\r
1012                                         fontSize: 9\r
1013                                 }\r
1014                         },\r
1015                         curveType: 'function',\r
1016                         areaOpacity: 0.3,\r
1017                         isStacked: false\r
1018                 };\r
1019 \r
1020                 switch(chart.chart_type) {\r
1021                         case "area":\r
1022                                 options.vAxis.viewWindowMode = 'maximized';\r
1023                                 gchart = new google.visualization.AreaChart(this);\r
1024                                 break;\r
1025 \r
1026                         case "stacked":\r
1027                                 options.isStacked = true;\r
1028                                 options.areaOpacity = 0.85;\r
1029                                 options.vAxis.viewWindowMode = 'maximized';\r
1030                                 options.vAxis.minValue = null;\r
1031                                 options.vAxis.maxValue = null;\r
1032                                 gchart = new google.visualization.AreaChart(this);\r
1033                                 break;\r
1034 \r
1035                         default:\r
1036                         case "line":\r
1037                                 options.lineWidth = 2;\r
1038                                 gchart = new google.visualization.LineChart(this);\r
1039                                 break;\r
1040                 }\r
1041 \r
1042                 gchart.draw(datatable, options);\r
1043 \r
1044                 self.data('google-instance', gchart)\r
1045                 .data('google-options', options)\r
1046                 .data('created', true);\r
1047         };\r
1048 \r
1049         // ----------------------------------------------------------------------------------------------------------------\r
1050         // load all libraries and initialize\r
1051 \r
1052         NETDATA.errorReset();\r
1053 \r
1054         NETDATA._loadjQuery(function() {                \r
1055                 NETDATA.raphaelInitialize(function() {\r
1056                         NETDATA.morrisInitialize(function() {\r
1057                                 NETDATA.peityInitialize(function() {\r
1058                                         NETDATA.sparklineInitialize(function() {\r
1059                                                 NETDATA.dygraphInitialize(function() {\r
1060                                                         NETDATA.googleInitialize(function() {\r
1061                                                                 netdataParsePageCharts();\r
1062                                                         }) // google\r
1063                                                 }) // dygraph.js\r
1064                                         }) // sparkline.js\r
1065                                 }) // piety.js\r
1066                         }) // morris.js\r
1067                 }) // raphael.js\r
1068         });\r
1069 \r
1070 })(window);\r
1071 \r