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,
98 fast_render_timeframe: 200 // render continously for these many ms
102 if(NETDATA.options.debug) console.log('welcome to NETDATA');
105 // ----------------------------------------------------------------------------------------------------------------
108 NETDATA.errorCodes = {
109 100: { message: "Cannot load chart library", alert: true },
110 101: { message: "Cannot load jQuery", alert: true },
111 402: { message: "Chart library not found", alert: false },
112 403: { message: "Chart library not enabled/is failed", alert: false },
113 404: { message: "Chart not found", alert: false }
115 NETDATA.errorLast = {
121 NETDATA.error = function(code, msg) {
122 NETDATA.errorLast.code = code;
123 NETDATA.errorLast.message = msg;
124 NETDATA.errorLast.datetime = new Date().getTime();
126 console.log("ERROR " + code + ": " + NETDATA.errorCodes[code].message + ": " + msg);
128 if(NETDATA.errorCodes[code].alert)
129 alert("ERROR " + code + ": " + NETDATA.errorCodes[code].message + ": " + msg);
132 NETDATA.errorReset = function() {
133 NETDATA.errorLast.code = 0;
134 NETDATA.errorLast.message = "You are doing fine!";
135 NETDATA.errorLast.datetime = 0;
138 NETDATA.messageInABox = function(element, message) {
142 if(NETDATA.options.debug)
143 bgcolor = " background-color: lightgrey;";
145 element.innerHTML = '<div style="overflow: hidden;' + bgcolor + ' width: 100%; height: 100%;"><small>'
149 self.data('created', false);
152 // ----------------------------------------------------------------------------------------------------------------
153 // Load a script without jquery
154 // This is used to load jquery - after it is loaded, we use jquery
156 NETDATA._loadjQuery = function(callback) {
157 if(typeof jQuery == 'undefined') {
158 var script = document.createElement('script');
159 script.type = 'text/javascript';
161 script.src = NETDATA.jQuery;
163 // script.onabort = onError;
164 script.onerror = function(err, t) { NETDATA.error(101, NETDATA.jQuery); };
165 if(typeof callback == "function")
166 script.onload = callback;
168 var s = document.getElementsByTagName('script')[0];
169 s.parentNode.insertBefore(script, s);
171 else if(typeof callback == "function")
175 NETDATA.generateChartDataURL = function() {
178 var chart = self.data('chart');
179 var host = self.data('host') || NETDATA.chartDefaults.host;
180 var width = self.width();
181 var height = self.height();
182 var method = self.data('method') || NETDATA.chartDefaults.method;
183 var after = self.data('after') || NETDATA.chartDefaults.after;
184 var before = self.data('before') || NETDATA.chartDefaults.before;
185 var library = self.data('chart-library') || NETDATA.chartDefaults.library;
186 var dimensions = self.data('dimensions') || null;
187 var pixels_per_point = self.data('pixels-per-point') || NETDATA.chartLibraries[library].pixels_per_point;
189 // force an options provided detail
190 if(pixels_per_point < NETDATA.options.current.pixels_per_point)
191 pixels_per_point = NETDATA.options.current.pixels_per_point
193 var points = self.data('points') || Math.round(width / pixels_per_point);
195 // build the data URL
196 var url = host + chart.data_url;
197 url += "&format=" + NETDATA.chartLibraries[library].format;
198 url += "&points=" + points.toString();
199 url += "&options=" + NETDATA.chartLibraries[library].options;
200 url += "&group=" + method;
203 url += "&after=" + after.toString();
206 url += "&before=" + before.toString();
209 url += "&dimensions=" + dimensions;
211 self.data('calculated-width', width)
212 .data('calculated-height', height)
213 .data('calculated-points', points)
214 .data('calculated-url', url);
216 if(NETDATA.options.debug) console.log('generateChartDataURL(): ' + url + ' WxH:' + width + 'x' + height + ' points: ' + points + ' library: ' + library);
220 NETDATA.validateDomCharts = function(targets, index, callback) {
221 if(NETDATA.options.debug) console.log('validateDomCharts() working on ' + index);
223 var target = targets.get(index);
225 if(NETDATA.options.debug) console.log('validateDomCharts(): all ' + (index - 1) + ' charts parsed.');
226 if(typeof callback == 'function') callback();
229 var self = $(target);
230 if(!self.data('prepared')) {
231 self.data('prepared', true)
233 .data('created', false)
234 .data('enabled', false);
236 var id = self.data('netdata');
237 var host = self.data('host') || NETDATA.chartDefaults.host;
238 var library = self.data('chart-library') || NETDATA.chartDefaults.library;
240 if(NETDATA.options.debug) console.log('validateDomCharts() parsing ' + id + ' of type ' + library);
242 if(typeof NETDATA.chartLibraries[library] == 'undefined') {
243 NETDATA.error(402, library);
244 NETDATA.messageInABox(target, 'chart library "' + library + '" is not found');
245 NETDATA.validateDomCharts(targets, ++index, callback);
247 else if(!NETDATA.chartLibraries[library].enabled) {
248 NETDATA.error(403, library);
249 NETDATA.messageInABox(target, 'chart library "' + library + '" is not enabled');
250 NETDATA.validateDomCharts(targets, ++index, callback);
252 else if(!NETDATA.chartLibraries[library].initialized) {
253 self.data('prepared', false);
254 NETDATA.chartLibraries[library].initialize(function() {
255 NETDATA.validateDomCharts(targets, index, callback);
259 var url = host + "/api/v1/chart?chart=" + id;
265 .done(function(chart) {
266 self.data('chart', chart)
267 .data('update-every', chart.update_every * 1000)
268 .data('enabled', true)
270 .data('chart-library', library);
273 NETDATA.error(404, url);
274 NETDATA.messageInABox(target, 'chart "' + id + '" not found on url "' + url + '"');
277 NETDATA.validateDomCharts(targets, ++index, callback);
282 NETDATA.validateDomCharts(targets, ++index, callback);
287 NETDATA.sizeDomCharts = function(targets, index, callback) {
288 // this is used to quickly size all charts to their size
290 if(NETDATA.options.debug) console.log('sizeDomCharts() working on ' + index);
292 var target = targets.get(index);
294 if(NETDATA.options.debug) console.log('sizeDomCharts(): all ' + (index - 1) + ' charts sized.');
295 if(typeof callback == 'function') callback();
298 var self = $(target);
300 var id = self.data('netdata');
301 var width = self.data('width') || NETDATA.chartDefaults.width;
302 var height = self.data('height') || NETDATA.chartDefaults.height;
304 self.css('width', width)
305 .css('height', height)
306 .css('display', 'inline-block')
307 .css('overflow', 'hidden');
309 NETDATA.messageInABox(target, 'chart "' + id + '" is loading...');
310 NETDATA.sizeDomCharts(targets, ++index, callback);
314 NETDATA.getDomCharts = function(callback) {
315 NETDATA.options.updated_dom = 0;
317 NETDATA.options.targets = $('div[data-netdata]').filter(':visible')
318 .bind('create', function(event, data) {
321 if(NETDATA.options.debug)
322 NETDATA.chartLibraries[self.data('chart-library')].create(this, data);
325 NETDATA.chartLibraries[self.data('chart-library')].create(this, data);
328 NETDATA.messageInABox(this, 'chart "' + self.data('netdata') + '" failed to be created as ' + self.data('chart-library'));
329 self.data('created', false);
333 .bind('update', function(event, data) {
335 if(NETDATA.options.debug)
336 NETDATA.chartLibraries[self.data('chart-library')].update(this, data);
339 NETDATA.chartLibraries[self.data('chart-library')].update(this, data);
342 NETDATA.messageInABox(this, 'chart "' + self.data('netdata') + '" failed to be updated as ' + self.data('chart-library'));
343 self.data('created', false);
348 if(NETDATA.options.debug)
349 console.log('DOM updated - there are ' + NETDATA.options.targets.length + ' charts on page.');
351 NETDATA.sizeDomCharts(NETDATA.options.targets, 0, function() {
352 NETDATA.validateDomCharts(NETDATA.options.targets, 0, callback);
356 NETDATA.init = function() {
357 // this should be called only once
358 NETDATA.getDomCharts(function() {
359 NETDATA.chartRefresher(0);
363 // ----------------------------------------------------------------------------------------------------------------
365 //var chart = function() {
368 //chart.prototype.color = function() {
372 //var c = new chart();
375 NETDATA.chartValuesDownloader = function(element, callback) {
376 var self = $(element);
377 var last = self.data('updated') || 0;
378 var every = self.data('update-every') || 1;
380 // check if this chart has to be refreshed now
381 var now = new Date().getTime();
382 if(last + every > now) {
383 console.log(self.data('netdata') + ' too soon - skipping.');
384 if(typeof callback == 'function') callback();
386 else if(!self.visible(true)) {
387 console.log(self.data('netdata') + ' is NOT visible.');
388 if(typeof callback == 'function') callback();
391 console.log(self.data('netdata') + ' is visible, downloading data...');
393 url: NETDATA.generateChartDataURL.call(element), // self.data('chart-url'),
396 .then(function(data) {
397 var started = new Date().getTime();
399 if(self.data('created')) {
400 console.log('updating ' + self.data('chart-library') + ' chart ' + self.data('netdata'));
401 self.trigger('update', [data]);
402 // NETDATA.chartLibraries[self.data('chart-library')].update(element, data);
405 console.log('creating ' + self.data('chart-library') + ' chart ' + self.data('netdata'));
406 self.trigger('create', [data]);
407 //NETDATA.chartLibraries[self.data('chart-library')].create(element, data);
408 self.data('created', true);
411 var ended = new Date().getTime();
412 self.data('updated', ended);
414 var dt = ended - started;
416 self.data('refresh-dt', dt);
417 var element_name = self.data('dt-element-name') || null;
419 var element = document.getElementById(element_name) || null;
421 element.innerHTML = dt.toString();
426 NETDATA.messageInABox(element, 'cannot download chart "' + self.data('netdata') + '" values from url "' + self.data('chart-url') + '"');
429 if(typeof callback == 'function') callback();
434 NETDATA.chartRefresher = function(index) {
435 // if(NETDATA.options.debug) console.log('NETDATA.chartRefresher(<targets, ' + index + ')');
437 now = new Date().getTime();
439 if(NETDATA.options.updated_dom) {
440 NETDATA.getDomCharts(function() {
441 NETDATA.chartRefresher(0);
445 var target = NETDATA.options.targets.get(index);
447 if(NETDATA.options.debug) console.log('waiting to restart main loop...');
448 NETDATA.options.last_paused = now;
450 setTimeout(function() {
451 NETDATA.chartRefresher(0);
452 }, NETDATA.options.current.idle_between_loops);
455 var self = $(target);
456 if(!self.data('enabled')) {
457 NETDATA.chartRefresher(++index);
460 if(now - NETDATA.options.last_paused < NETDATA.options.current.fast_render_timeframe) {
461 if(NETDATA.options.debug) console.log('fast rendering...');
463 NETDATA.chartValuesDownloader(target, function() {
464 NETDATA.chartRefresher(++index);
468 if(NETDATA.options.debug) console.log('waiting for next refresh...');
469 NETDATA.options.last_paused = now;
471 setTimeout(function() {
472 NETDATA.chartValuesDownloader(target, function() {
473 NETDATA.chartRefresher(++index);
475 }, NETDATA.options.current.idle_between_charts);
482 NETDATA.guid = function() {
484 return Math.floor((1 + Math.random()) * 0x10000)
489 return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
492 // ----------------------------------------------------------------------------------------------------------------
495 NETDATA.peityInitialize = function(callback) {
496 if(typeof netdataStopPeity == 'undefined') {
497 $.getScript(NETDATA.peity_js)
499 NETDATA.registerChartLibrary('peity', NETDATA.peity_js);
502 NETDATA.error(100, NETDATA.peity_js);
505 if(typeof callback == "function")
510 NETDATA.chartLibraries.peity.enabled = false;
511 if(typeof callback == "function")
516 NETDATA.peityChartUpdate = function(element, data) {
517 var self = $(element);
518 var instance = self.data('peity-instance');
519 var ins = $(instance);
522 // peity.change() does not accept options
523 // to pass width and height
525 ins.peity('line', { width: self.data('calculated-width'), height: self.data('calculated-height') })
528 NETDATA.peityChartCreate = function(element, data) {
529 var self = $(element);
531 var uuid = NETDATA.guid();
532 element.innerHTML = '<div id="' + uuid + '">' + data + '</div>';
533 var instance = document.getElementById(uuid);
534 var ins = $(instance);
536 ins.peity('line', { width: self.data('calculated-width'), height: self.data('calculated-height') })
538 self.data('peity-uuid', uuid)
539 .data('peity-instance', instance)
540 .data('created', true);
543 // ----------------------------------------------------------------------------------------------------------------
546 NETDATA.sparklineInitialize = function(callback) {
547 if(typeof netdataStopSparkline == 'undefined') {
548 $.getScript(NETDATA.sparkline_js)
550 NETDATA.registerChartLibrary('sparkline', NETDATA.sparkline_js);
553 NETDATA.error(100, NETDATA.sparkline_js);
556 if(typeof callback == "function")
561 NETDATA.chartLibraries.sparkline.enabled = false;
562 if(typeof callback == "function")
567 NETDATA.sparklineChartUpdate = function(element, data) {
568 var self = $(element);
569 var options = self.data('sparkline-options');
570 options.width = self.data('calculated-width');
571 options.height = self.data('calculated-height');
572 self.sparkline(data, options);
575 NETDATA.sparklineChartCreate = function(element, data) {
576 var self = $(element);
577 var chart = self.data('chart');
578 var type = self.data('sparkline-type') || 'line';
579 var lineColor = self.data('sparkline-lineColor') || undefined;
580 var fillColor = self.data('sparkline-fillColor') || (chart.chart_type == 'line')?'#FFF':undefined;
581 var chartRangeMin = self.data('sparkline-chartRangeMin') || undefined;
582 var chartRangeMax = self.data('sparkline-chartRangeMax') || undefined;
583 var composite = self.data('sparkline-composite') || undefined;
584 var enableTagOptions = self.data('sparkline-enableTagOptions') || undefined;
585 var tagOptionPrefix = self.data('sparkline-tagOptionPrefix') || undefined;
586 var tagValuesAttribute = self.data('sparkline-tagValuesAttribute') || undefined;
587 var disableHiddenCheck = self.data('sparkline-disableHiddenCheck') || undefined;
588 var defaultPixelsPerValue = self.data('sparkline-defaultPixelsPerValue') || undefined;
589 var spotColor = self.data('sparkline-spotColor') || undefined;
590 var minSpotColor = self.data('sparkline-minSpotColor') || undefined;
591 var maxSpotColor = self.data('sparkline-maxSpotColor') || undefined;
592 var spotRadius = self.data('sparkline-spotRadius') || undefined;
593 var valueSpots = self.data('sparkline-valueSpots') || undefined;
594 var highlightSpotColor = self.data('sparkline-highlightSpotColor') || undefined;
595 var highlightLineColor = self.data('sparkline-highlightLineColor') || undefined;
596 var lineWidth = self.data('sparkline-lineWidth') || undefined;
597 var normalRangeMin = self.data('sparkline-normalRangeMin') || undefined;
598 var normalRangeMax = self.data('sparkline-normalRangeMax') || undefined;
599 var drawNormalOnTop = self.data('sparkline-drawNormalOnTop') || undefined;
600 var xvalues = self.data('sparkline-xvalues') || undefined;
601 var chartRangeClip = self.data('sparkline-chartRangeClip') || undefined;
602 var xvalues = self.data('sparkline-xvalues') || undefined;
603 var chartRangeMinX = self.data('sparkline-chartRangeMinX') || undefined;
604 var chartRangeMaxX = self.data('sparkline-chartRangeMaxX') || undefined;
605 var disableInteraction = self.data('sparkline-disableInteraction') || false;
606 var disableTooltips = self.data('sparkline-disableTooltips') || false;
607 var disableHighlight = self.data('sparkline-disableHighlight') || false;
608 var highlightLighten = self.data('sparkline-highlightLighten') || 1.4;
609 var highlightColor = self.data('sparkline-highlightColor') || undefined;
610 var tooltipContainer = self.data('sparkline-tooltipContainer') || undefined;
611 var tooltipClassname = self.data('sparkline-tooltipClassname') || undefined;
612 var tooltipFormat = self.data('sparkline-tooltipFormat') || undefined;
613 var tooltipPrefix = self.data('sparkline-tooltipPrefix') || undefined;
614 var tooltipSuffix = self.data('sparkline-tooltipSuffix') || ' ' + chart.units;
615 var tooltipSkipNull = self.data('sparkline-tooltipSkipNull') || true;
616 var tooltipValueLookups = self.data('sparkline-tooltipValueLookups') || undefined;
617 var tooltipFormatFieldlist = self.data('sparkline-tooltipFormatFieldlist') || undefined;
618 var tooltipFormatFieldlistKey = self.data('sparkline-tooltipFormatFieldlistKey') || undefined;
619 var numberFormatter = self.data('sparkline-numberFormatter') || function(n){ return n.toFixed(2); };
620 var numberDigitGroupSep = self.data('sparkline-numberDigitGroupSep') || undefined;
621 var numberDecimalMark = self.data('sparkline-numberDecimalMark') || undefined;
622 var numberDigitGroupCount = self.data('sparkline-numberDigitGroupCount') || undefined;
623 var animatedZooms = self.data('sparkline-animatedZooms') || false;
627 lineColor: lineColor,
628 fillColor: fillColor,
629 chartRangeMin: chartRangeMin,
630 chartRangeMax: chartRangeMax,
631 composite: composite,
632 enableTagOptions: enableTagOptions,
633 tagOptionPrefix: tagOptionPrefix,
634 tagValuesAttribute: tagValuesAttribute,
635 disableHiddenCheck: disableHiddenCheck,
636 defaultPixelsPerValue: defaultPixelsPerValue,
637 spotColor: spotColor,
638 minSpotColor: minSpotColor,
639 maxSpotColor: maxSpotColor,
640 spotRadius: spotRadius,
641 valueSpots: valueSpots,
642 highlightSpotColor: highlightSpotColor,
643 highlightLineColor: highlightLineColor,
644 lineWidth: lineWidth,
645 normalRangeMin: normalRangeMin,
646 normalRangeMax: normalRangeMax,
647 drawNormalOnTop: drawNormalOnTop,
649 chartRangeClip: chartRangeClip,
650 chartRangeMinX: chartRangeMinX,
651 chartRangeMaxX: chartRangeMaxX,
652 disableInteraction: disableInteraction,
653 disableTooltips: disableTooltips,
654 disableHighlight: disableHighlight,
655 highlightLighten: highlightLighten,
656 highlightColor: highlightColor,
657 tooltipContainer: tooltipContainer,
658 tooltipClassname: tooltipClassname,
659 tooltipChartTitle: chart.title,
660 tooltipFormat: tooltipFormat,
661 tooltipPrefix: tooltipPrefix,
662 tooltipSuffix: tooltipSuffix,
663 tooltipSkipNull: tooltipSkipNull,
664 tooltipValueLookups: tooltipValueLookups,
665 tooltipFormatFieldlist: tooltipFormatFieldlist,
666 tooltipFormatFieldlistKey: tooltipFormatFieldlistKey,
667 numberFormatter: numberFormatter,
668 numberDigitGroupSep: numberDigitGroupSep,
669 numberDecimalMark: numberDecimalMark,
670 numberDigitGroupCount: numberDigitGroupCount,
671 animatedZooms: animatedZooms,
672 width: self.data('calculated-width'),
673 height: self.data('calculated-height')
676 var uuid = NETDATA.guid();
677 element.innerHTML = '<div style="display: inline-block; position: relative;" id="' + uuid + '"></div>';
678 var div = document.getElementById(uuid);
680 self.sparkline(data, options);
681 self.data('sparkline-options', options)
683 .data('created', true);
686 // ----------------------------------------------------------------------------------------------------------------
689 NETDATA.dygraphAllCharts = [];
690 NETDATA.dygraphInitSync = function(callback) {
691 //$.getScript(NETDATA.serverDefault + 'dygraph-synchronizer.js')
692 // .always(function() {
693 if(typeof callback == "function")
698 NETDATA.dygraphSync = null;
699 NETDATA.dygraphSyncAll = function() {
700 if(NETDATA.dygraphSync) {
701 NETDATA.dygraphSync.detach();
702 NETDATA.dygraphSync = null;
705 NETDATA.dygraphSync = Dygraph.synchronize(NETDATA.dygraphAllCharts, {
711 NETDATA.dygraphInitialize = function(callback) {
712 if(typeof netdataStopDygraph == 'undefined') {
713 $.getScript(NETDATA.dygraph_js)
715 NETDATA.registerChartLibrary('dygraph', NETDATA.dygraph_js);
718 NETDATA.error(100, NETDATA.dygraph_js);
721 NETDATA.dygraphInitSync(callback);
725 NETDATA.chartLibraries.dygraph.enabled = false;
726 if(typeof callback == "function")
731 NETDATA.dygraphChartUpdate = function(element, data) {
732 var self = $(element);
733 var dygraph = self.data('dygraph-instance');
735 if(typeof data.update_every != 'undefined')
736 self.data('update-every', data.update_every * 1000);
738 if(dygraph != null) {
739 console.log('updating dygraphs');
740 dygraph.updateOptions({
743 labelsDivWidth: self.width() - 70
747 console.log('not updating dygraphs');
750 NETDATA.dygraphChartCreate = function(element, data) {
751 var self = $(element);
752 var chart = self.data('chart');
753 var title = self.data('dygraph-title') || chart.title;
754 var titleHeight = self.data('dygraph-titleHeight') || 20;
755 var labelsDiv = self.data('dygraph-labelsDiv') || undefined;
756 var connectSeparatedPoints = self.data('dygraph-connectSeparatedPoints') || false;
757 var yLabelWidth = self.data('dygraph-yLabelWidth') || 12;
758 var stackedGraph = self.data('dygraph-stackedGraph') || (chart.chart_type == 'stacked')?true:false;
759 var stackedGraphNaNFill = self.data('dygraph-stackedGraphNaNFill') || 'none';
760 var hideOverlayOnMouseOut = self.data('dygraph-hideOverlayOnMouseOut') || true;
761 var fillGraph = self.data('dygraph-fillGraph') || (chart.chart_type == 'area')?true:false;
762 var drawPoints = self.data('dygraph-drawPoints') || false;
763 var labelsDivStyles = self.data('dygraph-labelsDivStyles') || { 'fontSize':'10px' };
764 // var labelsDivWidth = self.data('dygraph-labelsDivWidth') || 250;
765 var labelsDivWidth = self.width() - 70;
766 var labelsSeparateLines = self.data('dygraph-labelsSeparateLines') || false;
767 var labelsShowZeroValues = self.data('dygraph-labelsShowZeroValues') || true;
768 var legend = self.data('dygraph-legend') || 'onmouseover';
769 var showLabelsOnHighlight = self.data('dygraph-showLabelsOnHighlight') || true;
770 var gridLineColor = self.data('dygraph-gridLineColor') || '#EEE';
771 var axisLineColor = self.data('dygraph-axisLineColor') || '#EEE';
772 var maxNumberWidth = self.data('dygraph-maxNumberWidth') || 8;
773 var sigFigs = self.data('dygraph-sigFigs') || null;
774 var digitsAfterDecimal = self.data('dygraph-digitsAfterDecimal') || 2;
775 var axisLabelFontSize = self.data('dygraph-axisLabelFontSize') || 10;
776 var axisLineWidth = self.data('dygraph-axisLineWidth') || 0.3;
777 var drawAxis = self.data('dygraph-drawAxis') || true;
778 var strokeWidth = self.data('dygraph-strokeWidth') || 1.0;
779 var drawGapEdgePoints = self.data('dygraph-drawGapEdgePoints') || true;
780 var colors = self.data('dygraph-colors') || NETDATA.colors;
781 var pointSize = self.data('dygraph-pointSize') || 1;
782 var stepPlot = self.data('dygraph-stepPlot') || false;
783 var strokeBorderColor = self.data('dygraph-strokeBorderColor') || 'white';
784 var strokeBorderWidth = self.data('dygraph-strokeBorderWidth') || (chart.chart_type == 'stacked')?1.0:0.0;
785 var strokePattern = self.data('dygraph-strokePattern') || undefined;
786 var highlightCircleSize = self.data('dygraph-highlightCircleSize') || 3;
787 var highlightSeriesOpts = self.data('dygraph-highlightSeriesOpts') || { strokeWidth: 1.5 };
788 var highlightSeriesBackgroundAlpha = self.data('dygraph-highlightSeriesBackgroundAlpha') || (chart.chart_type == 'stacked')?0.7:0.5;
789 var pointClickCallback = self.data('dygraph-pointClickCallback') || undefined;
790 var showRangeSelector = self.data('dygraph-showRangeSelector') || false;
791 var showRoller = self.data('dygraph-showRoller') || false;
792 var valueFormatter = self.data('dygraph-valueFormatter') || undefined; //function(x){ return x.toFixed(2); };
793 var rightGap = self.data('dygraph-rightGap') || 5;
794 var drawGrid = self.data('dygraph-drawGrid') || true;
795 var drawXGrid = self.data('dygraph-drawXGrid') || undefined;
796 var drawYGrid = self.data('dygraph-drawYGrid') || undefined;
797 var gridLinePattern = self.data('dygraph-gridLinePattern') || null;
798 var gridLineWidth = self.data('dygraph-gridLineWidth') || 0.3;
802 titleHeight: titleHeight,
804 yLabelWidth: yLabelWidth,
805 connectSeparatedPoints: connectSeparatedPoints,
806 drawPoints: drawPoints,
807 fillGraph: fillGraph,
808 stackedGraph: stackedGraph,
809 stackedGraphNaNFill: stackedGraphNaNFill,
811 drawXGrid: drawXGrid,
812 drawYGrid: drawYGrid,
813 gridLinePattern: gridLinePattern,
814 gridLineWidth: gridLineWidth,
815 gridLineColor: gridLineColor,
816 axisLineColor: axisLineColor,
817 axisLineWidth: axisLineWidth,
819 hideOverlayOnMouseOut: hideOverlayOnMouseOut,
820 labelsDiv: labelsDiv,
821 labelsDivStyles: labelsDivStyles,
822 labelsDivWidth: labelsDivWidth,
823 labelsSeparateLines: labelsSeparateLines,
824 labelsShowZeroValues: labelsShowZeroValues,
828 showLabelsOnHighlight: showLabelsOnHighlight,
829 maxNumberWidth: maxNumberWidth,
831 digitsAfterDecimal: digitsAfterDecimal,
832 axisLabelFontSize: axisLabelFontSize,
834 strokeWidth: strokeWidth,
835 drawGapEdgePoints: drawGapEdgePoints,
836 pointSize: pointSize,
838 strokeBorderColor: strokeBorderColor,
839 strokeBorderWidth: strokeBorderWidth,
840 strokePattern: strokePattern,
841 highlightCircleSize: highlightCircleSize,
842 highlightSeriesOpts: highlightSeriesOpts,
843 highlightSeriesBackgroundAlpha: highlightSeriesBackgroundAlpha,
844 pointClickCallback: pointClickCallback,
845 showRangeSelector: showRangeSelector,
846 showRoller: showRoller,
847 valueFormatter: valueFormatter,
853 ticker: Dygraph.dateTicker,
854 axisLabelFormatter: function (d, gran) {
855 return Dygraph.zeropad(d.getHours()) + ":" + Dygraph.zeropad(d.getMinutes()) + ":" + Dygraph.zeropad(d.getSeconds());
857 valueFormatter :function (ms) {
858 var d = new Date(ms);
859 return Dygraph.zeropad(d.getHours()) + ":" + Dygraph.zeropad(d.getMinutes()) + ":" + Dygraph.zeropad(d.getSeconds());
868 var uuid = NETDATA.guid();
869 self.html('<div id="' + uuid + '" style="width: 100%; height: 100%;"></div>');
871 var dchart = new Dygraph(document.getElementById(uuid),
874 self.data('dygraph-instance', dchart)
875 .data('dygraph-options', options)
877 .data('created', true);
879 //NETDATA.dygraphAllCharts.push(dchart);
880 //if(NETDATA.dygraphAllCharts.length > 1)
881 // NETDATA.dygraphSyncAll();
884 // ----------------------------------------------------------------------------------------------------------------
887 NETDATA.morrisInitialize = function(callback) {
888 if(typeof netdataStopMorris == 'undefined') {
890 // morris requires raphael
891 if(!NETDATA.chartLibraries.raphael.initialized) {
892 if(NETDATA.chartLibraries.raphael.enabled) {
893 NETDATA.raphaelInitialize(function() {
894 NETDATA.morrisInitialize(callback);
898 NETDATA.chartLibraries.morris.enabled = false;
899 if(typeof callback == "function")
904 var fileref = document.createElement("link");
905 fileref.setAttribute("rel", "stylesheet");
906 fileref.setAttribute("type", "text/css");
907 fileref.setAttribute("href", NETDATA.morris_css);
909 if (typeof fileref != "undefined")
910 document.getElementsByTagName("head")[0].appendChild(fileref);
912 $.getScript(NETDATA.morris_js)
914 NETDATA.registerChartLibrary('morris', NETDATA.morris_js);
917 NETDATA.error(100, NETDATA.morris_js);
920 if(typeof callback == "function")
925 NETDATA.chartLibraries.morris.enabled = false;
926 if(typeof callback == "function")
931 NETDATA.morrisChartUpdate = function(element, data) {
932 var self = $(element);
933 var morris = self.data('morris-instance');
935 if(typeof data.update_every != 'undefined')
936 self.data('update-every', data.update_every * 1000);
939 console.log('updating morris');
940 morris.setData(data.data);
943 console.log('not updating morris');
946 NETDATA.morrisChartCreate = function(element, data) {
947 var self = $(element);
948 var chart = self.data('chart');
950 var uuid = NETDATA.guid();
951 self.html('<div id="' + uuid + '" style="width: ' + self.data('calculated-width') + 'px; height: ' + self.data('calculated-height') + 'px;"></div>');
953 // remove the 'time' element from the labels
954 data.labels.splice(0, 1);
967 continuousLine: false,
968 behaveLikeLine: false
972 if(chart.chart_type == 'line')
973 morris = new Morris.Line(options);
975 else if(chart.chart_type == 'area') {
976 options.behaveLikeLine = true;
977 morris = new Morris.Area(options);
980 morris = new Morris.Area(options);
982 self.data('morris-instance', morris)
983 .data('created', true);
986 // ----------------------------------------------------------------------------------------------------------------
989 NETDATA.raphaelInitialize = function(callback) {
990 if(typeof netdataStopRaphael == 'undefined') {
991 $.getScript(NETDATA.raphael_js)
993 NETDATA.registerChartLibrary('raphael', NETDATA.raphael_js);
996 NETDATA.error(100, NETDATA.raphael_js);
999 if(typeof callback == "function")
1004 NETDATA.chartLibraries.raphael.enabled = false;
1005 if(typeof callback == "function")
1010 NETDATA.raphaelChartUpdate = function(element, data) {
1011 var self = $(element);
1013 self.raphael(data, {
1014 width: self.data('calculated-width'),
1015 height: self.data('calculated-height')
1019 NETDATA.raphaelChartCreate = function(element, data) {
1020 var self = $(element);
1022 self.raphael(data, {
1023 width: self.data('calculated-width'),
1024 height: self.data('calculated-height')
1026 .data('created', true);
1029 // ----------------------------------------------------------------------------------------------------------------
1032 NETDATA.googleInitialize = function(callback) {
1033 if(typeof netdataStopGoogleCharts == 'undefined') {
1034 $.getScript(NETDATA.google_js)
1036 NETDATA.registerChartLibrary('google', NETDATA.google_js);
1038 google.load('visualization', '1.1', {
1039 'packages': ['corechart', 'controls'],
1040 'callback': callback
1044 NETDATA.error(100, NETDATA.google_js);
1045 if(typeof callback == "function")
1050 NETDATA.chartLibraries.google.enabled = false;
1051 if(typeof callback == "function")
1056 NETDATA.googleChartUpdate = function(element, data) {
1057 var self = $(element);
1058 var gchart = self.data('google-instance');
1059 var options = self.data('google-options');
1061 if(typeof data.update_every != 'undefined')
1062 self.data('update-every', data.update_every * 1000);
1064 var datatable = new google.visualization.DataTable(data);
1066 gchart.draw(datatable, options);
1069 NETDATA.googleChartCreate = function(element, data) {
1070 var self = $(element);
1071 var chart = self.data('chart');
1073 var datatable = new google.visualization.DataTable(data);
1077 // do not set width, height - the chart resizes itself
1078 //width: self.data('calculated-width'),
1079 //height: self.data('calculated-height'),
1084 // title: "Time of Day",
1085 // format:'HH:mm:ss',
1086 viewWindowMode: 'maximized',
1098 viewWindowMode: 'pretty',
1113 focusTarget: 'category',
1120 titlePosition: 'out',
1131 curveType: 'function',
1136 var uuid = NETDATA.guid();
1137 self.html('<div id="' + uuid + '" style="width: 100%; height: 100%;"></div>');
1139 switch(chart.chart_type) {
1141 options.vAxis.viewWindowMode = 'maximized';
1142 gchart = new google.visualization.AreaChart(document.getElementById(uuid));
1146 options.isStacked = true;
1147 options.areaOpacity = 0.85;
1148 options.vAxis.viewWindowMode = 'maximized';
1149 options.vAxis.minValue = null;
1150 options.vAxis.maxValue = null;
1151 gchart = new google.visualization.AreaChart(document.getElementById(uuid));
1156 options.lineWidth = 2;
1157 gchart = new google.visualization.LineChart(document.getElementById(uuid));
1161 gchart.draw(datatable, options);
1163 self.data('google-instance', gchart)
1164 .data('google-options', options)
1166 .data('created', true);
1169 // ----------------------------------------------------------------------------------------------------------------
1170 // Charts Libraries Registration
1172 NETDATA.chartLibraries = {
1174 initialize: NETDATA.dygraphInitialize,
1175 create: NETDATA.dygraphChartCreate,
1176 update: NETDATA.dygraphChartUpdate,
1181 pixels_per_point: 2,
1182 detects_dimensions_on_update: false
1185 initialize: NETDATA.sparklineInitialize,
1186 create: NETDATA.sparklineChartCreate,
1187 update: NETDATA.sparklineChartUpdate,
1191 options: 'flip|min2max',
1192 pixels_per_point: 2,
1193 detects_dimensions_on_update: false
1196 initialize: NETDATA.peityInitialize,
1197 create: NETDATA.peityChartCreate,
1198 update: NETDATA.peityChartUpdate,
1202 options: 'null2zero|flip|min2max',
1203 pixels_per_point: 2,
1204 detects_dimensions_on_update: false
1207 initialize: NETDATA.morrisInitialize,
1208 create: NETDATA.morrisChartCreate,
1209 update: NETDATA.morrisChartUpdate,
1213 options: 'objectrows|ms',
1214 pixels_per_point: 10,
1215 detects_dimensions_on_update: false
1218 initialize: NETDATA.googleInitialize,
1219 create: NETDATA.googleChartCreate,
1220 update: NETDATA.googleChartUpdate,
1223 format: 'datatable',
1225 pixels_per_point: 2,
1226 detects_dimensions_on_update: true
1229 initialize: NETDATA.raphaelInitialize,
1230 create: NETDATA.raphaelChartCreate,
1231 update: NETDATA.raphaelChartUpdate,
1236 pixels_per_point: 1,
1237 detects_dimensions_on_update: false
1241 NETDATA.registerChartLibrary = function(library, url) {
1242 console.log("registering chart library: " + library);
1244 NETDATA.chartLibraries[library].url = url;
1245 NETDATA.chartLibraries[library].initialized = true;
1246 NETDATA.chartLibraries[library].enabled = true;
1248 console.log(NETDATA.chartLibraries);
1251 // ----------------------------------------------------------------------------------------------------------------
1252 // load all libraries and initialize
1254 NETDATA.errorReset();
1256 NETDATA._loadjQuery(function() {
1257 $.getScript(NETDATA.serverDefault + 'lib/visible.js').then(function() {