4 <title>NetData Dashboard</title>
6 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
8 <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
9 <meta name="viewport" content="width=device-width, initial-scale=1">
10 <meta name="apple-mobile-web-app-capable" content="yes">
11 <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
12 <meta name="author" content="costa@tsaousis.gr">
16 <div class="container-fluid">
17 <div id="charts_div" class="container-fluid"></div>
22 <!-- you can set your netdata server globally, by ucommenting this -->
23 <!-- you can also give a different server per chart, with the attribute: data-host="http://netdata.server:19999" -->
24 <!-- <script> netdataServer = "http://box:19999"; </script> -->
26 <!-- load the dashboard manager - it will do the rest -->
27 <script type="text/javascript" src="dashboard.js"></script>
32 hostnane: 'netdata_server',
33 categories: new Array(),
35 families: new Array(),
43 function screenWidth() {
44 return (($(window).width() * 0.95) - 50);
47 function chartsPerRow(total) {
48 if(options.chartsPerRow === 0) {
49 width = Math.floor(total / options.chartsMinWidth);
50 if(width === 0) width = 1;
53 else return options.chartsPerRow;
56 function chartsPrioritySort(a, b) {
57 if(a.priority === b.priority) {
58 if(a.name < b.name) return -1;
60 else if(a.priority < b.priority) return -1;
64 function uniq(array, find_key, get_result) {
65 if(typeof get_result === 'undefined' || get_result === null)
66 get_result = find_key;
69 var result = new Array();
71 $.each(array, function(i, c) {
73 if(typeof idx[key] === 'undefined') {
75 result.push(get_result(c));
81 function uniq_with_list(array, find_key_function) {
83 var result = new Array();
85 $.each(array, function(i, c) {
86 key = find_key_function(c);
87 if(typeof idx[key] === 'undefined') {
88 idx[key] = new Array();
89 result.push( { name: key, values: idx[key] } );
93 result.sort(function(a, b) {
94 if(a.name < b.name) return -1;
100 function prepareScreen(data) {
101 console.log('NETDATA is paused - ready to prepare the screen');
105 options.hostname = data.hostname;
106 var charts = data.charts;
108 $.each(charts, function(i, c) {
109 if(c.enabled === true) {
111 //if(c.family.length > 4 && c.family.substring(c.family.length - 4, c.family.length) === '-ifb')
112 // c.family = c.family.split('-')[0];
114 // find the category of the chart
115 c.category = c.type.split('.')[0];
117 var tmp = c.category.split('_')[0];
118 if(tmp === 'net' || tmp === 'disk')
123 c.category_priority = 10;
124 c.category_title = 'System';
125 c.glyphicon = "glyphicon-dashboard";
129 c.category_priority = 20;
130 c.category_title = 'Quality Of Service';
131 c.glyphicon = "glyphicon-random";
135 c.category_priority = 30;
136 c.category_title = 'Network Interfaces';
137 c.glyphicon = "glyphicon-transfer";
141 c.category_priority = 40;
142 c.category_title = 'Applications Monitoring';
143 c.glyphicon = "glyphicon-tasks";
147 c.category_priority = 50;
148 c.category_title = 'IP Virtual Server';
149 c.glyphicon = "glyphicon-transfer";
153 c.category_priority = 60;
154 c.category_title = 'Netfilter';
155 c.glyphicon = "glyphicon-cloud";
159 c.category_priority = 70;
160 c.category_title = 'IPv4';
161 c.glyphicon = "glyphicon-globe";
165 c.category_priority = 80;
166 c.category_title = 'Memory';
167 c.glyphicon = "glyphicon-dashboard";
171 c.category_priority = 90;
172 c.category_title = 'CPUs';
173 c.glyphicon = "glyphicon-dashboard";
177 c.category_priority = 100;
178 c.category_title = 'Disks';
179 c.glyphicon = "glyphicon-hdd";
183 c.category_priority = 110;
184 c.category_title = 'NFS Server';
185 c.glyphicon = "glyphicon-hdd";
189 c.category_priority = 140;
190 c.category_title = 'Proxy Server';
191 c.glyphicon = "glyphicon-link";
195 c.category_priority = 150;
196 c.category_title = 'Netdata Monitoring';
197 c.glyphicon = "glyphicon-thumbs-up";
201 c.category_priority = 100000;
202 c.category_title = 'Example Plugins';
203 c.glyphicon = "glyphicon-search";
207 c.category_priority = 150;
208 c.category_title = c.type;
209 c.glyphicon = "glyphicon-dashboard";
213 // find the unique categories
214 if(typeof options.categories_idx[c.category] === 'undefined') {
215 options.categories_idx[c.category] = {
218 options.categories.push({
220 title: c.category_title,
221 priority: c.category_priority,
222 glyphicon: c.glyphicon,
223 charts: options.categories_idx[c.category].charts
226 options.categories_idx[c.category].charts.push(c);
228 // find the unique families
229 if(typeof options.families_idx[c.family] === 'undefined') {
230 options.families_idx[c.family] = {
233 options.families.push({
236 priority: c.category_priority,
237 glyphicon: c.glyphicon,
238 charts: options.categories_idx[c.category].charts
241 options.families_idx[c.family].charts.push(c);
245 function prioritySort(a, b) {
246 if(a.priority < b.priority) return -1;
251 options.categories.sort(prioritySort);
252 options.families.sort(prioritySort);
253 $.each(options.families, function(i, c) { c.charts.sort(prioritySort); });
255 var div = document.getElementById('charts_div');
256 var pcent_width = Math.floor(100 / chartsPerRow($(div).width()));
258 // find the proper duration for per-second updates
259 var duration = Math.round(($(div).width() * pcent_width / 100 * data.update_every / 3) / 60) * 60;
260 console.log(duration);
262 $.each(options.categories, function(i, t) {
263 t.charts.sort(prioritySort);
265 html += '<div class="container-fluid row clearfix"><h2>' + t.title + '</h2>';
267 if(t.name === 'net') {
268 var interfaces = uniq_with_list(t.charts, function(c) { return c.family; });
269 console.log(interfaces);
271 $.each(interfaces, function(i, c) {
272 html += '<div class="netdata-group-container" id="interface_' + c.name + '" style="display: inline-block; width: ' + pcent_width.toString() + '%"><h2 class="netdata-chart-alignment">' + c.name + '</h2>';
273 $.each(c.values, function(x, f) {
274 if(f.type === 'net') {
275 html += '<div data-netdata="' + f.id + '"'
276 + ' data-width="100%"'
277 + ' data-height="' + options.chartsHeight.toString() + 'px"'
279 + ' data-after="-' + duration.toString() + '"'
283 html += '<div data-netdata="' + f.id + '"'
284 + ' data-width="100%"'
285 + ' data-height="' + (options.chartsHeight / 2).toString() + 'px"'
287 + ' data-after="-' + duration.toString() + '"'
294 else if(t.name === 'disk') {
295 var disks = uniq_with_list(t.charts, function(c) { return c.family; });
298 $.each(disks, function(i, c) {
299 html += '<div class="netdata-group-container" id="disk_' + c.name + '" style="display: inline-block; width: ' + pcent_width.toString() + '%"><h2 class="netdata-chart-alignment">' + c.name + '</h2>';
300 $.each(c.values, function(x, f) {
302 var h = options.chartsHeight / 2;
304 case 'disk' : h = options.chartsHeight; break;
305 case 'disk_backlog': c = '#DD4477'; break;
306 case 'disk_util' : c = '#109618'; break;
307 case 'disk_qops' : c = '#8B0707'; break;
310 html += '<div data-netdata="' + f.id + '"'
311 + ' data-width="100%"'
312 + ' data-height="' + h.toString() + 'px"'
314 + ' data-after="-' + duration.toString() + '"'
315 + ' data-colors="' + c + '"'
322 $.each(t.charts, function(x, c) {
323 html += '<div data-netdata="' + c.id + '"'
324 + ' data-width="' + pcent_width.toString() + '%"'
325 + ' data-height="' + options.chartsHeight.toString() + 'px"'
327 + ' data-after="-' + duration.toString() + '"'
336 $.each(NETDATA.colors, function(i, c){
337 html += '<div style="display: inline-block;"><div style="display: inline-block; width: 100px; height: 100px; background: ' + c + ';"></div><br/>' + c + '</div>';
340 div.innerHTML = html;
344 NETDATA.ready(function() {
345 NETDATA.chartRegistry.downloadAll(NETDATA.serverDefault, function(data) {
346 NETDATA.pause(function () {