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 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: 20, // the chart height
81 library: 'peity', // 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
95 idle_between_charts: 50,
96 idle_between_loops: 100,
101 if(NETDATA.options.debug) console.log('welcome to NETDATA');
104 // ----------------------------------------------------------------------------------------------------------------
107 NETDATA.errorCodes = {
108 100: { message: "Cannot load chart library", alert: true },
109 101: { message: "Cannot load jQuery", alert: true },
110 402: { message: "Chart library not found", alert: false },
111 404: { message: "Chart not found", alert: false },
113 NETDATA.errorLast = {
119 NETDATA.error = function(code, msg) {
120 NETDATA.errorLast.code = code;
121 NETDATA.errorLast.message = msg;
122 NETDATA.errorLast.datetime = new Date().getTime();
124 console.log("ERROR " + code + ": " + NETDATA.errorCodes[code].message + ": " + msg);
126 if(NETDATA.errorCodes[code].alert)
127 alert("ERROR " + code + ": " + NETDATA.errorCodes[code].message + ": " + msg);
130 NETDATA.errorReset = function() {
131 NETDATA.errorLast.code = 0;
132 NETDATA.errorLast.message = "You are doing fine!";
133 NETDATA.errorLast.datetime = 0;
136 NETDATA.chartContainer = function(element, width, height) {
138 self.css('width', width)
139 .css('height', height)
140 .css('display', 'inline-block')
141 .css('overflow', 'hidden');
144 NETDATA.messageInABox = function(element, width, height, message) {
145 NETDATA.chartContainer(element, width, height);
146 element.innerHTML = '<div style="overflow: hidden; border: 0px; background-color: lightgrey; width: ' + width + '; height: ' + height + ';"><small>'
151 // ----------------------------------------------------------------------------------------------------------------
152 // Load a script without jquery
153 // This is used to load jquery - after it is loaded, we use jquery
155 NETDATA._loadjQuery = function(callback) {
156 if(typeof jQuery == 'undefined') {
157 var script = document.createElement('script');
158 script.type = 'text/javascript';
160 script.src = NETDATA.jQuery;
162 // script.onabort = onError;
163 script.onerror = function(err, t) { NETDATA.error(101, NETDATA.jQuery); };
164 if(typeof callback == "function")
165 script.onload = callback;
167 var s = document.getElementsByTagName('script')[0];
168 s.parentNode.insertBefore(script, s);
170 else if(typeof callback == "function")
174 NETDATA.generateChartDataURL = function(options) {
175 // build the data URL
176 var url = options.host + options.url;
178 url += options.points.toString();
180 url += options.method;
182 url += options.after || "0";
184 url += options.before || "0";
185 url += "&options=" + NETDATA.chartLibraries[options.library].options + '|';
186 url += (options.non_zero)?"nonzero":"";
187 url += "&format=" + NETDATA.chartLibraries[options.library].format;
189 if(options.dimensions)
190 url += "&dimensions=" + options.dimensions;
192 if(NETDATA.options.debug) console.log('generateChartDataURL(' + options + ') = ' + url );
196 NETDATA.parseDomCharts = function(targets, index, callback) {
197 if(NETDATA.options.debug) console.log('parseDomCharts() working on ' + index);
199 var target = targets.get(index);
201 if(NETDATA.options.debug) console.log('parseDomCharts(): all ' + (index - 1) + ' charts parsed.');
202 if(typeof callback == 'function') callback();
205 var self = $(target);
206 if(!self.data('prepared')) {
207 self.data('prepared', true);
209 var id = self.data('netdata');
210 var host = self.data('host') || NETDATA.chartDefaults.host;
211 var width = self.data('width') || NETDATA.chartDefaults.width;
212 var height = self.data('height') || NETDATA.chartDefaults.height;
213 var method = self.data('method') || NETDATA.chartDefaults.method;
214 var after = self.data('after') || NETDATA.chartDefaults.after;
215 var before = self.data('before') || NETDATA.chartDefaults.before;
216 var library = self.data('chart-library') || NETDATA.chartDefaults.library;
217 var dimensions = self.data('dimensions') || null;
219 NETDATA.chartContainer(target, width, height);
220 if(NETDATA.options.debug) console.log('parseDomCharts() parsing ' + id + ' of type ' + library);
222 if(typeof NETDATA.chartLibraries[library] == 'undefined') {
223 self.data('created', false)
225 .data('enabled', false);
227 NETDATA.error(402, library);
228 NETDATA.messageInABox(target, width, height, 'chart library "' + library + '" is not found');
230 NETDATA.parseDomCharts(targets, ++index, callback);
233 var url = host + "/api/v1/chart?chart=" + id;
239 .done(function(chart) {
240 var pixels_per_point = self.data('point-width') || NETDATA.chartLibraries[library].pixels_per_point;
241 var points = self.data('points') || Math.round(width / pixels_per_point);
243 var url = NETDATA.generateChartDataURL({
246 dimensions: dimensions,
255 // done processing of this DIV
256 // store the processing result, in
257 // 'data' sections in the DIV
258 self.data('chart', chart)
259 .data('chart-url', url)
260 .data('update-every', chart.update_every * 1000)
261 .data('created', false)
263 .data('enabled', true)
265 .data('width', width)
266 .data('height', height)
267 .data('method', method)
268 .data('after', after)
269 .data('before', before)
270 .data('chart-library', library)
271 .data('dimensions', dimensions)
274 NETDATA.messageInABox(target, width, height, 'chart "' + id + '" is loading...');
277 self.data('created', false)
278 .data('enabled', false);
280 NETDATA.error(404, url);
281 NETDATA.messageInABox(target, width, height, 'chart "' + id + '" not found on url "' + url + '"');
284 self.data('updated', 0);
285 NETDATA.parseDomCharts(targets, ++index, callback);
292 NETDATA.domUpdated = function(callback) {
293 NETDATA.options.updated_dom = 0;
295 NETDATA.options.targets = $('div[data-netdata]') // .filter(':visible')
296 .bind('create', function(event, data) {
299 NETDATA.chartLibraries[self.data('chart-library')].create(this, data);
302 NETDATA.messageInABox(this, self.data('width'), self.data('height'), 'chart "' + id + '" failed to be created as ' + self.data('chart-library'));
305 .bind('update', function(event, data) {
308 NETDATA.chartLibraries[self.data('chart-library')].update(this, data);
311 NETDATA.messageInABox(this, self.data('width'), self.data('height'), 'chart "' + id + '" failed to be updated as ' + self.data('chart-library'));
315 if(NETDATA.options.debug)
316 console.log('DOM updated - there are ' + NETDATA.options.targets.length + ' charts on page.');
318 NETDATA.parseDomCharts(NETDATA.options.targets, 0, callback);
321 NETDATA.init = function() {
322 NETDATA.domUpdated(function() {
323 // done processing all netdata DIVs in this page
324 // call the refresh handler
327 NETDATA.chartRefresher(0);
331 // ----------------------------------------------------------------------------------------------------------------
333 //var chart = function() {
336 //chart.prototype.color = function() {
340 //var c = new chart();
343 NETDATA.chartValuesDownloader = function(element, callback) {
344 var self = $(element);
345 var last = self.data('updated') || 0;
346 var every = self.data('update-every') || 1;
348 // check if this chart has to be refreshed now
349 var now = new Date().getTime();
350 if(last + every > now) {
351 console.log(self.data('netdata') + ' too soon - skipping.');
352 if(typeof callback == 'function') callback();
354 else if(!self.visible(true)) {
355 console.log(self.data('netdata') + ' is NOT visible.');
356 if(typeof callback == 'function') callback();
359 console.log(self.data('netdata') + ' is visible, downloading data...');
361 url: self.data('chart-url'),
364 .then(function(data) {
365 var started = new Date().getTime();
367 if(self.data('created')) {
368 console.log('updating ' + self.data('chart-library') + ' chart ' + self.data('netdata'));
369 self.trigger('update', [data]);
370 // NETDATA.chartLibraries[self.data('chart-library')].update(element, data);
373 console.log('creating ' + self.data('chart-library') + ' chart ' + self.data('netdata'));
374 self.trigger('create', [data]);
375 //NETDATA.chartLibraries[self.data('chart-library')].create(element, data);
376 self.data('created', true);
379 var ended = new Date().getTime();
380 self.data('updated', ended);
382 var dt = ended - started;
384 self.data('refresh-dt', dt);
385 var element_name = self.data('dt-element-name') || null;
387 var element = document.getElementById(element_name) || null;
389 element.innerHTML = dt.toString();
394 NETDATA.messageInABox(element, width, height, 'chart "' + id + '" not found on url "' + url + '"');
397 if(typeof callback == 'function') callback();
402 NETDATA.chartRefresher = function(index) {
403 // if(NETDATA.options.debug) console.log('NETDATA.chartRefresher(<targets, ' + index + ')');
405 if(NETDATA.options.updated_dom) {
406 NETDATA.domUpdated(function() {
407 NETDATA.chartRefresher(0);
411 var target = NETDATA.options.targets.get(index);
413 console.log('waiting to restart main loop...');
416 setTimeout(function() {
417 NETDATA.chartRefresher(0);
418 }, NETDATA.options.current.idle_between_loops);
421 var self = $(target);
422 if(!self.data('enabled')) {
423 NETDATA.chartRefresher(++index);
426 setTimeout(function() {
427 NETDATA.chartValuesDownloader(target, function() {
428 NETDATA.chartRefresher(++index);
430 }, NETDATA.options.current.idle_between_charts);
436 NETDATA.guid = function() {
438 return Math.floor((1 + Math.random()) * 0x10000)
443 return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
446 // ----------------------------------------------------------------------------------------------------------------
449 NETDATA.peityInitialize = function(callback) {
450 if(typeof netdataStopPeity == 'undefined') {
451 $.getScript(NETDATA.peity_js)
453 NETDATA.registerChartLibrary('peity', NETDATA.peity_js);
456 NETDATA.error(100, NETDATA.peity_js);
459 if(typeof callback == "function")
463 else if(typeof callback == "function")
467 NETDATA.peityChartUpdate = function(element, data) {
468 var self = $(element);
469 var instance = self.html(data).not('[data-created]');
473 NETDATA.peityChartCreate = function(element, data) {
474 var self = $(element);
475 var width = self.data('width') || NETDATA.chartDefaults.width;
476 var height = self.data('height') || NETDATA.chartDefaults.height;
477 var instance = self.html(data).not('[data-created]');
479 instance.peity('line', {
483 .data('created', true);
486 // ----------------------------------------------------------------------------------------------------------------
489 NETDATA.sparklineInitialize = function(callback) {
490 if(typeof netdataStopSparkline == 'undefined') {
491 $.getScript(NETDATA.sparkline_js)
493 NETDATA.registerChartLibrary('sparkline', NETDATA.sparkline_js);
496 NETDATA.error(100, NETDATA.sparkline_js);
499 if(typeof callback == "function")
503 else if(typeof callback == "function")
507 NETDATA.sparklineChartUpdate = function(element, data) {
508 var self = $(element);
509 var options = self.data('sparkline-options');
510 self.sparkline(data, options);
513 NETDATA.sparklineChartCreate = function(element, data) {
514 var self = $(element);
515 var chart = self.data('chart');
516 var width = self.data('width') || NETDATA.chartDefaults.width;
517 var height = self.data('height') || NETDATA.chartDefaults.height;
518 var type = self.data('sparkline-type') || 'line';
519 var lineColor = self.data('sparkline-lineColor') || undefined;
520 var fillColor = self.data('sparkline-fillColor') || (chart.chart_type == 'line')?'#FFF':undefined;
521 var chartRangeMin = self.data('sparkline-chartRangeMin') || undefined;
522 var chartRangeMax = self.data('sparkline-chartRangeMax') || undefined;
523 var composite = self.data('sparkline-composite') || undefined;
524 var enableTagOptions = self.data('sparkline-enableTagOptions') || undefined;
525 var tagOptionPrefix = self.data('sparkline-tagOptionPrefix') || undefined;
526 var tagValuesAttribute = self.data('sparkline-tagValuesAttribute') || undefined;
527 var disableHiddenCheck = self.data('sparkline-disableHiddenCheck') || undefined;
528 var defaultPixelsPerValue = self.data('sparkline-defaultPixelsPerValue') || undefined;
529 var spotColor = self.data('sparkline-spotColor') || undefined;
530 var minSpotColor = self.data('sparkline-minSpotColor') || undefined;
531 var maxSpotColor = self.data('sparkline-maxSpotColor') || undefined;
532 var spotRadius = self.data('sparkline-spotRadius') || undefined;
533 var valueSpots = self.data('sparkline-valueSpots') || undefined;
534 var highlightSpotColor = self.data('sparkline-highlightSpotColor') || undefined;
535 var highlightLineColor = self.data('sparkline-highlightLineColor') || undefined;
536 var lineWidth = self.data('sparkline-lineWidth') || undefined;
537 var normalRangeMin = self.data('sparkline-normalRangeMin') || undefined;
538 var normalRangeMax = self.data('sparkline-normalRangeMax') || undefined;
539 var drawNormalOnTop = self.data('sparkline-drawNormalOnTop') || undefined;
540 var xvalues = self.data('sparkline-xvalues') || undefined;
541 var chartRangeClip = self.data('sparkline-chartRangeClip') || undefined;
542 var xvalues = self.data('sparkline-xvalues') || undefined;
543 var chartRangeMinX = self.data('sparkline-chartRangeMinX') || undefined;
544 var chartRangeMaxX = self.data('sparkline-chartRangeMaxX') || undefined;
545 var disableInteraction = self.data('sparkline-disableInteraction') || false;
546 var disableTooltips = self.data('sparkline-disableTooltips') || false;
547 var disableHighlight = self.data('sparkline-disableHighlight') || false;
548 var highlightLighten = self.data('sparkline-highlightLighten') || 1.4;
549 var highlightColor = self.data('sparkline-highlightColor') || undefined;
550 var tooltipContainer = self.data('sparkline-tooltipContainer') || undefined;
551 var tooltipClassname = self.data('sparkline-tooltipClassname') || undefined;
552 var tooltipFormat = self.data('sparkline-tooltipFormat') || undefined;
553 var tooltipPrefix = self.data('sparkline-tooltipPrefix') || undefined;
554 var tooltipSuffix = self.data('sparkline-tooltipSuffix') || ' ' + chart.units;
555 var tooltipSkipNull = self.data('sparkline-tooltipSkipNull') || true;
556 var tooltipValueLookups = self.data('sparkline-tooltipValueLookups') || undefined;
557 var tooltipFormatFieldlist = self.data('sparkline-tooltipFormatFieldlist') || undefined;
558 var tooltipFormatFieldlistKey = self.data('sparkline-tooltipFormatFieldlistKey') || undefined;
559 var numberFormatter = self.data('sparkline-numberFormatter') || function(n){ return n.toFixed(2); };
560 var numberDigitGroupSep = self.data('sparkline-numberDigitGroupSep') || undefined;
561 var numberDecimalMark = self.data('sparkline-numberDecimalMark') || undefined;
562 var numberDigitGroupCount = self.data('sparkline-numberDigitGroupCount') || undefined;
563 var animatedZooms = self.data('sparkline-animatedZooms') || false;
567 lineColor: lineColor,
568 fillColor: fillColor,
569 chartRangeMin: chartRangeMin,
570 chartRangeMax: chartRangeMax,
571 composite: composite,
572 enableTagOptions: enableTagOptions,
573 tagOptionPrefix: tagOptionPrefix,
574 tagValuesAttribute: tagValuesAttribute,
575 disableHiddenCheck: disableHiddenCheck,
576 defaultPixelsPerValue: defaultPixelsPerValue,
577 spotColor: spotColor,
578 minSpotColor: minSpotColor,
579 maxSpotColor: maxSpotColor,
580 spotRadius: spotRadius,
581 valueSpots: valueSpots,
582 highlightSpotColor: highlightSpotColor,
583 highlightLineColor: highlightLineColor,
584 lineWidth: lineWidth,
585 normalRangeMin: normalRangeMin,
586 normalRangeMax: normalRangeMax,
587 drawNormalOnTop: drawNormalOnTop,
589 chartRangeClip: chartRangeClip,
590 chartRangeMinX: chartRangeMinX,
591 chartRangeMaxX: chartRangeMaxX,
592 disableInteraction: disableInteraction,
593 disableTooltips: disableTooltips,
594 disableHighlight: disableHighlight,
595 highlightLighten: highlightLighten,
596 highlightColor: highlightColor,
597 tooltipContainer: tooltipContainer,
598 tooltipClassname: tooltipClassname,
599 tooltipChartTitle: chart.title,
600 tooltipFormat: tooltipFormat,
601 tooltipPrefix: tooltipPrefix,
602 tooltipSuffix: tooltipSuffix,
603 tooltipSkipNull: tooltipSkipNull,
604 tooltipValueLookups: tooltipValueLookups,
605 tooltipFormatFieldlist: tooltipFormatFieldlist,
606 tooltipFormatFieldlistKey: tooltipFormatFieldlistKey,
607 numberFormatter: numberFormatter,
608 numberDigitGroupSep: numberDigitGroupSep,
609 numberDecimalMark: numberDecimalMark,
610 numberDigitGroupCount: numberDigitGroupCount,
611 animatedZooms: animatedZooms,
616 var uuid = NETDATA.guid();
617 element.innerHTML = '<div style="display: inline-block; position: relative;" id="' + uuid + '"></div>';
618 var div = document.getElementById(uuid);
620 self.sparkline(data, options);
621 self.data('sparkline-options', options)
623 .data('created', true);
626 // ----------------------------------------------------------------------------------------------------------------
629 NETDATA.dygraphAllCharts = [];
630 NETDATA.dygraphInitSync = function(callback) {
631 //$.getScript(NETDATA.serverDefault + 'dygraph-synchronizer.js')
632 // .always(function() {
633 if(typeof callback == "function")
638 NETDATA.dygraphSync = null;
639 NETDATA.dygraphSyncAll = function() {
640 if(NETDATA.dygraphSync) {
641 NETDATA.dygraphSync.detach();
642 NETDATA.dygraphSync = null;
645 NETDATA.dygraphSync = Dygraph.synchronize(NETDATA.dygraphAllCharts, {
651 NETDATA.dygraphInitialize = function(callback) {
652 if(typeof netdataStopDygraph == 'undefined') {
653 $.getScript(NETDATA.dygraph_js)
655 NETDATA.registerChartLibrary('dygraph', NETDATA.dygraph_js);
658 NETDATA.error(100, NETDATA.dygraph_js);
661 NETDATA.dygraphInitSync(callback);
664 else if(typeof callback == "function")
668 NETDATA.dygraphChartUpdate = function(element, data) {
669 var self = $(element);
670 var dygraph = self.data('dygraph-instance');
672 if(typeof data.update_every != 'undefined')
673 self.data('update-every', data.update_every * 1000);
675 if(dygraph != null) {
676 console.log('updating dygraphs');
677 dygraph.updateOptions( { 'file': data.data, 'labels': data.labels } );
680 console.log('not updating dygraphs');
683 NETDATA.dygraphChartCreate = function(element, data) {
684 var self = $(element);
685 var width = self.data('width') || NETDATA.chartDefaults.width;
686 var height = self.data('height') || NETDATA.chartDefaults.height;
687 var chart = self.data('chart');
688 var title = self.data('dygraph-title') || chart.title;
689 var titleHeight = self.data('dygraph-titleHeight') || 20;
690 var labelsDiv = self.data('dygraph-labelsDiv') || undefined;
691 var connectSeparatedPoints = self.data('dygraph-connectSeparatedPoints') || false;
692 var yLabelWidth = self.data('dygraph-yLabelWidth') || 12;
693 var stackedGraph = self.data('dygraph-stackedGraph') || (chart.chart_type == 'stacked')?true:false;
694 var stackedGraphNaNFill = self.data('dygraph-stackedGraphNaNFill') || 'none';
695 var hideOverlayOnMouseOut = self.data('dygraph-hideOverlayOnMouseOut') || true;
696 var fillGraph = self.data('dygraph-fillGraph') || (chart.chart_type == 'area')?true:false;
697 var drawPoints = self.data('dygraph-drawPoints') || false;
698 var labelsDivStyles = self.data('dygraph-labelsDivStyles') || { 'fontSize':'10' };
699 var labelsDivWidth = self.data('dygraph-labelsDivWidth') || 250;
700 var labelsSeparateLines = self.data('dygraph-labelsSeparateLines') || false;
701 var labelsShowZeroValues = self.data('dygraph-labelsShowZeroValues') || true;
702 var legend = self.data('dygraph-legend') || 'onmouseover';
703 var showLabelsOnHighlight = self.data('dygraph-showLabelsOnHighlight') || true;
704 var gridLineColor = self.data('dygraph-gridLineColor') || '#EEE';
705 var axisLineColor = self.data('dygraph-axisLineColor') || '#EEE';
706 var maxNumberWidth = self.data('dygraph-maxNumberWidth') || 8;
707 var sigFigs = self.data('dygraph-sigFigs') || null;
708 var digitsAfterDecimal = self.data('dygraph-digitsAfterDecimal') || 2;
709 var axisLabelFontSize = self.data('dygraph-axisLabelFontSize') || 10;
710 var axisLineWidth = self.data('dygraph-axisLineWidth') || 0.3;
711 var drawAxis = self.data('dygraph-drawAxis') || true;
712 var strokeWidth = self.data('dygraph-strokeWidth') || 1.0;
713 var drawGapEdgePoints = self.data('dygraph-drawGapEdgePoints') || true;
714 var colors = self.data('dygraph-colors') || NETDATA.colors;
715 var pointSize = self.data('dygraph-pointSize') || 1;
716 var stepPlot = self.data('dygraph-stepPlot') || false;
717 var strokeBorderColor = self.data('dygraph-strokeBorderColor') || 'white';
718 var strokeBorderWidth = self.data('dygraph-strokeBorderWidth') || (chart.chart_type == 'stacked')?1.0:0.0;
719 var strokePattern = self.data('dygraph-strokePattern') || undefined;
720 var highlightCircleSize = self.data('dygraph-highlightCircleSize') || 3;
721 var highlightSeriesOpts = self.data('dygraph-highlightSeriesOpts') || { strokeWidth: 1.5 };
722 var highlightSeriesBackgroundAlpha = self.data('dygraph-highlightSeriesBackgroundAlpha') || (chart.chart_type == 'stacked')?0.7:0.5;
723 var pointClickCallback = self.data('dygraph-pointClickCallback') || undefined;
724 var showRangeSelector = self.data('dygraph-showRangeSelector') || false;
725 var showRoller = self.data('dygraph-showRoller') || false;
726 var valueFormatter = self.data('dygraph-valueFormatter') || undefined; //function(x){ return x.toFixed(2); };
727 var rightGap = self.data('dygraph-rightGap') || 5;
728 var drawGrid = self.data('dygraph-drawGrid') || true;
729 var drawXGrid = self.data('dygraph-drawXGrid') || undefined;
730 var drawYGrid = self.data('dygraph-drawYGrid') || undefined;
731 var gridLinePattern = self.data('dygraph-gridLinePattern') || null;
732 var gridLineWidth = self.data('dygraph-gridLineWidth') || 0.3;
736 titleHeight: titleHeight,
738 yLabelWidth: yLabelWidth,
739 connectSeparatedPoints: connectSeparatedPoints,
740 drawPoints: drawPoints,
741 fillGraph: fillGraph,
742 stackedGraph: stackedGraph,
743 stackedGraphNaNFill: stackedGraphNaNFill,
745 drawXGrid: drawXGrid,
746 drawYGrid: drawYGrid,
747 gridLinePattern: gridLinePattern,
748 gridLineWidth: gridLineWidth,
749 gridLineColor: gridLineColor,
750 axisLineColor: axisLineColor,
751 axisLineWidth: axisLineWidth,
753 hideOverlayOnMouseOut: hideOverlayOnMouseOut,
754 labelsDiv: labelsDiv,
755 labelsDivStyles: labelsDivStyles,
756 labelsDivWidth: labelsDivWidth,
757 labelsSeparateLines: labelsSeparateLines,
758 labelsShowZeroValues: labelsShowZeroValues,
762 showLabelsOnHighlight: showLabelsOnHighlight,
763 maxNumberWidth: maxNumberWidth,
765 digitsAfterDecimal: digitsAfterDecimal,
766 axisLabelFontSize: axisLabelFontSize,
768 strokeWidth: strokeWidth,
769 drawGapEdgePoints: drawGapEdgePoints,
770 pointSize: pointSize,
772 strokeBorderColor: strokeBorderColor,
773 strokeBorderWidth: strokeBorderWidth,
774 strokePattern: strokePattern,
775 highlightCircleSize: highlightCircleSize,
776 highlightSeriesOpts: highlightSeriesOpts,
777 highlightSeriesBackgroundAlpha: highlightSeriesBackgroundAlpha,
778 pointClickCallback: pointClickCallback,
779 showRangeSelector: showRangeSelector,
780 showRoller: showRoller,
781 valueFormatter: valueFormatter,
789 ticker: Dygraph.dateTicker,
790 axisLabelFormatter: function (d, gran) {
791 return Dygraph.zeropad(d.getHours()) + ":" + Dygraph.zeropad(d.getMinutes()) + ":" + Dygraph.zeropad(d.getSeconds());
793 valueFormatter :function (ms) {
794 var d = new Date(ms);
795 return Dygraph.zeropad(d.getHours()) + ":" + Dygraph.zeropad(d.getMinutes()) + ":" + Dygraph.zeropad(d.getSeconds());
804 var uuid = NETDATA.guid();
805 self.html('<div id="' + uuid + '"></div>');
807 var dchart = new Dygraph(document.getElementById(uuid),
810 self.data('dygraph-instance', dchart)
811 .data('dygraph-options', options)
813 .data('created', true);
815 //NETDATA.dygraphAllCharts.push(dchart);
816 //if(NETDATA.dygraphAllCharts.length > 1)
817 // NETDATA.dygraphSyncAll();
820 // ----------------------------------------------------------------------------------------------------------------
823 NETDATA.morrisInitialize = function(callback) {
824 if(typeof netdataStopMorris == 'undefined') {
825 var fileref = document.createElement("link");
826 fileref.setAttribute("rel", "stylesheet");
827 fileref.setAttribute("type", "text/css");
828 fileref.setAttribute("href", NETDATA.morris_css);
830 if (typeof fileref != "undefined")
831 document.getElementsByTagName("head")[0].appendChild(fileref);
833 $.getScript(NETDATA.morris_js)
835 NETDATA.registerChartLibrary('morris', NETDATA.morris_js);
838 NETDATA.error(100, NETDATA.morris_js);
841 if(typeof callback == "function")
845 else if(typeof callback == "function")
849 NETDATA.morrisChartUpdate = function(element, data) {
850 var self = $(element);
851 var width = self.data('width') || NETDATA.chartDefaults.width;
852 var height = self.data('height') || NETDATA.chartDefaults.height;
853 var morris = self.data('morris-instance');
855 if(typeof data.update_every != 'undefined')
856 self.data('update-every', data.update_every * 1000);
859 console.log('updating morris');
860 morris.setData(data.data);
863 console.log('not updating morris');
866 NETDATA.morrisChartCreate = function(element, data) {
867 var self = $(element);
868 var width = self.data('width') || NETDATA.chartDefaults.width;
869 var height = self.data('height') || NETDATA.chartDefaults.height;
870 var chart = self.data('chart');
872 self.html('<div id="morris-' + chart.id + '" style="width: ' + width + 'px; height: ' + height + 'px;"></div>');
874 // remove the 'time' element from the labels
875 data.labels.splice(0, 1);
878 element: 'morris-' + chart.id,
888 continuousLine: false,
889 behaveLikeLine: false,
895 if(chart.chart_type == 'line')
896 morris = new Morris.Line(options);
898 else if(chart.chart_type == 'area') {
899 options.behaveLikeLine = true;
900 morris = new Morris.Area(options);
903 morris = new Morris.Area(options);
905 self.data('morris-instance', morris)
906 .data('created', true);
909 // ----------------------------------------------------------------------------------------------------------------
912 NETDATA.raphaelInitialize = function(callback) {
913 if(typeof netdataStopRaphael == 'undefined') {
914 $.getScript(NETDATA.raphael_js)
916 NETDATA.registerChartLibrary('raphael', NETDATA.raphael_js);
919 NETDATA.error(100, NETDATA.raphael_js);
922 if(typeof callback == "function")
926 else if(typeof callback == "function")
930 NETDATA.raphaelChartUpdate = function(element, data) {
931 var self = $(element);
932 var width = self.data('width') || NETDATA.chartDefaults.width;
933 var height = self.data('height') || NETDATA.chartDefaults.height;
941 NETDATA.raphaelChartCreate = function(element, data) {
942 var self = $(element);
943 var width = self.data('width') || NETDATA.chartDefaults.width;
944 var height = self.data('height') || NETDATA.chartDefaults.height;
950 .data('created', true);
953 // ----------------------------------------------------------------------------------------------------------------
956 NETDATA.googleInitialize = function(callback) {
957 if(typeof netdataStopGoogleCharts == 'undefined' && typeof google != 'undefined') {
958 NETDATA.registerChartLibrary('google', NETDATA.google_js);
959 if(typeof callback == "function")
962 else if(typeof callback == "function")
966 NETDATA.googleChartUpdate = function(element, data) {
967 var self = $(element);
968 var width = self.data('width') || NETDATA.chartDefaults.width;
969 var height = self.data('height') || NETDATA.chartDefaults.height;
970 var gchart = self.data('google-instance');
971 var options = self.data('google-options');
973 if(typeof data.update_every != 'undefined')
974 self.data('update-every', data.update_every * 1000);
976 var datatable = new google.visualization.DataTable(data);
978 gchart.draw(datatable, options);
981 NETDATA.googleChartCreate = function(element, data) {
982 var self = $(element);
983 var width = self.data('width') || NETDATA.chartDefaults.width;
984 var height = self.data('height') || NETDATA.chartDefaults.height;
985 var chart = self.data('chart');
987 var datatable = new google.visualization.DataTable(data);
997 // title: "Time of Day",
998 // format:'HH:mm:ss',
999 viewWindowMode: 'maximized',
1011 viewWindowMode: 'pretty',
1026 focusTarget: 'category',
1033 titlePosition: 'out',
1044 curveType: 'function',
1049 switch(chart.chart_type) {
1051 options.vAxis.viewWindowMode = 'maximized';
1052 gchart = new google.visualization.AreaChart(element);
1056 options.isStacked = true;
1057 options.areaOpacity = 0.85;
1058 options.vAxis.viewWindowMode = 'maximized';
1059 options.vAxis.minValue = null;
1060 options.vAxis.maxValue = null;
1061 gchart = new google.visualization.AreaChart(element);
1066 options.lineWidth = 2;
1067 gchart = new google.visualization.LineChart(element);
1071 gchart.draw(datatable, options);
1073 self.data('google-instance', gchart)
1074 .data('google-options', options)
1075 .data('created', true);
1078 // ----------------------------------------------------------------------------------------------------------------
1079 // Charts Libraries Registration
1081 NETDATA.chartLibraries = {
1083 initialize: NETDATA.dygraphInitialize,
1084 create: NETDATA.dygraphChartCreate,
1085 update: NETDATA.dygraphChartUpdate,
1090 pixels_per_point: 2,
1091 detects_dimensions_on_update: false
1094 initialize: NETDATA.sparklineInitialize,
1095 create: NETDATA.sparklineChartCreate,
1096 update: NETDATA.sparklineChartUpdate,
1100 options: 'flip|min2max',
1101 pixels_per_point: 2,
1102 detects_dimensions_on_update: false
1105 initialize: NETDATA.peityInitialize,
1106 create: NETDATA.peityChartCreate,
1107 update: NETDATA.peityChartUpdate,
1111 options: 'null2zero|flip|min2max',
1112 pixels_per_point: 2,
1113 detects_dimensions_on_update: false
1116 initialize: NETDATA.morrisInitialize,
1117 create: NETDATA.morrisChartCreate,
1118 update: NETDATA.morrisChartUpdate,
1122 options: 'objectrows|ms',
1123 pixels_per_point: 10,
1124 detects_dimensions_on_update: false
1127 initialize: NETDATA.googleInitialize,
1128 create: NETDATA.googleChartCreate,
1129 update: NETDATA.googleChartUpdate,
1132 format: 'datatable',
1134 pixels_per_point: 2,
1135 detects_dimensions_on_update: true
1138 initialize: NETDATA.raphaelInitialize,
1139 create: NETDATA.raphaelChartCreate,
1140 update: NETDATA.raphaelChartUpdate,
1145 pixels_per_point: 1,
1146 detects_dimensions_on_update: false
1150 NETDATA.registerChartLibrary = function(library, url) {
1151 console.log("registering chart library: " + library);
1153 NETDATA.chartLibraries[library]
1155 .initialized = new Date().getTime();
1157 console.log(NETDATA.chartLibraries);
1160 // ----------------------------------------------------------------------------------------------------------------
1161 // load all libraries and initialize
1163 NETDATA.errorReset();
1165 NETDATA._loadjQuery(function() {
1166 $.getScript(NETDATA.serverDefault + 'lib/visible.js').then(function() {
1167 NETDATA.raphaelInitialize(function() {
1168 NETDATA.morrisInitialize(function() {
1169 NETDATA.peityInitialize(function() {
1170 NETDATA.sparklineInitialize(function() {
1171 NETDATA.dygraphInitialize(function() {
1172 NETDATA.googleInitialize(function() {