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
7 // You can also set the default netdata server, using the following.
8 // When this variable is not set, we assume the page is hosted on your
9 // netdata server already.
10 // var netdataServer = "http://yourhost:19999"; // set your NetData server
12 // --------------------------------------------------------------------------------------------------------------------
13 // For google charts you need this in your page:
14 // <script type="text/javascript" src="https://www.google.com/jsapi"></script>
15 // <script type='text/javascript'>google.load('visualization', '1.1', {'packages':['corechart', 'controls']});</script>
19 // fix IE bug with console
20 if(!window.console){ window.console = {log: function(){} }; }
22 var NETDATA = window.NETDATA || {};
24 // ----------------------------------------------------------------------------------------------------------------
25 // Detect the netdata server
27 // http://stackoverflow.com/questions/984510/what-is-my-script-src-url
28 // http://stackoverflow.com/questions/6941533/get-protocol-domain-and-port-from-url
29 NETDATA._scriptSource = function(scripts) {
30 var script = null, base = null;
32 if(typeof document.currentScript != 'undefined') {
33 script = document.currentScript;
36 var all_scripts = document.getElementsByTagName('script');
37 script = all_scripts[all_scripts.length - 1];
40 if (script.getAttribute.length != 'undefined')
43 script = script.getAttribute('src', -1);
45 var link = document.createElement('a');
46 link.setAttribute('href', script);
48 if(!link.protocol || !link.hostname) return null;
51 if(base) base += "//";
52 base += link.hostname;
54 if(link.port) base += ":" + link.port;
60 if(typeof netdataServer != 'undefined')
61 NETDATA.serverDefault = netdataServer + "/";
63 NETDATA.serverDefault = NETDATA._scriptSource();
65 NETDATA.jQuery = NETDATA.serverDefault + 'lib/jquery-1.11.3.min.js';
66 NETDATA.peity_js = NETDATA.serverDefault + 'lib/jquery.peity.min.js';
67 NETDATA.sparkline_js = NETDATA.serverDefault + 'lib/jquery.sparkline.min.js';
68 NETDATA.dygraph_js = NETDATA.serverDefault + 'lib/dygraph-combined.js';
69 NETDATA.raphael_js = NETDATA.serverDefault + 'lib/raphael-min.js';
70 NETDATA.morris_js = NETDATA.serverDefault + 'lib/morris.min.js';
71 NETDATA.morris_css = NETDATA.serverDefault + 'css/morris.css';
72 NETDATA.google_js = 'https://www.google.com/jsapi';
73 NETDATA.colors = [ '#3366CC', '#DC3912', '#FF9900', '#109618', '#990099', '#3B3EAC', '#0099C6',
74 '#DD4477', '#66AA00', '#B82E2E', '#316395', '#994499', '#22AA99', '#AAAA11',
75 '#6633CC', '#E67300', '#8B0707', '#329262', '#5574A6', '#3B3EAC' ];
77 // ----------------------------------------------------------------------------------------------------------------
78 // the defaults for all charts
80 NETDATA.chartDefaults = {
81 host: NETDATA.serverDefault, // the server to get data from
82 width: '100%', // the chart width
83 height: '100%', // the chart height
84 library: 'dygraph', // the graphing library to use
85 method: 'average', // the grouping method
87 after: -600, // panning
88 pixels_per_point: 1 // the detail of the chart
99 idle_between_charts: 100,
100 idle_between_loops: 500,
101 fast_render_timeframe: 200 // render continously for these many ms
105 if(NETDATA.options.debug) console.log('welcome to NETDATA');
108 // ----------------------------------------------------------------------------------------------------------------
111 NETDATA.errorCodes = {
112 100: { message: "Cannot load chart library", alert: true },
113 101: { message: "Cannot load jQuery", alert: true },
114 402: { message: "Chart library not found", alert: false },
115 403: { message: "Chart library not enabled/is failed", alert: false },
116 404: { message: "Chart not found", alert: false }
118 NETDATA.errorLast = {
124 NETDATA.error = function(code, msg) {
125 NETDATA.errorLast.code = code;
126 NETDATA.errorLast.message = msg;
127 NETDATA.errorLast.datetime = new Date().getTime();
129 console.log("ERROR " + code + ": " + NETDATA.errorCodes[code].message + ": " + msg);
131 if(NETDATA.errorCodes[code].alert)
132 alert("ERROR " + code + ": " + NETDATA.errorCodes[code].message + ": " + msg);
135 NETDATA.errorReset = function() {
136 NETDATA.errorLast.code = 0;
137 NETDATA.errorLast.message = "You are doing fine!";
138 NETDATA.errorLast.datetime = 0;
141 NETDATA.messageInABox = function(element, message) {
145 if(NETDATA.options.debug)
146 bgcolor = " background-color: lightgrey;";
148 element.innerHTML = '<div style="overflow: hidden;' + bgcolor + ' width: 100%; height: 100%;"><small>'
152 self.data('created', false);
155 // ----------------------------------------------------------------------------------------------------------------
156 // Load a script without jquery
157 // This is used to load jquery - after it is loaded, we use jquery
159 NETDATA._loadjQuery = function(callback) {
160 if(typeof jQuery == 'undefined') {
161 var script = document.createElement('script');
162 script.type = 'text/javascript';
164 script.src = NETDATA.jQuery;
166 // script.onabort = onError;
167 script.onerror = function(err, t) { NETDATA.error(101, NETDATA.jQuery); };
168 if(typeof callback == "function")
169 script.onload = callback;
171 var s = document.getElementsByTagName('script')[0];
172 s.parentNode.insertBefore(script, s);
174 else if(typeof callback == "function")
178 NETDATA.generateChartDataURL = function() {
181 var chart = self.data('chart');
182 var host = self.data('host') || NETDATA.chartDefaults.host;
183 var width = self.width();
184 var height = self.height();
185 var method = self.data('method') || NETDATA.chartDefaults.method;
186 var after = self.data('after') || NETDATA.chartDefaults.after;
187 var before = self.data('before') || NETDATA.chartDefaults.before;
188 var library = self.data('chart-library') || NETDATA.chartDefaults.library;
189 var dimensions = self.data('dimensions') || null;
190 var pixels_per_point = self.data('pixels-per-point') || NETDATA.chartLibraries[library].pixels_per_point;
192 // force an options provided detail
193 if(pixels_per_point < NETDATA.options.current.pixels_per_point)
194 pixels_per_point = NETDATA.options.current.pixels_per_point
196 var points = self.data('points') || Math.round(width / pixels_per_point);
198 // build the data URL
199 var url = host + chart.data_url;
200 url += "&format=" + NETDATA.chartLibraries[library].format;
201 url += "&points=" + points.toString();
202 url += "&options=" + NETDATA.chartLibraries[library].options;
203 url += "&group=" + method;
206 url += "&after=" + after.toString();
209 url += "&before=" + before.toString();
212 url += "&dimensions=" + dimensions;
214 self.data('calculated-width', width)
215 .data('calculated-height', height)
216 .data('calculated-points', points)
217 .data('calculated-url', url);
219 if(NETDATA.options.debug) console.log('generateChartDataURL(): ' + url + ' WxH:' + width + 'x' + height + ' points: ' + points + ' library: ' + library);
223 NETDATA.validateDomCharts = function(targets, index, callback) {
224 if(NETDATA.options.debug) console.log('validateDomCharts() working on ' + index);
226 var target = targets.get(index);
228 if(NETDATA.options.debug) console.log('validateDomCharts(): all ' + (index - 1) + ' charts parsed.');
229 if(typeof callback == 'function') callback();
232 var self = $(target);
233 if(!self.data('prepared')) {
234 self.data('prepared', true)
236 .data('created', false)
237 .data('enabled', false);
239 var id = self.data('netdata');
240 var host = self.data('host') || NETDATA.chartDefaults.host;
241 var library = self.data('chart-library') || NETDATA.chartDefaults.library;
243 if(NETDATA.options.debug) console.log('validateDomCharts() parsing ' + id + ' of type ' + library);
245 if(typeof NETDATA.chartLibraries[library] == 'undefined') {
246 NETDATA.error(402, library);
247 NETDATA.messageInABox(target, 'chart library "' + library + '" is not found');
248 NETDATA.validateDomCharts(targets, ++index, callback);
250 else if(!NETDATA.chartLibraries[library].enabled) {
251 NETDATA.error(403, library);
252 NETDATA.messageInABox(target, 'chart library "' + library + '" is not enabled');
253 NETDATA.validateDomCharts(targets, ++index, callback);
255 else if(!NETDATA.chartLibraries[library].initialized) {
256 self.data('prepared', false);
257 NETDATA.chartLibraries[library].initialize(function() {
258 NETDATA.validateDomCharts(targets, index, callback);
262 var url = host + "/api/v1/chart?chart=" + id;
268 .done(function(chart) {
269 self.data('chart', chart)
270 .data('update-every', chart.update_every * 1000)
271 .data('enabled', true)
273 .data('chart-library', library);
276 NETDATA.error(404, url);
277 NETDATA.messageInABox(target, 'chart "' + id + '" not found on url "' + url + '"');
280 NETDATA.validateDomCharts(targets, ++index, callback);
285 NETDATA.validateDomCharts(targets, ++index, callback);
290 NETDATA.sizeDomCharts = function(targets, index, callback) {
291 // this is used to quickly size all charts to their size
293 if(NETDATA.options.debug) console.log('sizeDomCharts() working on ' + index);
295 var target = targets.get(index);
297 if(NETDATA.options.debug) console.log('sizeDomCharts(): all ' + (index - 1) + ' charts sized.');
298 if(typeof callback == 'function') callback();
301 var self = $(target);
303 var id = self.data('netdata');
304 var width = self.data('width') || NETDATA.chartDefaults.width;
305 var height = self.data('height') || NETDATA.chartDefaults.height;
307 self.css('width', width)
308 .css('height', height)
309 .css('display', 'inline-block')
310 .css('overflow', 'hidden');
312 NETDATA.messageInABox(target, 'chart "' + id + '" is loading...');
313 NETDATA.sizeDomCharts(targets, ++index, callback);
317 NETDATA.domUpdated = function(callback) {
318 NETDATA.options.updated_dom = 0;
320 NETDATA.options.targets = $('div[data-netdata]').filter(':visible')
321 .bind('create', function(event, data) {
324 if(NETDATA.options.debug)
325 NETDATA.chartLibraries[self.data('chart-library')].create(this, data);
328 NETDATA.chartLibraries[self.data('chart-library')].create(this, data);
331 NETDATA.messageInABox(this, 'chart "' + self.data('netdata') + '" failed to be created as ' + self.data('chart-library'));
332 self.data('created', false);
336 .bind('update', function(event, data) {
338 if(NETDATA.options.debug)
339 NETDATA.chartLibraries[self.data('chart-library')].update(this, data);
342 NETDATA.chartLibraries[self.data('chart-library')].update(this, data);
345 NETDATA.messageInABox(this, 'chart "' + self.data('netdata') + '" failed to be updated as ' + self.data('chart-library'));
346 self.data('created', false);
351 if(NETDATA.options.debug)
352 console.log('DOM updated - there are ' + NETDATA.options.targets.length + ' charts on page.');
354 NETDATA.sizeDomCharts(NETDATA.options.targets, 0, function() {
355 NETDATA.validateDomCharts(NETDATA.options.targets, 0, callback);
359 NETDATA.init = function() {
360 // this should be called only once
361 NETDATA.domUpdated(function() {
362 NETDATA.chartRefresher(0);
366 // ----------------------------------------------------------------------------------------------------------------
368 //var chart = function() {
371 //chart.prototype.color = function() {
375 //var c = new chart();
378 NETDATA.chartValuesDownloader = function(element, callback) {
379 var self = $(element);
380 var last = self.data('updated') || 0;
381 var every = self.data('update-every') || 1;
383 // check if this chart has to be refreshed now
384 var now = new Date().getTime();
385 if(last + every > now) {
386 console.log(self.data('netdata') + ' too soon - skipping.');
387 if(typeof callback == 'function') callback();
389 else if(!self.visible(true)) {
390 console.log(self.data('netdata') + ' is NOT visible.');
391 if(typeof callback == 'function') callback();
394 console.log(self.data('netdata') + ' is visible, downloading data...');
396 url: NETDATA.generateChartDataURL.call(element), // self.data('chart-url'),
399 .then(function(data) {
400 var started = new Date().getTime();
402 if(self.data('created')) {
403 console.log('updating ' + self.data('chart-library') + ' chart ' + self.data('netdata'));
404 self.trigger('update', [data]);
405 // NETDATA.chartLibraries[self.data('chart-library')].update(element, data);
408 console.log('creating ' + self.data('chart-library') + ' chart ' + self.data('netdata'));
409 self.trigger('create', [data]);
410 //NETDATA.chartLibraries[self.data('chart-library')].create(element, data);
411 self.data('created', true);
414 var ended = new Date().getTime();
415 self.data('updated', ended);
417 var dt = ended - started;
419 self.data('refresh-dt', dt);
420 var element_name = self.data('dt-element-name') || null;
422 var element = document.getElementById(element_name) || null;
424 element.innerHTML = dt.toString();
429 NETDATA.messageInABox(element, 'cannot download chart "' + self.data('netdata') + '" values from url "' + self.data('chart-url') + '"');
432 if(typeof callback == 'function') callback();
437 NETDATA.chartRefresher = function(index) {
438 // if(NETDATA.options.debug) console.log('NETDATA.chartRefresher(<targets, ' + index + ')');
440 now = new Date().getTime();
442 if(NETDATA.options.updated_dom) {
443 NETDATA.domUpdated(function() {
444 NETDATA.chartRefresher(0);
448 var target = NETDATA.options.targets.get(index);
450 if(NETDATA.options.debug) console.log('waiting to restart main loop...');
451 NETDATA.options.last_paused = now;
453 setTimeout(function() {
454 NETDATA.chartRefresher(0);
455 }, NETDATA.options.current.idle_between_loops);
458 var self = $(target);
459 if(!self.data('enabled')) {
460 NETDATA.chartRefresher(++index);
463 if(now - NETDATA.options.last_paused < NETDATA.options.current.fast_render_timeframe) {
464 if(NETDATA.options.debug) console.log('fast rendering...');
466 NETDATA.chartValuesDownloader(target, function() {
467 NETDATA.chartRefresher(++index);
471 if(NETDATA.options.debug) console.log('waiting for next refresh...');
472 NETDATA.options.last_paused = now;
474 setTimeout(function() {
475 NETDATA.chartValuesDownloader(target, function() {
476 NETDATA.chartRefresher(++index);
478 }, NETDATA.options.current.idle_between_charts);
485 NETDATA.guid = function() {
487 return Math.floor((1 + Math.random()) * 0x10000)
492 return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
495 // ----------------------------------------------------------------------------------------------------------------
498 NETDATA.peityInitialize = function(callback) {
499 if(typeof netdataStopPeity == 'undefined') {
500 $.getScript(NETDATA.peity_js)
502 NETDATA.registerChartLibrary('peity', NETDATA.peity_js);
505 NETDATA.error(100, NETDATA.peity_js);
508 if(typeof callback == "function")
513 NETDATA.chartLibraries.peity.enabled = false;
514 if(typeof callback == "function")
519 NETDATA.peityChartUpdate = function(element, data) {
520 var self = $(element);
521 var instance = self.data('peity-instance');
522 var ins = $(instance);
525 // peity.change() does not accept options
526 // to pass width and height
528 ins.peity('line', { width: self.data('calculated-width'), height: self.data('calculated-height') })
531 NETDATA.peityChartCreate = function(element, data) {
532 var self = $(element);
534 var uuid = NETDATA.guid();
535 element.innerHTML = '<div id="' + uuid + '">' + data + '</div>';
536 var instance = document.getElementById(uuid);
537 var ins = $(instance);
539 ins.peity('line', { width: self.data('calculated-width'), height: self.data('calculated-height') })
541 self.data('peity-uuid', uuid)
542 .data('peity-instance', instance)
543 .data('created', true);
546 // ----------------------------------------------------------------------------------------------------------------
549 NETDATA.sparklineInitialize = function(callback) {
550 if(typeof netdataStopSparkline == 'undefined') {
551 $.getScript(NETDATA.sparkline_js)
553 NETDATA.registerChartLibrary('sparkline', NETDATA.sparkline_js);
556 NETDATA.error(100, NETDATA.sparkline_js);
559 if(typeof callback == "function")
564 NETDATA.chartLibraries.sparkline.enabled = false;
565 if(typeof callback == "function")
570 NETDATA.sparklineChartUpdate = function(element, data) {
571 var self = $(element);
572 var options = self.data('sparkline-options');
573 options.width = self.data('calculated-width');
574 options.height = self.data('calculated-height');
575 self.sparkline(data, options);
578 NETDATA.sparklineChartCreate = function(element, data) {
579 var self = $(element);
580 var chart = self.data('chart');
581 var type = self.data('sparkline-type') || 'line';
582 var lineColor = self.data('sparkline-lineColor') || undefined;
583 var fillColor = self.data('sparkline-fillColor') || (chart.chart_type == 'line')?'#FFF':undefined;
584 var chartRangeMin = self.data('sparkline-chartRangeMin') || undefined;
585 var chartRangeMax = self.data('sparkline-chartRangeMax') || undefined;
586 var composite = self.data('sparkline-composite') || undefined;
587 var enableTagOptions = self.data('sparkline-enableTagOptions') || undefined;
588 var tagOptionPrefix = self.data('sparkline-tagOptionPrefix') || undefined;
589 var tagValuesAttribute = self.data('sparkline-tagValuesAttribute') || undefined;
590 var disableHiddenCheck = self.data('sparkline-disableHiddenCheck') || undefined;
591 var defaultPixelsPerValue = self.data('sparkline-defaultPixelsPerValue') || undefined;
592 var spotColor = self.data('sparkline-spotColor') || undefined;
593 var minSpotColor = self.data('sparkline-minSpotColor') || undefined;
594 var maxSpotColor = self.data('sparkline-maxSpotColor') || undefined;
595 var spotRadius = self.data('sparkline-spotRadius') || undefined;
596 var valueSpots = self.data('sparkline-valueSpots') || undefined;
597 var highlightSpotColor = self.data('sparkline-highlightSpotColor') || undefined;
598 var highlightLineColor = self.data('sparkline-highlightLineColor') || undefined;
599 var lineWidth = self.data('sparkline-lineWidth') || undefined;
600 var normalRangeMin = self.data('sparkline-normalRangeMin') || undefined;
601 var normalRangeMax = self.data('sparkline-normalRangeMax') || undefined;
602 var drawNormalOnTop = self.data('sparkline-drawNormalOnTop') || undefined;
603 var xvalues = self.data('sparkline-xvalues') || undefined;
604 var chartRangeClip = self.data('sparkline-chartRangeClip') || undefined;
605 var xvalues = self.data('sparkline-xvalues') || undefined;
606 var chartRangeMinX = self.data('sparkline-chartRangeMinX') || undefined;
607 var chartRangeMaxX = self.data('sparkline-chartRangeMaxX') || undefined;
608 var disableInteraction = self.data('sparkline-disableInteraction') || false;
609 var disableTooltips = self.data('sparkline-disableTooltips') || false;
610 var disableHighlight = self.data('sparkline-disableHighlight') || false;
611 var highlightLighten = self.data('sparkline-highlightLighten') || 1.4;
612 var highlightColor = self.data('sparkline-highlightColor') || undefined;
613 var tooltipContainer = self.data('sparkline-tooltipContainer') || undefined;
614 var tooltipClassname = self.data('sparkline-tooltipClassname') || undefined;
615 var tooltipFormat = self.data('sparkline-tooltipFormat') || undefined;
616 var tooltipPrefix = self.data('sparkline-tooltipPrefix') || undefined;
617 var tooltipSuffix = self.data('sparkline-tooltipSuffix') || ' ' + chart.units;
618 var tooltipSkipNull = self.data('sparkline-tooltipSkipNull') || true;
619 var tooltipValueLookups = self.data('sparkline-tooltipValueLookups') || undefined;
620 var tooltipFormatFieldlist = self.data('sparkline-tooltipFormatFieldlist') || undefined;
621 var tooltipFormatFieldlistKey = self.data('sparkline-tooltipFormatFieldlistKey') || undefined;
622 var numberFormatter = self.data('sparkline-numberFormatter') || function(n){ return n.toFixed(2); };
623 var numberDigitGroupSep = self.data('sparkline-numberDigitGroupSep') || undefined;
624 var numberDecimalMark = self.data('sparkline-numberDecimalMark') || undefined;
625 var numberDigitGroupCount = self.data('sparkline-numberDigitGroupCount') || undefined;
626 var animatedZooms = self.data('sparkline-animatedZooms') || false;
630 lineColor: lineColor,
631 fillColor: fillColor,
632 chartRangeMin: chartRangeMin,
633 chartRangeMax: chartRangeMax,
634 composite: composite,
635 enableTagOptions: enableTagOptions,
636 tagOptionPrefix: tagOptionPrefix,
637 tagValuesAttribute: tagValuesAttribute,
638 disableHiddenCheck: disableHiddenCheck,
639 defaultPixelsPerValue: defaultPixelsPerValue,
640 spotColor: spotColor,
641 minSpotColor: minSpotColor,
642 maxSpotColor: maxSpotColor,
643 spotRadius: spotRadius,
644 valueSpots: valueSpots,
645 highlightSpotColor: highlightSpotColor,
646 highlightLineColor: highlightLineColor,
647 lineWidth: lineWidth,
648 normalRangeMin: normalRangeMin,
649 normalRangeMax: normalRangeMax,
650 drawNormalOnTop: drawNormalOnTop,
652 chartRangeClip: chartRangeClip,
653 chartRangeMinX: chartRangeMinX,
654 chartRangeMaxX: chartRangeMaxX,
655 disableInteraction: disableInteraction,
656 disableTooltips: disableTooltips,
657 disableHighlight: disableHighlight,
658 highlightLighten: highlightLighten,
659 highlightColor: highlightColor,
660 tooltipContainer: tooltipContainer,
661 tooltipClassname: tooltipClassname,
662 tooltipChartTitle: chart.title,
663 tooltipFormat: tooltipFormat,
664 tooltipPrefix: tooltipPrefix,
665 tooltipSuffix: tooltipSuffix,
666 tooltipSkipNull: tooltipSkipNull,
667 tooltipValueLookups: tooltipValueLookups,
668 tooltipFormatFieldlist: tooltipFormatFieldlist,
669 tooltipFormatFieldlistKey: tooltipFormatFieldlistKey,
670 numberFormatter: numberFormatter,
671 numberDigitGroupSep: numberDigitGroupSep,
672 numberDecimalMark: numberDecimalMark,
673 numberDigitGroupCount: numberDigitGroupCount,
674 animatedZooms: animatedZooms,
675 width: self.data('calculated-width'),
676 height: self.data('calculated-height')
679 var uuid = NETDATA.guid();
680 element.innerHTML = '<div style="display: inline-block; position: relative;" id="' + uuid + '"></div>';
681 var div = document.getElementById(uuid);
683 self.sparkline(data, options);
684 self.data('sparkline-options', options)
686 .data('created', true);
689 // ----------------------------------------------------------------------------------------------------------------
692 NETDATA.dygraphAllCharts = [];
693 NETDATA.dygraphInitSync = function(callback) {
694 //$.getScript(NETDATA.serverDefault + 'dygraph-synchronizer.js')
695 // .always(function() {
696 if(typeof callback == "function")
701 NETDATA.dygraphSync = null;
702 NETDATA.dygraphSyncAll = function() {
703 if(NETDATA.dygraphSync) {
704 NETDATA.dygraphSync.detach();
705 NETDATA.dygraphSync = null;
708 NETDATA.dygraphSync = Dygraph.synchronize(NETDATA.dygraphAllCharts, {
714 NETDATA.dygraphInitialize = function(callback) {
715 if(typeof netdataStopDygraph == 'undefined') {
716 $.getScript(NETDATA.dygraph_js)
718 NETDATA.registerChartLibrary('dygraph', NETDATA.dygraph_js);
721 NETDATA.error(100, NETDATA.dygraph_js);
724 NETDATA.dygraphInitSync(callback);
728 NETDATA.chartLibraries.dygraph.enabled = false;
729 if(typeof callback == "function")
734 NETDATA.dygraphChartUpdate = function(element, data) {
735 var self = $(element);
736 var dygraph = self.data('dygraph-instance');
738 if(typeof data.update_every != 'undefined')
739 self.data('update-every', data.update_every * 1000);
741 if(dygraph != null) {
742 console.log('updating dygraphs');
743 dygraph.updateOptions({
746 labelsDivWidth: self.width() - 70
750 console.log('not updating dygraphs');
753 NETDATA.dygraphChartCreate = function(element, data) {
754 var self = $(element);
755 var chart = self.data('chart');
756 var title = self.data('dygraph-title') || chart.title;
757 var titleHeight = self.data('dygraph-titleHeight') || 20;
758 var labelsDiv = self.data('dygraph-labelsDiv') || undefined;
759 var connectSeparatedPoints = self.data('dygraph-connectSeparatedPoints') || false;
760 var yLabelWidth = self.data('dygraph-yLabelWidth') || 12;
761 var stackedGraph = self.data('dygraph-stackedGraph') || (chart.chart_type == 'stacked')?true:false;
762 var stackedGraphNaNFill = self.data('dygraph-stackedGraphNaNFill') || 'none';
763 var hideOverlayOnMouseOut = self.data('dygraph-hideOverlayOnMouseOut') || true;
764 var fillGraph = self.data('dygraph-fillGraph') || (chart.chart_type == 'area')?true:false;
765 var drawPoints = self.data('dygraph-drawPoints') || false;
766 var labelsDivStyles = self.data('dygraph-labelsDivStyles') || { 'fontSize':'10px' };
767 // var labelsDivWidth = self.data('dygraph-labelsDivWidth') || 250;
768 var labelsDivWidth = self.width() - 70;
769 var labelsSeparateLines = self.data('dygraph-labelsSeparateLines') || false;
770 var labelsShowZeroValues = self.data('dygraph-labelsShowZeroValues') || true;
771 var legend = self.data('dygraph-legend') || 'onmouseover';
772 var showLabelsOnHighlight = self.data('dygraph-showLabelsOnHighlight') || true;
773 var gridLineColor = self.data('dygraph-gridLineColor') || '#EEE';
774 var axisLineColor = self.data('dygraph-axisLineColor') || '#EEE';
775 var maxNumberWidth = self.data('dygraph-maxNumberWidth') || 8;
776 var sigFigs = self.data('dygraph-sigFigs') || null;
777 var digitsAfterDecimal = self.data('dygraph-digitsAfterDecimal') || 2;
778 var axisLabelFontSize = self.data('dygraph-axisLabelFontSize') || 10;
779 var axisLineWidth = self.data('dygraph-axisLineWidth') || 0.3;
780 var drawAxis = self.data('dygraph-drawAxis') || true;
781 var strokeWidth = self.data('dygraph-strokeWidth') || 1.0;
782 var drawGapEdgePoints = self.data('dygraph-drawGapEdgePoints') || true;
783 var colors = self.data('dygraph-colors') || NETDATA.colors;
784 var pointSize = self.data('dygraph-pointSize') || 1;
785 var stepPlot = self.data('dygraph-stepPlot') || false;
786 var strokeBorderColor = self.data('dygraph-strokeBorderColor') || 'white';
787 var strokeBorderWidth = self.data('dygraph-strokeBorderWidth') || (chart.chart_type == 'stacked')?1.0:0.0;
788 var strokePattern = self.data('dygraph-strokePattern') || undefined;
789 var highlightCircleSize = self.data('dygraph-highlightCircleSize') || 3;
790 var highlightSeriesOpts = self.data('dygraph-highlightSeriesOpts') || { strokeWidth: 1.5 };
791 var highlightSeriesBackgroundAlpha = self.data('dygraph-highlightSeriesBackgroundAlpha') || (chart.chart_type == 'stacked')?0.7:0.5;
792 var pointClickCallback = self.data('dygraph-pointClickCallback') || undefined;
793 var showRangeSelector = self.data('dygraph-showRangeSelector') || false;
794 var showRoller = self.data('dygraph-showRoller') || false;
795 var valueFormatter = self.data('dygraph-valueFormatter') || undefined; //function(x){ return x.toFixed(2); };
796 var rightGap = self.data('dygraph-rightGap') || 5;
797 var drawGrid = self.data('dygraph-drawGrid') || true;
798 var drawXGrid = self.data('dygraph-drawXGrid') || undefined;
799 var drawYGrid = self.data('dygraph-drawYGrid') || undefined;
800 var gridLinePattern = self.data('dygraph-gridLinePattern') || null;
801 var gridLineWidth = self.data('dygraph-gridLineWidth') || 0.3;
805 titleHeight: titleHeight,
807 yLabelWidth: yLabelWidth,
808 connectSeparatedPoints: connectSeparatedPoints,
809 drawPoints: drawPoints,
810 fillGraph: fillGraph,
811 stackedGraph: stackedGraph,
812 stackedGraphNaNFill: stackedGraphNaNFill,
814 drawXGrid: drawXGrid,
815 drawYGrid: drawYGrid,
816 gridLinePattern: gridLinePattern,
817 gridLineWidth: gridLineWidth,
818 gridLineColor: gridLineColor,
819 axisLineColor: axisLineColor,
820 axisLineWidth: axisLineWidth,
822 hideOverlayOnMouseOut: hideOverlayOnMouseOut,
823 labelsDiv: labelsDiv,
824 labelsDivStyles: labelsDivStyles,
825 labelsDivWidth: labelsDivWidth,
826 labelsSeparateLines: labelsSeparateLines,
827 labelsShowZeroValues: labelsShowZeroValues,
831 showLabelsOnHighlight: showLabelsOnHighlight,
832 maxNumberWidth: maxNumberWidth,
834 digitsAfterDecimal: digitsAfterDecimal,
835 axisLabelFontSize: axisLabelFontSize,
837 strokeWidth: strokeWidth,
838 drawGapEdgePoints: drawGapEdgePoints,
839 pointSize: pointSize,
841 strokeBorderColor: strokeBorderColor,
842 strokeBorderWidth: strokeBorderWidth,
843 strokePattern: strokePattern,
844 highlightCircleSize: highlightCircleSize,
845 highlightSeriesOpts: highlightSeriesOpts,
846 highlightSeriesBackgroundAlpha: highlightSeriesBackgroundAlpha,
847 pointClickCallback: pointClickCallback,
848 showRangeSelector: showRangeSelector,
849 showRoller: showRoller,
850 valueFormatter: valueFormatter,
856 ticker: Dygraph.dateTicker,
857 axisLabelFormatter: function (d, gran) {
858 return Dygraph.zeropad(d.getHours()) + ":" + Dygraph.zeropad(d.getMinutes()) + ":" + Dygraph.zeropad(d.getSeconds());
860 valueFormatter :function (ms) {
861 var d = new Date(ms);
862 return Dygraph.zeropad(d.getHours()) + ":" + Dygraph.zeropad(d.getMinutes()) + ":" + Dygraph.zeropad(d.getSeconds());
871 var uuid = NETDATA.guid();
872 self.html('<div id="' + uuid + '" style="width: 100%; height: 100%;"></div>');
874 var dchart = new Dygraph(document.getElementById(uuid),
877 self.data('dygraph-instance', dchart)
878 .data('dygraph-options', options)
880 .data('created', true);
882 //NETDATA.dygraphAllCharts.push(dchart);
883 //if(NETDATA.dygraphAllCharts.length > 1)
884 // NETDATA.dygraphSyncAll();
887 // ----------------------------------------------------------------------------------------------------------------
890 NETDATA.morrisInitialize = function(callback) {
891 if(typeof netdataStopMorris == 'undefined') {
893 // morris requires raphael
894 if(!NETDATA.chartLibraries.raphael.initialized) {
895 if(NETDATA.chartLibraries.raphael.enabled) {
896 NETDATA.raphaelInitialize(function() {
897 NETDATA.morrisInitialize(callback);
901 NETDATA.chartLibraries.morris.enabled = false;
902 if(typeof callback == "function")
907 var fileref = document.createElement("link");
908 fileref.setAttribute("rel", "stylesheet");
909 fileref.setAttribute("type", "text/css");
910 fileref.setAttribute("href", NETDATA.morris_css);
912 if (typeof fileref != "undefined")
913 document.getElementsByTagName("head")[0].appendChild(fileref);
915 $.getScript(NETDATA.morris_js)
917 NETDATA.registerChartLibrary('morris', NETDATA.morris_js);
920 NETDATA.error(100, NETDATA.morris_js);
923 if(typeof callback == "function")
928 NETDATA.chartLibraries.morris.enabled = false;
929 if(typeof callback == "function")
934 NETDATA.morrisChartUpdate = function(element, data) {
935 var self = $(element);
936 var morris = self.data('morris-instance');
938 if(typeof data.update_every != 'undefined')
939 self.data('update-every', data.update_every * 1000);
942 console.log('updating morris');
943 morris.setData(data.data);
946 console.log('not updating morris');
949 NETDATA.morrisChartCreate = function(element, data) {
950 var self = $(element);
951 var chart = self.data('chart');
953 var uuid = NETDATA.guid();
954 self.html('<div id="' + uuid + '" style="width: ' + self.data('calculated-width') + 'px; height: ' + self.data('calculated-height') + 'px;"></div>');
956 // remove the 'time' element from the labels
957 data.labels.splice(0, 1);
970 continuousLine: false,
971 behaveLikeLine: false
975 if(chart.chart_type == 'line')
976 morris = new Morris.Line(options);
978 else if(chart.chart_type == 'area') {
979 options.behaveLikeLine = true;
980 morris = new Morris.Area(options);
983 morris = new Morris.Area(options);
985 self.data('morris-instance', morris)
986 .data('created', true);
989 // ----------------------------------------------------------------------------------------------------------------
992 NETDATA.raphaelInitialize = function(callback) {
993 if(typeof netdataStopRaphael == 'undefined') {
994 $.getScript(NETDATA.raphael_js)
996 NETDATA.registerChartLibrary('raphael', NETDATA.raphael_js);
999 NETDATA.error(100, NETDATA.raphael_js);
1001 .always(function() {
1002 if(typeof callback == "function")
1007 NETDATA.chartLibraries.raphael.enabled = false;
1008 if(typeof callback == "function")
1013 NETDATA.raphaelChartUpdate = function(element, data) {
1014 var self = $(element);
1016 self.raphael(data, {
1017 width: self.data('calculated-width'),
1018 height: self.data('calculated-height')
1022 NETDATA.raphaelChartCreate = function(element, data) {
1023 var self = $(element);
1025 self.raphael(data, {
1026 width: self.data('calculated-width'),
1027 height: self.data('calculated-height')
1029 .data('created', true);
1032 // ----------------------------------------------------------------------------------------------------------------
1035 NETDATA.googleInitialize = function(callback) {
1036 if(typeof netdataStopGoogleCharts == 'undefined') {
1037 $.getScript(NETDATA.google_js)
1039 NETDATA.registerChartLibrary('google', NETDATA.google_js);
1041 google.load('visualization', '1.1', {
1042 'packages': ['corechart', 'controls'],
1043 'callback': callback
1047 NETDATA.error(100, NETDATA.google_js);
1048 if(typeof callback == "function")
1053 NETDATA.chartLibraries.google.enabled = false;
1054 if(typeof callback == "function")
1059 NETDATA.googleChartUpdate = function(element, data) {
1060 var self = $(element);
1061 var gchart = self.data('google-instance');
1062 var options = self.data('google-options');
1064 if(typeof data.update_every != 'undefined')
1065 self.data('update-every', data.update_every * 1000);
1067 var datatable = new google.visualization.DataTable(data);
1069 gchart.draw(datatable, options);
1072 NETDATA.googleChartCreate = function(element, data) {
1073 var self = $(element);
1074 var chart = self.data('chart');
1076 var datatable = new google.visualization.DataTable(data);
1080 // do not set width, height - the chart resizes itself
1081 //width: self.data('calculated-width'),
1082 //height: self.data('calculated-height'),
1087 // title: "Time of Day",
1088 // format:'HH:mm:ss',
1089 viewWindowMode: 'maximized',
1101 viewWindowMode: 'pretty',
1116 focusTarget: 'category',
1123 titlePosition: 'out',
1134 curveType: 'function',
1139 var uuid = NETDATA.guid();
1140 self.html('<div id="' + uuid + '" style="width: 100%; height: 100%;"></div>');
1142 switch(chart.chart_type) {
1144 options.vAxis.viewWindowMode = 'maximized';
1145 gchart = new google.visualization.AreaChart(document.getElementById(uuid));
1149 options.isStacked = true;
1150 options.areaOpacity = 0.85;
1151 options.vAxis.viewWindowMode = 'maximized';
1152 options.vAxis.minValue = null;
1153 options.vAxis.maxValue = null;
1154 gchart = new google.visualization.AreaChart(document.getElementById(uuid));
1159 options.lineWidth = 2;
1160 gchart = new google.visualization.LineChart(document.getElementById(uuid));
1164 gchart.draw(datatable, options);
1166 self.data('google-instance', gchart)
1167 .data('google-options', options)
1169 .data('created', true);
1172 // ----------------------------------------------------------------------------------------------------------------
1173 // Charts Libraries Registration
1175 NETDATA.chartLibraries = {
1177 initialize: NETDATA.dygraphInitialize,
1178 create: NETDATA.dygraphChartCreate,
1179 update: NETDATA.dygraphChartUpdate,
1184 pixels_per_point: 2,
1185 detects_dimensions_on_update: false
1188 initialize: NETDATA.sparklineInitialize,
1189 create: NETDATA.sparklineChartCreate,
1190 update: NETDATA.sparklineChartUpdate,
1194 options: 'flip|min2max',
1195 pixels_per_point: 2,
1196 detects_dimensions_on_update: false
1199 initialize: NETDATA.peityInitialize,
1200 create: NETDATA.peityChartCreate,
1201 update: NETDATA.peityChartUpdate,
1205 options: 'null2zero|flip|min2max',
1206 pixels_per_point: 2,
1207 detects_dimensions_on_update: false
1210 initialize: NETDATA.morrisInitialize,
1211 create: NETDATA.morrisChartCreate,
1212 update: NETDATA.morrisChartUpdate,
1216 options: 'objectrows|ms',
1217 pixels_per_point: 10,
1218 detects_dimensions_on_update: false
1221 initialize: NETDATA.googleInitialize,
1222 create: NETDATA.googleChartCreate,
1223 update: NETDATA.googleChartUpdate,
1226 format: 'datatable',
1228 pixels_per_point: 2,
1229 detects_dimensions_on_update: true
1232 initialize: NETDATA.raphaelInitialize,
1233 create: NETDATA.raphaelChartCreate,
1234 update: NETDATA.raphaelChartUpdate,
1239 pixels_per_point: 1,
1240 detects_dimensions_on_update: false
1244 NETDATA.registerChartLibrary = function(library, url) {
1245 console.log("registering chart library: " + library);
1247 NETDATA.chartLibraries[library].url = url;
1248 NETDATA.chartLibraries[library].initialized = true;
1249 NETDATA.chartLibraries[library].enabled = true;
1251 console.log(NETDATA.chartLibraries);
1254 // ----------------------------------------------------------------------------------------------------------------
1255 // load all libraries and initialize
1257 NETDATA.errorReset();
1259 NETDATA._loadjQuery(function() {
1260 $.getScript(NETDATA.serverDefault + 'lib/visible.js').then(function() {