summaryrefslogtreecommitdiffstats
path: root/web
diff options
context:
space:
mode:
authorCosta Tsaousis (ktsaou) <costa@tsaousis.gr>2015-11-29 22:55:51 +0200
committerCosta Tsaousis (ktsaou) <costa@tsaousis.gr>2015-11-29 22:55:51 +0200
commit29f349198b8dec33d3c3c2a0e56d547f2c80aa4c (patch)
tree1f605f098991c36b2fb6d0c2e62b6373a98599ed /web
parent76eafaa8cdae91d6c7447ccfbae63f152aaa0767 (diff)
added support for custom dashboards - new API is operational and stable
Diffstat (limited to 'web')
-rw-r--r--web/Makefile.am10
-rw-r--r--web/css/morris.css2
-rwxr-xr-xweb/dashboard.html267
-rwxr-xr-xweb/dashboard.js1054
-rwxr-xr-xweb/lib/dygraph-combined.js6
-rw-r--r--web/lib/dygraph-synchronizer.js229
-rwxr-xr-xweb/lib/jquery-1.11.3.min.js5
-rwxr-xr-xweb/lib/jquery.peity.min.js13
-rwxr-xr-xweb/lib/jquery.sparkline.min.js5
-rw-r--r--web/lib/morris.min.js7
-rw-r--r--web/lib/raphael-min.js10
11 files changed, 1608 insertions, 0 deletions
diff --git a/web/Makefile.am b/web/Makefile.am
index ad6850a1e3..bc496ad4c6 100644
--- a/web/Makefile.am
+++ b/web/Makefile.am
@@ -10,5 +10,15 @@ dist_web_DATA = \
netdata.js \
robots.txt \
theme.css \
+ css/morris.css \
+ dashboard.html \
+ dashboard.js \
+ lib/dygraph-combined.js \
+ lib/dygraph-synchronizer.js \
+ lib/jquery-1.11.3.min.js \
+ lib/jquery.peity.min.js \
+ lib/jquery.sparkline.min.js \
+ lib/morris.min.js \
+ lib/raphael-min.js \
$(NULL)
diff --git a/web/css/morris.css b/web/css/morris.css
new file mode 100644
index 0000000000..209f09156b
--- /dev/null
+++ b/web/css/morris.css
@@ -0,0 +1,2 @@
+.morris-hover{position:absolute;z-index:1000}.morris-hover.morris-default-style{border-radius:10px;padding:6px;color:#666;background:rgba(255,255,255,0.8);border:solid 2px rgba(230,230,230,0.8);font-family:sans-serif;font-size:12px;text-align:center}.morris-hover.morris-default-style .morris-hover-row-label{font-weight:bold;margin:0.25em 0}
+.morris-hover.morris-default-style .morris-hover-point{white-space:nowrap;margin:0.1em 0}
diff --git a/web/dashboard.html b/web/dashboard.html
new file mode 100755
index 0000000000..07799ba6e3
--- /dev/null
+++ b/web/dashboard.html
@@ -0,0 +1,267 @@
+<html>
+<head>
+ <title>NetData Dashboard</title>
+ <style type="text/css">
+ html{font-family:sans-serif;}
+ </style>
+</head>
+<body>
+
+<h1>NetData Custom Dashboard</h1>
+
+This is a template for building custom dashboards. To build a dashboard you just do this:
+
+<pre>
+&lt;html>
+&lt;body>
+ &lt;div data-netdata="system.processes"
+ data-chart-library="dygraph"
+ data-width="600"
+ data-height="200"
+ data-after="-600"
+ &lt;/div>
+&lt;/body>
+&lt;script type="text/javascript" src="http://netdata.server:19999/dashboard.js"></script>
+&lt;/html>
+</pre>
+
+<ul>
+ <li>You can host your dashboard anywhere.</li>
+ <li>You can add as many charts as you like.</li>
+ <li>You can have charts from many different netdata servers (add <pre>data-host="http://another.netdata.server:19999/"</pre> to each chart).</li>
+ <li>You can use different chart libraries on the same page: <b>peity</b>, <b>sparkline</b>, <b>dygraph</b>, <b>google</b> (requires some more lines in your html page - view source this one), <b>morris</b></li>
+ <li>You can customize each chart to your preferences. For each chart library most of their attributes can be given in <b>data-</b> attributes.</li>
+ <li>Each chart can have each own duration - it is controlled with the <b>data-after</b> attribute to give that many seconds of data.</li>
+ <li>Depending on the width of the chart and <b>data-after</b> attribute, netdata will automatically refresh the chart when it needs to be updated. For example giving 600 pixels for width for -600 seconds of data, using a chart library that needs 3 pixels per point, will yeld in a chart updated once every 3 seconds.</li>
+</ul>
+
+ <table border="0" cellpadding="5" cellspacing="5">
+ <tr>
+ <th width="600">
+ System Processes - Line Chart
+ </th>
+ <th width="600">
+ System ipv4 - Area Chart
+ </th>
+ <th width="600">
+ System CPU - Stacked Area Chart
+ </th>
+ </tr>
+ <tr><td colspan="3" align="center">&nbsp;</td></tr>
+ <tr><th colspan="3" align="center"><hr>Peity Charts</th></tr>
+ <tr><td colspan="3" align="center">
+ Peity charts do not support 'NULL' values, so the charts cannot indicate that values are missing.
+ Peity charts cannot have multiple dimensions on the charts - so netdata will use 'min2max' to show
+ the total of all dimensions.
+ </td></tr>
+ <tr>
+ <td width="600" align="center">
+ <div data-netdata="system.processes"
+ data-chart-library="peity"
+ data-width="600"
+ data-height="30"
+ data-after="-600"
+ data-dt-element-name="time11"
+ </div>
+ </td>
+ <td width="600" align="center">
+ <div data-netdata="system.ipv4"
+ data-chart-library="peity"
+ data-width="600"
+ data-height="30"
+ data-after="-600"
+ data-dt-element-name="time12"
+ </div>
+ </td>
+ <td width="600" align="center">
+ <div data-netdata="system.cpu"
+ data-chart-library="peity"
+ data-width="600"
+ data-height="30"
+ data-after="-600"
+ data-dt-element-name="time13"
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td>rendered in <span id="time11">X</span> ms</td>
+ <td>rendered in <span id="time12">X</span> ms</td>
+ <td>rendered in <span id="time13">X</span> ms</td>
+ </tr>
+ <tr><td colspan="3" align="center">&nbsp;</td></tr>
+ <tr><th colspan="3" align="center"><hr>Sparkline Charts</th></tr>
+ <tr><td colspan="3" align="center">
+ Sparkline charts support 'NULL' values, so the charts can indicate that values are missing.
+ Sparkline charts stretch the values to show the variations between values in more detail.
+ They also have mouse-hover support.
+ </td></tr>
+ <tr>
+ <td width="600" align="center">
+ <div data-netdata="system.processes"
+ data-chart-library="sparkline"
+ data-width="600"
+ data-height="30"
+ data-after="-600"
+ data-dt-element-name="time21"
+ </div>
+ </td>
+ <td width="600" align="center">
+ <div data-netdata="system.ipv4"
+ data-chart-library="sparkline"
+ data-width="600"
+ data-height="30"
+ data-after="-600"
+ data-dt-element-name="time22"
+ </div>
+ </td>
+ <td width="600" align="center">
+ <div data-netdata="system.cpu"
+ data-chart-library="sparkline"
+ data-width="600"
+ data-height="30"
+ data-after="-600"
+ data-dt-element-name="time23"
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td>rendered in <span id="time21">X</span> ms</td>
+ <td>rendered in <span id="time22">X</span> ms</td>
+ <td>rendered in <span id="time23">X</span> ms</td>
+ </tr>
+ <tr><td colspan="3" align="center">&nbsp;</td></tr>
+ <tr><th colspan="3" align="center"><hr>Dygraph Charts</th></tr>
+ <tr><td colspan="3" align="center">
+ The fastest charting engine that can chart complete charts (not just sparklines).
+ The charts are zoomable (drag their contents to zoom-in, double click to zoom-out).
+ For the moment zooming is just on the presentation layer (the data do not become more detailed when you zoom).
+ </td></tr>
+ <tr>
+ <td width="600" align="center">
+ <div data-netdata="system.processes"
+ data-chart-library="dygraph"
+ data-width="600"
+ data-height="200"
+ data-after="-600"
+ data-dt-element-name="time31"
+ </div>
+ </td>
+ <td width="600" align="center">
+ <div data-netdata="system.ipv4"
+ data-chart-library="dygraph"
+ data-width="600"
+ data-height="200"
+ data-after="-600"
+ data-dt-element-name="time32"
+ </div>
+ </td>
+ <td width="600" align="center">
+ <div data-netdata="system.cpu"
+ data-chart-library="dygraph"
+ data-width="600"
+ data-height="200"
+ data-after="-600"
+ data-dt-element-name="time33"
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td>rendered in <span id="time31">X</span> ms</td>
+ <td>rendered in <span id="time32">X</span> ms</td>
+ <td>rendered in <span id="time33">X</span> ms</td>
+ </tr>
+ <tr><td colspan="3" align="center">&nbsp;</td></tr>
+ <tr><th colspan="3" align="center"><hr>Google Charts</th></tr>
+ <tr><td colspan="3" align="center">
+ NetData was originaly developed with Google Charts.
+ NetData is a complete Google Visualization API provider.
+ </td></tr>
+ <tr>
+ <td width="600" align="center">
+ <div data-netdata="system.processes"
+ data-chart-library="google"
+ data-width="600"
+ data-height="200"
+ data-after="-600"
+ data-dt-element-name="time51"
+ </div>
+ </td>
+ <td width="600" align="center">
+ <div data-netdata="system.ipv4"
+ data-chart-library="google"
+ data-width="600"
+ data-height="200"
+ data-after="-600"
+ data-dt-element-name="time52"
+ </div>
+ </td>
+ <td width="600" align="center">
+ <div data-netdata="system.cpu"
+ data-chart-library="google"
+ data-width="600"
+ data-height="200"
+ data-after="-600"
+ data-dt-element-name="time53"
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td>rendered in <span id="time51">X</span> ms</td>
+ <td>rendered in <span id="time52">X</span> ms</td>
+ <td>rendered in <span id="time53">X</span> ms</td>
+ </tr>
+ <tr><td colspan="3" align="center">&nbsp;</td></tr>
+ <tr><th colspan="3" align="center"><hr>Morris Charts</th></tr>
+ <tr><td colspan="3" align="center">
+ Unfortunatelly, Morris Charts are veeeeeeeeeeeeeeeery slow! We force them to lower their detail to get acceptable results.
+ And they have issues with negative numbers in area charts...
+ </td></tr>
+ <tr>
+ <td width="600" align="center">
+ <div data-netdata="system.processes"
+ data-chart-library="morris"
+ data-width="600"
+ data-height="200"
+ data-after="-600"
+ data-dt-element-name="time41"
+ </div>
+ </td>
+ <td width="600" align="center">
+ <div data-netdata="system.ipv4"
+ data-chart-library="morris"
+ data-width="600"
+ data-height="200"
+ data-after="-600"
+ data-dt-element-name="time42"
+ </div>
+ </td>
+ <td width="600" align="center">
+ <div data-netdata="system.cpu"
+ data-chart-library="morris"
+ data-width="600"
+ data-height="200"
+ data-after="-600"
+ data-dt-element-name="time43"
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td>rendered in <span id="time41">X</span> ms</td>
+ <td>rendered in <span id="time42">X</span> ms</td>
+ <td>rendered in <span id="time43">X</span> ms</td>
+ </tr>
+ </table>
+
+</body>
+</html>
+ <!-- You can disable Google Visualization by commenting the following two lines -->
+ <script type="text/javascript" src="https://www.google.com/jsapi"></script>
+ <script type='text/javascript'>google.load('visualization', '1.1', {'packages':['corechart', 'controls']});</script>
+
+ <!-- you can set your netdata server globally, by ucommenting this -->
+ <!-- you can also give a different server per chart, with the attribute: data-host="http://netdata.server:19999" -->
+ <!-- <script> netdataServer = "http://box:19999"; </script> -->
+
+ <!-- load the dashboard manager - it will do the rest -->
+ <script type="text/javascript" src="dashboard.js"></script>
+
diff --git a/web/dashboard.js b/web/dashboard.js
new file mode 100755
index 0000000000..81a7ade4b2
--- /dev/null
+++ b/web/dashboard.js
@@ -0,0 +1,1054 @@
+// You can set the following variables before loading this script:
+//
+// var netdataStopDygraph = 1; // do not use dygraph
+// var netdataStopSparkline = 1; // do not use sparkline
+// var netdataStopPeity = 1; // do not use peity
+//
+// You can also set the default netdata server, using the following.
+// When this variable is not set, we assume the page is hosted on your
+// netdata server already.
+// var netdataServer = "http://yourhost:19999"; // set your NetData server
+
+// --------------------------------------------------------------------------------------------------------------------
+// For google charts you need this in your page:
+// <script type="text/javascript" src="https://www.google.com/jsapi"></script>
+// <script type='text/javascript'>google.load('visualization', '1.1', {'packages':['corechart', 'controls']});</script>
+
+(function(window)
+{
+ var NETDATA = window.NETDATA || {};
+
+ // ----------------------------------------------------------------------------------------------------------------
+ // Detect the netdata server
+
+ // http://stackoverflow.com/questions/984510/what-is-my-script-src-url
+ // http://stackoverflow.com/questions/6941533/get-protocol-domain-and-port-from-url
+ NETDATA._scriptSource = function(scripts) {
+ var script = null, base = null;
+
+ if(typeof document.currentScript != 'undefined') {
+ script = document.currentScript;
+ }
+ else {
+ var all_scripts = document.getElementsByTagName('script');
+ script = all_scripts[all_scripts.length - 1];
+ }
+
+ if (script.getAttribute.length != 'undefined')
+ script = script.src;
+ else
+ script = script.getAttribute('src', -1);
+
+ var link = document.createElement('a');
+ link.setAttribute('href', script);
+
+ if(!link.protocol || !link.hostname) return null;
+
+ base = link.protocol;
+ if(base) base += "//";
+ base += link.hostname;
+
+ if(link.port) base += ":" + link.port;
+ base += "/";
+
+ return base;
+ };
+
+ if(typeof netdataServer != 'undefined')
+ NETDATA.serverDefault = netdataServer + "/";
+ else
+ NETDATA.serverDefault = NETDATA._scriptSource();
+
+ NETDATA.jQuery = NETDATA.serverDefault + 'lib/jquery-1.11.3.min.js';
+ NETDATA.peity_js = NETDATA.serverDefault + 'lib/jquery.peity.min.js';
+ NETDATA.sparkline_js = NETDATA.serverDefault + 'lib/jquery.sparkline.min.js';
+ NETDATA.dygraph_js = NETDATA.serverDefault + 'lib/dygraph-combined.js';
+ NETDATA.raphael_js = NETDATA.serverDefault + 'lib/raphael-min.js';
+ NETDATA.morris_js = NETDATA.serverDefault + 'lib/morris.min.js';
+ NETDATA.morris_css = NETDATA.serverDefault + 'css/morris.css';
+ NETDATA.google_js = 'https://www.google.com/jsapi';
+ NETDATA.colors = [ '#3366CC', '#DC3912', '#FF9900', '#109618', '#990099', '#3B3EAC', '#0099C6', '#DD4477',
+ '#66AA00', '#B82E2E', '#316395', '#994499', '#22AA99', '#AAAA11', '#6633CC', '#E67300', '#8B0707',
+ '#329262', '#5574A6', '#3B3EAC' ];
+
+ // ----------------------------------------------------------------------------------------------------------------
+ // the defaults for all charts
+
+ NETDATA.chartDefaults = {
+ host: NETDATA.serverDefault, // the server to get data from
+ width: 100, // the chart width
+ height: 20, // the chart height
+ library: 'peity', // the graphing library to use
+ method: 'average', // the grouping method
+ before: 0, // panning
+ after: -600, // panning
+ point_width: 1, // the detail of the chart
+ }
+
+ NETDATA.all_url = 'all2.js';
+ NETDATA_idle_between_charts = 50;
+ NETDATA.debug = 1;
+
+ if(NETDATA.debug) console.log('welcome to NETDATA');
+
+
+ // ----------------------------------------------------------------------------------------------------------------
+ // Error Handling
+
+ NETDATA.errorCodes = {
+ 100: { message: "Cannot load chart library", alert: true },
+ 101: { message: "Cannot load jQuery", alert: true },
+ 402: { message: "Chart library not found", alert: false },
+ 404: { message: "Chart not found", alert: false },
+ };
+ NETDATA.errorLast = {
+ code: 0,
+ message: "",
+ datetime: 0,
+ };
+
+ NETDATA.error = function(code, msg) {
+ NETDATA.errorLast.code = code;
+ NETDATA.errorLast.message = msg;
+ NETDATA.errorLast.datetime = new Date().getTime();
+
+ console.log("ERROR " + code + ": " + NETDATA.errorCodes[code].message + ": " + msg);
+
+ if(NETDATA.errorCodes[code].alert)
+ alert("ERROR " + code + ": " + NETDATA.errorCodes[code].message + ": " + msg);
+ }
+
+ NETDATA.errorReset = function() {
+ NETDATA.errorLast.code = 0;
+ NETDATA.errorLast.message = "You are doing fine!";
+ NETDATA.errorLast.datetime = 0;
+ }
+
+ NETDATA.messageInABox = function(div, width, height, message) {
+ div.innerHTML = '<table border="0"><tr><td width="' + width + '" height="' + height
+ + '" valign="middle" align="center">'
+ + message
+ + '</td></tr></table>';
+ }
+
+ // ----------------------------------------------------------------------------------------------------------------
+ // Load a script without jquery
+ // This is used to load jquery - after it is loaded, we use jquery
+
+ NETDATA._loadjQuery = function(callback) {
+ if(typeof jQuery == 'undefined') {
+ var script = document.createElement('script');
+ script.type = 'text/javascript';
+ script.async = true;
+ script.src = NETDATA.jQuery;
+
+ // script.onabort = onError;
+ script.onerror = function(err, t) { NETDATA.error(101, NETDATA.jQuery); };
+ if(typeof callback == "function")
+ script.onload = callback;
+
+ var s = document.getElementsByTagName('script')[0];
+ s.parentNode.insertBefore(script, s);
+ }
+ else if(typeof callback == "function")
+ callback();
+ }
+
+ NETDATA.generateDataURL = function(args) {
+ // build the data URL
+ var url = args.host + args.url;
+ url += "&points=";
+ url += args.points.toString();
+ url += "&group=";
+ url += args.method;
+ url += "&after=";
+ url += args.after || "0";
+ url += "&before=";
+ url += args.before || "0";
+ url += "&options=" + NETDATA.chartLibraries[args.library].options + '|';
+ url += (args.non_zero)?"nonzero":"";
+ url += "&format=" + NETDATA.chartLibraries[args.library].format;
+
+ if(args.dimensions)
+ url += "&dimensions=" + args.dimensions;
+
+ if(NETDATA.debug) console.log('generateDataURL(' + args + ') = ' + url );
+ return url;
+ }
+
+ NETDATA.loadCharts = function(targets, index, callback) {
+ if(NETDATA.debug) console.log('loadCharts(<targets, ' + index + ')');
+
+ var target = targets.get(index);
+
+ if(target == null) {
+ console.log('loaded all charts');
+ callback();
+ }
+ else {
+ var self = $(target);
+
+ if(!self.data('loaded')) {
+ var id = self.data('netdata');
+
+ var host = self.data('host') || NETDATA.chartDefaults.host;
+ var width = self.data('width') || NETDATA.chartDefaults.width;
+ var height = self.data('height') || NETDATA.chartDefaults.height;
+ var method = self.data('method') || NETDATA.chartDefaults.method;
+ var after = self.data('after') || NETDATA.chartDefaults.after;
+ var before = self.data('before') || NETDATA.chartDefaults.before;
+ var host = self.data('host') || NETDATA.chartDefaults.host;
+ var library = self.data('chart-library') || NETDATA.chartDefaults.library;
+ var dimensions = self.data('dimensions') || null;
+
+ if(typeof NETDATA.chartLibraries[library] == 'undefined') {
+ NETDATA.error(402, library);
+ NETDATA.messageInABox(target, width, height, 'chart library "' + library + '" is not found');
+ self.data('enabled', false);
+ NETDATA.loadCharts(targets, ++index, callback);
+ }
+ else {
+ var url = host + "/api/v1/chart?chart=" + id;
+
+ $.ajax( {
+ url: url,
+ crossDomain: true
+ })
+ .done(function(chart) {
+
+ var point_width = self.data('point-width') || NETDATA.chartLibraries[library].pixels;
+ var points = self.data('points') || Math.round(width / point_width);
+
+ var url = NETDATA.generateDataURL({
+ host: host,
+ url: chart.data_url,
+ dimensions: dimensions,
+ library: library,
+ method: method,
+ before: before,
+ points: points,
+ after: after,
+ non_zero: null
+ });
+
+ // done processing of this DIV
+ // store the processing result, in
+ // 'data' sections in the DIV
+ self
+ .data('chart', chart)
+ .data('chart-url', url)
+ .data('last-updated', 0)
+ .data('update-every', chart.update_every * 1000)
+ .data('enabled', true);
+ })
+ .fail(function() {
+ NETDATA.error(404, url);
+ NETDATA.messageInABox(target, width, height, 'chart "' + id + '" not found on url "' + url + '"');
+ self.data('enabled', false);
+ })
+ .always(function() {
+ NETDATA.loadCharts(targets, ++index, callback);
+ });
+ }
+ }
+ }
+ }
+
+ function netdataParsePageCharts() {
+ if(NETDATA.debug) console.log('processing web page defined charts');
+
+ // targets
+ // a list of all DIVs containing netdata charts
+
+ var targets = $('div[data-netdata]')
+ .bind('create', function(event, data) {
+ var self = $(this);
+ var lib = self.data('chart-library') || 'dygraph';
+ var method = lib + 'ChartCreate';
+
+ console.log('Calling ' + method + '()');
+ NETDATA[method].apply(this, arguments);
+ })
+ .bind('update', function() {
+ var self = $(this);
+ var lib = self.data('chart-library') || 'dygraph';
+ var method = lib + 'ChartUpdate';
+
+ console.log('Calling ' + method + '()');
+ NETDATA[method].apply(this, arguments);
+ });
+
+ NETDATA.loadCharts(targets, 0, function() {
+ // done processing all netdata DIVs in this page
+ // call the refresh handler
+ netdataRefreshTargets(targets, 0);
+ });
+ }
+
+ // ----------------------------------------------------------------------------------------------------------------
+ // Charts Libraries Registration
+
+ NETDATA.chartLibraries = {};
+
+ NETDATA.registerChartLibrary = function(library, url, format, options, min_pixels_per_point) {
+ console.log("registering chart library: " + library);
+
+ NETDATA.chartLibraries[library] = {
+ initialized: new Date().getTime(),
+ url: url,
+ format: format,
+ options: options,
+ pixels: min_pixels_per_point
+ };
+
+ console.log(NETDATA.chartLibraries);
+ }
+
+ // ----------------------------------------------------------------------------------------------------------------
+
+ //var chart = function() {
+ //}
+
+ //chart.prototype.color = function() {
+ // return 'red';
+ //}
+
+ //var c = new chart();
+ //c.color();
+
+ function netdataDownloadChartData(callback) {
+ var self = $(this);
+ var last = self.data('last-updated') || 0;
+ var every = self.data('update-every') || 1;
+
+ // check if this chart has to be refreshed now
+ var now = new Date().getTime();
+ if(last + every > now) {
+ if(typeof callback == 'function')
+ callback();
+ }
+ else {
+ var url = self.data('chart-url');
+
+ if(NETDATA.debug) console.log('netdataDownloadChartData(): downloading ' + url);
+
+ $.ajax( {
+ url: url,
+ crossDomain: true
+ })
+ .then(function(data) {
+ //var result = $.map(data.rows, function(item) {
+ // get from the 3rd column the 'v' member
+ //return item.c[3].v;
+ //});
+
+ // since we downloaded the data
+ // update the last-updated time to prevent
+ // another download too soon
+ self.data('last-updated', new Date().getTime());
+
+ // render it
+ var created = self.data('created');
+ self.trigger((created ? 'update' : 'create'), [data]).data('created', true)
+ })
+ .fail(function() {
+ console.log('failed to download chart data');
+ })
+ .always(function() {
+ var last = self.data('last-updated');
+ var now = new Date().getTime();
+ var dt = now - last;
+ self.data('refresh-dt', dt);
+
+ var element_name = self.data('dt-element-name') || null;
+ if(element_name) {
+ var element = document.getElementById(element_name) || null;
+ if(element) {
+ element.innerHTML = dt.toString();
+ }
+ }
+
+ if(typeof callback == 'function')
+ callback();
+ });
+ }
+ };
+
+ function netdataRefreshTargets(targets, index) {
+ // if(NETDATA.debug) console.log('netdataRefreshTargets(<targets, ' + index + ')');
+
+ var target = targets.get(index);
+
+ if(target == null) {
+ console.log('restart');
+
+ // finished, restart
+ setTimeout(function() {
+ netdataRefreshTargets(targets, 0);
+ }, 1000);
+ }
+ else {
+ var self = $(target);
+
+ if(!self.data('enabled')) {
+ netdataRefreshTargets(targets, ++index);
+ }
+ else {
+ setTimeout(function() {
+ netdataDownloadChartData.call(target, function() {
+ netdataRefreshTargets(targets, ++index);
+ });
+ }, NETDATA_idle_between_charts);
+ }
+ }
+ }
+
+
+ // ----------------------------------------------------------------------------------------------------------------
+ // piety
+
+ NETDATA.peityInitialize = function(callback) {
+ if(typeof netdataStopPeity == 'undefined') {
+ $.getScript(NETDATA.peity_js)
+ .done(function() {
+ NETDATA.registerChartLibrary('peity', NETDATA.peity_js, 'ssvcomma', 'null2zero|flip|min2max', 2);
+ })
+ .fail(function() {
+ NETDATA.error(100, NETDATA.peity_js);
+ })
+ .always(function() {
+ if(typeof callback == "function")
+ callback();
+ })
+ }
+ else if(typeof callback == "function")
+ callback();
+ };
+
+ NETDATA.peityChartUpdate = function(event, data) {
+ var self = $(this);
+ var instance = self.html(data).not('[data-created]');
+ instance.change();
+ }
+
+ NETDATA.peityChartCreate = function(event, data) {
+ var self = $(this);
+ var width = self.data('width') || NETDATA.chartDefaults.width;
+ var height = self.data('height') || NETDATA.chartDefaults.height;
+ var instance = self.html(data).not('[data-created]');
+
+ instance.peity('line', {
+ width: width,
+ height: height
+ })
+ .data('created', true);
+ }
+
+ // ----------------------------------------------------------------------------------------------------------------
+ // sparkline
+
+ NETDATA.sparklineInitialize = function(callback) {
+ if(typeof netdataStopSparkline == 'undefined') {
+ $.getScript(NETDATA.sparkline_js)
+ .done(function() {
+ NETDATA.registerChartLibrary('sparkline', NETDATA.sparkline_js, 'array', 'flip|min2max', 2);
+ })
+ .fail(function() {
+ NETDATA.error(100, NETDATA.sparkline_js);
+ })
+ .always(function() {
+ if(typeof callback == "function")
+ callback();
+ })
+ }
+ else if(typeof callback == "function")
+ callback();
+ };
+
+ NETDATA.sparklineChartUpdate = function(event, data) {
+ var self = $(this);
+ var options = self.data('sparkline-options');
+ self.sparkline(data, options);
+ }
+
+ NETDATA.sparklineChartCreate = function(event, data) {
+ var self = $(this);
+ var chart = self.data('chart');
+ var width = self.data('width') || NETDATA.chartDefaults.width;
+ var height = self.data('height') || NETDATA.chartDefaults.height;
+ var type = self.data('sparkline-type') || 'line';
+ var lineColor = self.data('sparkline-lineColor') || undefined;
+ var fillColor = self.data('sparkline-fillColor') || (chart.chart_type == 'line')?'#FFF':undefined;
+ var chartRangeMin = self.data('sparkline-chartRangeMin') || undefined;
+ var chartRangeMax = self.data('sparkline-chartRangeMax') || undefined;
+ var composite = self.data('sparkline-composite') || undefined;
+ var enableTagOptions = self.data('sparkline-enableTagOptions') || undefined;
+ var tagOptionPrefix = self.data('sparkline-tagOptionPrefix') || undefined;
+ var tagValuesAttribute = self.data('sparkline-tagValuesAttribute') || undefined;
+ var disableHiddenCheck = self.data('sparkline-disableHiddenCheck') || undefined;
+ var defaultPixelsPerValue = self.data('sparkline-defaultPixelsPerValue') || undefined;
+ var spotColor = self.data('sparkline-spotColor') || undefined;
+ var minSpotColor = self.data('sparkline-minSpotColor') || undefined;
+ var maxSpotColor = self.data('sparkline-maxSpotColor') || undefined;
+ var spotRadius = self.data('sparkline-spotRadius') || undefined;
+ var valueSpots = self.data('sparkline-valueSpots') || undefined;
+ var highlightSpotColor = self.data('sparkline-highlightSpotColor') || undefined;
+ var highlightLineColor = self.data('sparkline-highlightLineColor') || undefined;
+ var lineWidth = self.data('sparkline-lineWidth') || undefined;
+ var normalRangeMin = self.data('sparkline-normalRangeMin') || undefined;
+ var normalRangeMax = self.data('sparkline-normalRangeMax') || undefined;
+ var drawNormalOnTop = self.data('sparkline-drawNormalOnTop') || undefined;
+ var xvalues = self.data('sparkline-xvalues') || undefined;
+ var chartRangeClip = self.data('sparkline-chartRangeClip') || undefined;
+ var xvalues = self.data('sparkline-xvalues') || undefined;
+ var chartRangeMinX = self.data('sparkline-chartRangeMinX') || undefined;
+ var chartRangeMaxX = self.data('sparkline-chartRangeMaxX') || undefined;
+ var disableInteraction = self.data('sparkline-disableInteraction') || false;
+ var disableTooltips = self.data('sparkline-disableTooltips') || false;
+ var disableHighlight = self.data('sparkline-disableHighlight') || false;
+ var highlightLighten = self.data('sparkline-highlightLighten') || 1.4;
+ var highlightColor = self.data('sparkline-highlightColor') || undefined;
+ var tooltipContainer = self.data('sparkline-tooltipContainer') || undefined;
+ var tooltipClassname = self.data('sparkline-tooltipClassname') || undefined;
+ var tooltipFormat = self.data('sparkline-tooltipFormat') || undefined;
+ var tooltipPrefix = self.data('sparkline-tooltipPrefix') || undefined;
+ var tooltipSuffix = self.data('sparkline-tooltipSuffix') || ' ' + chart.units;
+ var tooltipSkipNull = self.data('sparkline-tooltipSkipNull') || true;
+ var tooltipValueLookups = self.data('sparkline-tooltipValueLookups') || undefined;
+ var tooltipFormatFieldlist = self.data('sparkline-tooltipFormatFieldlist') || undefined;
+ var tooltipFormatFieldlistKey = self.data('sparkline-tooltipFormatFieldlistKey') || undefined;
+ var numberFormatter = self.data('sparkline-numberFormatter') || function(n){ return n.toFixed(2); };
+ var numberDigitGroupSep = self.data('sparkline-numberDigitGroupSep') || undefined;
+ var numberDecimalMark = self.data('sparkline-numberDecimalMark') || undefined;
+ var numberDigitGroupCount = self.data('sparkline-numberDigitGroupCount') || undefined;
+ var animatedZooms = self.data('sparkline-animatedZooms') || false;
+
+ var options = {
+ type: type,
+ lineColor: lineColor,
+ fillColor: fillColor,
+ chartRangeMin: chartRangeMin,
+ chartRangeMax: chartRangeMax,
+ composite: composite,
+ enableTagOptions: enableTagOptions,
+ tagOptionPrefix: tagOptionPrefix,
+ tagValuesAttribute: tagValuesAttribute,
+ disableHiddenCheck: disableHiddenCheck,
+ defaultPixelsPerValue: defaultPixelsPerValue,
+ spotColor: spotColor,
+ minSpotColor: minSpotColor,
+ maxSpotColor: maxSpotColor,
+ spotRadius: spotRadius,
+ valueSpots: valueSpots,
+ highlightSpotColor: highlightSpotColor,
+ highlightLineColor: highlightLineColor,
+ lineWidth: lineWidth,
+ normalRangeMin: normalRangeMin,
+ normalRangeMax: normalRangeMax,
+ drawNormalOnTop: drawNormalOnTop,
+ xvalues: xvalues,
+ chartRangeClip: chartRangeClip,
+ chartRangeMinX: chartRangeMinX,
+ chartRangeMaxX: chartRangeMaxX,
+ disableInteraction: disableInteraction,
+ disableTooltips: disableTooltips,