1 // You can set the following variables before loading this script:
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
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
16 // fix IE bug with console
17 if(!window.console){ window.console = {log: function(){} }; }
19 var NETDATA = window.NETDATA || {};
21 // ----------------------------------------------------------------------------------------------------------------
22 // Detect the netdata server
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;
29 if(typeof document.currentScript != 'undefined') {
30 script = document.currentScript;
33 var all_scripts = document.getElementsByTagName('script');
34 script = all_scripts[all_scripts.length - 1];
37 if (script.getAttribute.length != 'undefined')
40 script = script.getAttribute('src', -1);
42 var link = document.createElement('a');
43 link.setAttribute('href', script);
45 if(!link.protocol || !link.hostname) return null;
48 if(base) base += "//";
49 base += link.hostname;
51 if(link.port) base += ":" + link.port;
57 if(typeof netdataServer != 'undefined')
58 NETDATA.serverDefault = netdataServer + "/";
60 NETDATA.serverDefault = NETDATA._scriptSource();
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' ];
74 // ----------------------------------------------------------------------------------------------------------------
75 // the defaults for all charts
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
84 after: -600, // panning
85 pixels_per_point: 1 // the detail of the chart
96 idle_between_charts: 100,
97 idle_between_loops: 500,
99 fast_render_timeframe: 200 // render continously for these many ms
114 if(NETDATA.options.debug.main_loop) console.log('welcome to NETDATA');
117 // ----------------------------------------------------------------------------------------------------------------
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 }
127 NETDATA.errorLast = {
133 NETDATA.error = function(code, msg) {
134 NETDATA.errorLast.code = code;
135 NETDATA.errorLast.message = msg;
136 NETDATA.errorLast.datetime = new Date().getTime();
138 console.log("ERROR " + code + ": " + NETDATA.errorCodes[code].message + ": " + msg);
140 if(NETDATA.errorCodes[code].alert)
141 alert("ERROR " + code + ": " + NETDATA.errorCodes[code].message + ": " + msg);
144 NETDATA.errorReset = function() {
145 NETDATA.errorLast.code = 0;
146 NETDATA.errorLast.message = "You are doing fine!";
147 NETDATA.errorLast.datetime = 0;
150 NETDATA.messageInABox = function(element, message) {
154 if(NETDATA.options.debug.show_boxes)
155 bgcolor = " background-color: lightgrey;";
157 element.innerHTML = '<div style="font-size: xx-small; overflow: hidden;' + bgcolor + ' width: 100%; height: 100%;"><small>'
161 self.data('created', false);
164 // ----------------------------------------------------------------------------------------------------------------
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';
174 script.src = NETDATA.jQuery;
176 // script.onabort = onError;
177 script.onerror = function(err, t) { NETDATA.error(101, NETDATA.jQuery); };
178 if(typeof callback == "function")
179 script.onload = callback;
181 var s = document.getElementsByTagName('script')[0];
182 s.parentNode.insertBefore(script, s);
184 else if(typeof callback == "function")
188 NETDATA.ColorLuminance = function(hex, lum) {
189 // validate hex string
190 hex = String(hex).replace(/[^0-9a-f]/gi, '');
192 hex = hex[0]+hex[0]+hex[1]+hex[1]+hex[2]+hex[2];
196 // convert to decimal and change luminosity
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);
207 NETDATA.guid = function() {
209 return Math.floor((1 + Math.random()) * 0x10000)
214 return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
217 // this is the main function - where everything starts
218 NETDATA.init = function() {
219 // this should be called only once
221 $(window).blur(function() {
222 NETDATA.options.page_is_visible = 0;
223 if(NETDATA.options.debug.focus) console.log('Lost Focus!');
226 $(window).focus(function() {
227 NETDATA.options.page_is_visible = 1;
228 if(NETDATA.options.debug.focus) console.log('Focus restored!');
231 NETDATA.getDomCharts(function() {
232 NETDATA.chartRefresher(0);
236 // user function to signal us the DOM has been
238 NETDATA.updatedDom = function() {
239 NETDATA.options.updated_dom = 1;
242 // ----------------------------------------------------------------------------------------------------------------
244 NETDATA.generateChartDataURL = function() {
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;
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
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;
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;
274 url += "&after=" + after.toString();
277 url += "&before=" + before.toString();
280 url += "&dimensions=" + dimensions;
282 self.data('calculated-width', width)
283 .data('calculated-height', height)
284 .data('calculated-points', points)
285 .data('calculated-url', url);
287 if(NETDATA.options.debug.chart_data_url) console.log('generateChartDataURL(): ' + url + ' WxH:' + width + 'x' + height + ' points: ' + points + ' library: ' + library);
291 NETDATA.validateDomCharts = function(targets, index, callback) {
292 if(NETDATA.options.debug.main_loop) console.log('validateDomCharts() working on ' + index);
294 var target = targets.get(index);
296 if(NETDATA.options.debug.main_loop) console.log('validateDomCharts(): all ' + (index - 1) + ' charts parsed.');
297 if(typeof callback == 'function') callback();
300 var self = $(target);
301 if(!self.data('prepared')) {
302 self.data('prepared', true)
304 .data('created', false)
305 .data('enabled', false);
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;
311 if(NETDATA.options.debug.main_loop) console.log('validateDomCharts() parsing ' + id + ' of type ' + library);
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);
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);
323 else if(!NETDATA.chartLibraries[library].initialized) {
324 self.data('prepared', false);
325 NETDATA.chartLibraries[library].initialize(function() {
326 NETDATA.validateDomCharts(targets, index, callback);
330 var url = host + "/api/v1/chart?chart=" + id;
336 .done(function(chart) {
337 self.data('chart', chart)
338 .data('update-every', chart.update_every * 1000)
339 .data('enabled', true)
341 .data('chart-library', library);
344 NETDATA.error(404, url);
345 NETDATA.messageInABox(target, 'chart "' + id + '" not found on url "' + url + '"');
348 NETDATA.validateDomCharts(targets, ++index, callback);
353 NETDATA.validateDomCharts(targets, ++index, callback);
358 NETDATA.sizeDomCharts = function(targets, index, callback) {
359 // this is used to quickly size all charts to their size
361 if(NETDATA.options.debug.main_loop) console.log('sizeDomCharts() working on ' + index);
363 var target = targets.get(index);
365 if(NETDATA.options.debug.main_loop) console.log('sizeDomCharts(): all ' + (index - 1) + ' charts sized.');
366 if(typeof callback == 'function') callback();
369 var self = $(target);
371 var id = self.data('netdata');
372 var width = self.data('width') || NETDATA.chartDefaults.width;
373 var height = self.data('height') || NETDATA.chartDefaults.height;
375 self.css('width', width)
376 .css('height', height)
377 .css('display', 'inline-block')
378 .css('overflow', 'hidden');
380 NETDATA.messageInABox(target, 'chart "' + id + '" is loading...');
381 NETDATA.sizeDomCharts(targets, ++index, callback);
385 NETDATA.getDomCharts = function(callback) {
386 NETDATA.options.updated_dom = 0;
388 NETDATA.options.targets = $('div[data-netdata]').filter(':visible')
389 .bind('create', function(event, data) {
392 if(NETDATA.options.debug.chart_errors)
393 NETDATA.chartLibraries[self.data('chart-library')].create(this, data);
396 NETDATA.chartLibraries[self.data('chart-library')].create(this, data);
399 NETDATA.messageInABox(this, 'chart "' + self.data('netdata') + '" failed to be created as ' + self.data('chart-library'));
400 self.data('created', false);
404 .bind('update', function(event, data) {
406 if(NETDATA.options.debug.chart_errors)
407 NETDATA.chartLibraries[self.data('chart-library')].update(this, data);
410 NETDATA.chartLibraries[self.data('chart-library')].update(this, data);
413 NETDATA.messageInABox(this, 'chart "' + self.data('netdata') + '" failed to be updated as ' + self.data('chart-library'));
414 self.data('created', false);
419 if(NETDATA.options.debug.main_loop)
420 console.log('DOM updated - there are ' + NETDATA.options.targets.length + ' charts on page.');
422 NETDATA.sizeDomCharts(NETDATA.options.targets, 0, function() {
423 NETDATA.validateDomCharts(NETDATA.options.targets, 0, callback);
427 // ----------------------------------------------------------------------------------------------------------------
429 //var chart = function() {
432 //chart.prototype.color = function() {
436 //var c = new chart();
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;
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();
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();
455 if(NETDATA.options.debug.visibility) console.log(self.data('netdata') + ' is visible, downloading data...');
457 url: NETDATA.generateChartDataURL.call(element), // self.data('chart-url'),
460 .then(function(data) {
461 var started = new Date().getTime();
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);
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);
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);
480 var ended = new Date().getTime();
481 self.data('updated', ended);
483 var dt = ended - started;
485 self.data('refresh-dt', dt);
486 var element_name = self.data('dt-element-name') || null;
488 var element = document.getElementById(element_name) || null;
490 element.innerHTML = dt.toString();
495 NETDATA.messageInABox(element, 'cannot download chart "' + self.data('netdata') + '" values from url "' + self.data('chart-url') + '"');
498 if(typeof callback == 'function') callback();
503 NETDATA.chartRefresher = function(index) {
504 // if(NETDATA.options.debug.mail_loop) console.log('NETDATA.chartRefresher(<targets, ' + index + ')');
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);
513 now = new Date().getTime();
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);
523 var target = NETDATA.options.targets.get(index);
525 if(NETDATA.options.debug.main_loop) console.log('waiting to restart main loop...');
526 NETDATA.options.last_paused = now;
528 setTimeout(function() {
529 NETDATA.chartRefresher(0);
530 }, NETDATA.options.current.idle_between_loops);
533 var self = $(target);
534 if(!self.data('enabled')) {
535 NETDATA.chartRefresher(++index);
538 if(now - NETDATA.options.last_paused < NETDATA.options.current.fast_render_timeframe) {
539 if(NETDATA.options.debug.main_loop) console.log('fast rendering...');
541 NETDATA.chartValuesDownloader(target, function() {
542 NETDATA.chartRefresher(++index);
546 if(NETDATA.options.debug.main_loop) console.log('waiting for next refresh...');
547 NETDATA.options.last_paused = now;
549 setTimeout(function() {
550 NETDATA.chartValuesDownloader(target, function() {
551 NETDATA.chartRefresher(++index);
553 }, NETDATA.options.current.idle_between_charts);
561 // ----------------------------------------------------------------------------------------------------------------
564 NETDATA.peityInitialize = function(callback) {
565 if(typeof netdataStopPeity == 'undefined') {
566 $.getScript(NETDATA.peity_js)
568 NETDATA.registerChartLibrary('peity', NETDATA.peity_js);
571 NETDATA.error(100, NETDATA.peity_js);
574 if(typeof callback == "function")
579 NETDATA.chartLibraries.peity.enabled = false;
580 if(typeof callback == "function")
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);
591 // peity.change() does not accept options
592 // to pass width and height
594 ins.peity('line', { width: self.data('calculated-width'), height: self.data('calculated-height') })
597 NETDATA.peityChartCreate = function(element, data) {
598 var self = $(element);
600 var uuid = NETDATA.guid();
601 element.innerHTML = '<div id="' + uuid + '">' + data.result + '</div>';
602 var instance = document.getElementById(uuid);
603 var ins = $(instance);
605 ins.peity('line', { width: self.data('calculated-width'), height: self.data('calculated-height') })
607 self.data('peity-uuid', uuid)
608 .data('peity-instance', instance)
609 .data('created', true);
612 // ----------------------------------------------------------------------------------------------------------------
615 NETDATA.sparklineInitialize = function(callback) {
616 if(typeof netdataStopSparkline == 'undefined') {
617 $.getScript(NETDATA.sparkline_js)
619 NETDATA.registerChartLibrary('sparkline', NETDATA.sparkline_js);
622 NETDATA.error(100, NETDATA.sparkline_js);
625 if(typeof callback == "function")
630 NETDATA.chartLibraries.sparkline.enabled = false;
631 if(typeof callback == "function")
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);
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;
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,
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')
745 var uuid = NETDATA.guid();
746 element.innerHTML = '<div style="display: inline-block; position: relative;" id="' + uuid + '"></div>';
747 var div = document.getElementById(uuid);
749 self.sparkline(data.result, options);
750 self.data('sparkline-options', options)
752 .data('created', true);
755 // ----------------------------------------------------------------------------------------------------------------
758 NETDATA.dygraphAllCharts = [];
759 NETDATA.dygraphInitSync = function(callback) {
760 //$.getScript(NETDATA.serverDefault + 'dygraph-synchronizer.js')
761 // .always(function() {
762 if(typeof callback == "function")
767 NETDATA.dygraphSync = null;
768 NETDATA.dygraphSyncAll = function() {
769 if(NETDATA.dygraphSync) {
770 NETDATA.dygraphSync.detach();
771 NETDATA.dygraphSync = null;
774 NETDATA.dygraphSync = Dygraph.synchronize(NETDATA.dygraphAllCharts, {
780 NETDATA.dygraphInitialize = function(callback) {
781 if(typeof netdataStopDygraph == 'undefined') {
782 $.getScript(NETDATA.dygraph_js)
784 NETDATA.registerChartLibrary('dygraph', NETDATA.dygraph_js);
787 NETDATA.error(100, NETDATA.dygraph_js);
790 NETDATA.dygraphInitSync(callback);
794 NETDATA.chartLibraries.dygraph.enabled = false;
795 if(typeof callback == "function")
800 NETDATA.dygraphChartUpdate = function(element, data) {
801 var self = $(element);
802 var dygraph = self.data('dygraph-instance');
804 dygraph.updateOptions({
805 file: data.result.data,
806 labels: data.result.labels,
807 labelsDivWidth: self.width() - 70
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;
862 titleHeight: titleHeight,
864 yLabelWidth: yLabelWidth,
865 connectSeparatedPoints: connectSeparatedPoints,
866 drawPoints: drawPoints,
867 fillGraph: fillGraph,
868 stackedGraph: stackedGraph,
869 stackedGraphNaNFill: stackedGraphNaNFill,
871 drawXGrid: drawXGrid,
872 drawYGrid: drawYGrid,
873 gridLinePattern: gridLinePattern,
874 gridLineWidth: gridLineWidth,
875 gridLineColor: gridLineColor,
876 axisLineColor: axisLineColor,
877 axisLineWidth: axisLineWidth,
879 hideOverlayOnMouseOut: hideOverlayOnMouseOut,
880 labelsDiv: labelsDiv,
881 labelsDivStyles: labelsDivStyles,
882 labelsDivWidth: labelsDivWidth,
883 labelsSeparateLines: labelsSeparateLines,
884 labelsShowZeroValues: labelsShowZeroValues,
888 showLabelsOnHighlight: showLabelsOnHighlight,
889 maxNumberWidth: maxNumberWidth,
891 digitsAfterDecimal: digitsAfterDecimal,
892 axisLabelFontSize: axisLabelFontSize,
894 strokeWidth: strokeWidth,
895 drawGapEdgePoints: drawGapEdgePoints,
896 pointSize: pointSize,
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,
909 labels: data.result.labels,
913 ticker: Dygraph.dateTicker,
914 axisLabelFormatter: function (d, gran) {
915 return Dygraph.zeropad(d.getHours()) + ":" + Dygraph.zeropad(d.getMinutes()) + ":" + Dygraph.zeropad(d.getSeconds());
917 valueFormatter :function (ms) {
918 var d = new Date(ms);
919 return Dygraph.zeropad(d.getHours()) + ":" + Dygraph.zeropad(d.getMinutes()) + ":" + Dygraph.zeropad(d.getSeconds());
928 var uuid = NETDATA.guid();
929 self.html('<div id="' + uuid + '" style="width: 100%; height: 100%;"></div>');
931 var dchart = new Dygraph(document.getElementById(uuid),
932 data.result.data, options);
934 self.data('dygraph-instance', dchart)
935 .data('dygraph-options', options)
937 .data('created', true);
939 //NETDATA.dygraphAllCharts.push(dchart);
940 //if(NETDATA.dygraphAllCharts.length > 1)
941 // NETDATA.dygraphSyncAll();
944 // ----------------------------------------------------------------------------------------------------------------
947 NETDATA.morrisInitialize = function(callback) {
948 if(typeof netdataStopMorris == 'undefined') {
950 // morris requires raphael
951 if(!NETDATA.chartLibraries.raphael.initialized) {
952 if(NETDATA.chartLibraries.raphael.enabled) {
953 NETDATA.raphaelInitialize(function() {
954 NETDATA.morrisInitialize(callback);
958 NETDATA.chartLibraries.morris.enabled = false;
959 if(typeof callback == "function")
964 var fileref = document.createElement("link");
965 fileref.setAttribute("rel", "stylesheet");
966 fileref.setAttribute("type", "text/css");
967 fileref.setAttribute("href", NETDATA.morris_css);
969 if (typeof fileref != "undefined")
970 document.getElementsByTagName("head")[0].appendChild(fileref);
972 $.getScript(NETDATA.morris_js)
974 NETDATA.registerChartLibrary('morris', NETDATA.morris_js);
977 NETDATA.error(100, NETDATA.morris_js);
980 if(typeof callback == "function")
985 NETDATA.chartLibraries.morris.enabled = false;
986 if(typeof callback == "function")
991 NETDATA.morrisChartUpdate = function(element, data) {
992 var self = $(element);
993 var morris = self.data('morris-instance');
996 console.log('updating morris');
997 morris.setData(data.result.data);
1000 console.log('not updating morris');
1003 NETDATA.morrisChartCreate = function(element, data) {
1004 var self = $(element);
1005 var chart = self.data('chart');
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>');
1012 data: data.result.data,
1014 ykeys: data.dimension_names,
1015 labels: data.dimension_names,
1021 continuousLine: false,
1022 behaveLikeLine: false
1026 if(chart.chart_type == 'line')
1027 morris = new Morris.Line(options);
1029 else if(chart.chart_type == 'area') {
1030 options.behaveLikeLine = true;
1031 morris = new Morris.Area(options);
1034 morris = new Morris.Area(options);
1036 self.data('morris-instance', morris)
1037 .data('created', true);
1040 // ----------------------------------------------------------------------------------------------------------------
1043 NETDATA.raphaelInitialize = function(callback) {
1044 if(typeof netdataStopRaphael == 'undefined') {
1045 $.getScript(NETDATA.raphael_js)
1047 NETDATA.registerChartLibrary('raphael', NETDATA.raphael_js);
1050 NETDATA.error(100, NETDATA.raphael_js);
1052 .always(function() {
1053 if(typeof callback == "function")
1058 NETDATA.chartLibraries.raphael.enabled = false;
1059 if(typeof callback == "function")
1064 NETDATA.raphaelChartUpdate = function(element, data) {
1065 var self = $(element);
1067 self.raphael(data, {
1068 width: self.data('calculated-width'),
1069 height: self.data('calculated-height')
1073 NETDATA.raphaelChartCreate = function(element, data) {
1074 var self = $(element);
1076 self.raphael(data, {
1077 width: self.data('calculated-width'),
1078 height: self.data('calculated-height')
1080 .data('created', true);
1083 // ----------------------------------------------------------------------------------------------------------------
1086 NETDATA.googleInitialize = function(callback) {
1087 if(typeof netdataStopGoogleCharts == 'undefined') {
1088 $.getScript(NETDATA.google_js)
1090 NETDATA.registerChartLibrary('google', NETDATA.google_js);
1092 google.load('visualization', '1.1', {
1093 'packages': ['corechart', 'controls'],
1094 'callback': callback
1098 NETDATA.error(100, NETDATA.google_js);
1099 if(typeof callback == "function")
1104 NETDATA.chartLibraries.google.enabled = false;
1105 if(typeof callback == "function")
1110 NETDATA.googleChartUpdate = function(element, data) {
1111 var self = $(element);
1112 var gchart = self.data('google-instance');
1113 var options = self.data('google-options');
1115 var datatable = new google.visualization.DataTable(data.result);
1117 gchart.draw(datatable, options);
1120 NETDATA.googleChartCreate = function(element, data) {
1121 var self = $(element);
1122 var chart = self.data('chart');
1124 var datatable = new google.visualization.DataTable(data.result);
1128 // do not set width, height - the chart resizes itself
1129 //width: self.data('calculated-width'),
1130 //height: self.data('calculated-height'),
1135 // title: "Time of Day",
1136 // format:'HH:mm:ss',
1137 viewWindowMode: 'maximized',
1149 viewWindowMode: 'pretty',
1164 focusTarget: 'category',
1171 titlePosition: 'out',
1182 curveType: 'function',
1187 var uuid = NETDATA.guid();
1188 self.html('<div id="' + uuid + '" style="width: 100%; height: 100%;"></div>');
1190 switch(chart.chart_type) {
1192 options.vAxis.viewWindowMode = 'maximized';
1193 gchart = new google.visualization.AreaChart(document.getElementById(uuid));
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));
1207 options.lineWidth = 2;
1208 gchart = new google.visualization.LineChart(document.getElementById(uuid));
1212 gchart.draw(datatable, options);
1214 self.data('google-instance', gchart)
1215 .data('google-options', options)
1217 .data('created', true);
1220 // ----------------------------------------------------------------------------------------------------------------
1221 // Charts Libraries Registration
1223 NETDATA.chartLibraries = {
1225 initialize: NETDATA.dygraphInitialize,
1226 create: NETDATA.dygraphChartCreate,
1227 update: NETDATA.dygraphChartUpdate,
1231 options: 'ms|flip|jsonwrap',
1233 pixels_per_point: 2,
1234 detects_dimensions_on_update: false
1237 initialize: NETDATA.sparklineInitialize,
1238 create: NETDATA.sparklineChartCreate,
1239 update: NETDATA.sparklineChartUpdate,
1243 options: 'flip|min2max|jsonwrap',
1245 pixels_per_point: 2,
1246 detects_dimensions_on_update: false
1249 initialize: NETDATA.peityInitialize,
1250 create: NETDATA.peityChartCreate,
1251 update: NETDATA.peityChartUpdate,
1255 options: 'null2zero|flip|min2max|jsonwrap',
1257 pixels_per_point: 2,
1258 detects_dimensions_on_update: false
1261 initialize: NETDATA.morrisInitialize,
1262 create: NETDATA.morrisChartCreate,
1263 update: NETDATA.morrisChartUpdate,
1267 options: 'objectrows|ms|jsonwrap',
1269 pixels_per_point: 10,
1270 detects_dimensions_on_update: false
1273 initialize: NETDATA.googleInitialize,
1274 create: NETDATA.googleChartCreate,
1275 update: NETDATA.googleChartUpdate,
1278 format: 'datatable',
1279 options: 'jsonwrap',
1281 pixels_per_point: 2,
1282 detects_dimensions_on_update: true
1285 initialize: NETDATA.raphaelInitialize,
1286 create: NETDATA.raphaelChartCreate,
1287 update: NETDATA.raphaelChartUpdate,
1293 pixels_per_point: 1,
1294 detects_dimensions_on_update: false
1298 NETDATA.registerChartLibrary = function(library, url) {
1299 console.log("registering chart library: " + library);
1301 NETDATA.chartLibraries[library].url = url;
1302 NETDATA.chartLibraries[library].initialized = true;
1303 NETDATA.chartLibraries[library].enabled = true;
1305 console.log(NETDATA.chartLibraries);
1308 // ----------------------------------------------------------------------------------------------------------------
1309 // load all libraries and initialize
1311 NETDATA.errorReset();
1313 NETDATA._loadjQuery(function() {
1314 $.getScript(NETDATA.serverDefault + 'lib/visible.js').then(function() {