new resizable dashboard; all charts can now have relative width; more code cleanups
Costa Tsaousis (ktsaou) committed
Dec 2, 2015 at 02:14 UTC
236150e1c9beaf153cbd06a50d354453c632469f
2 files changed
+471
-409
web/dashboard.html
+259
-242
@@ -1,6 +1,16 @@
1
-<html>
1
+<!DOCTYPE html>
2
+<html lang="en">
3
<head>
4
<title>NetData Dashboard</title>
5
+
6
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
7
+ <meta 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">
13
+
14
<style type="text/css">
15
html{font-family:sans-serif;}
16
</style>
@@ -12,7 +22,16 @@
22
This is a template for building custom dashboards. To build a dashboard you just do this:
23
24
<pre>
15
-<html>
25
+<!DOCTYPE html>
26
+<html lang="en">
27
+<head>
28
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
29
+ <meta charset="utf-8">
30
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
31
+ <meta name="viewport" content="width=device-width, initial-scale=1">
32
+ <meta name="apple-mobile-web-app-capable" content="yes">
33
+ <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
34
+</head>
35
<body>
36
<div data-netdata="system.processes"
37
data-chart-library="dygraph"
@@ -35,246 +54,244 @@ This is a template for building custom dashboards. To build a dashboard you just
54
<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>
55
</ul>
56
38
- <table border="0" cellpadding="5" cellspacing="5">
39
- <tr>
40
- <th width="600">
41
- System Processes - Line Chart
42
- </th>
43
- <th width="600">
44
- System ipv4 - Area Chart
45
- </th>
46
- <th width="600">
47
- System CPU - Stacked Area Chart
48
- </th>
49
- </tr>
50
- <tr><td colspan="3"> </td></tr>
51
- <tr><th colspan="3"><hr>Peity Charts</th></tr>
52
- <tr><td colspan="3">
53
- Peity charts do not support 'NULL' values, so the charts cannot indicate that values are missing.
54
- Peity charts cannot have multiple dimensions on the charts - so netdata will use 'min2max' to show
55
- the total of all dimensions.
56
- </td></tr>
57
- <tr>
58
- <td width="600">
59
- <div data-netdata="system.processes"
60
- data-chart-library="peity"
61
- data-width="600"
62
- data-height="30"
63
- data-after="-600"
64
- data-dt-element-name="time11"
65
- </div>
66
- </td>
67
- <td width="600">
68
- <div data-netdata="system.ipv4"
69
- data-chart-library="peity"
70
- data-width="600"
71
- data-height="30"
72
- data-after="-600"
73
- data-dt-element-name="time12"
74
- </div>
75
- </td>
76
- <td width="600">
77
- <div data-netdata="system.cpu"
78
- data-chart-library="peity"
79
- data-width="600"
80
- data-height="30"
81
- data-after="-600"
82
- data-dt-element-name="time13"
83
- </div>
84
- </td>
85
- </tr>
86
- <tr>
87
- <td>rendered in <span id="time11">X</span> ms</td>
88
- <td>rendered in <span id="time12">X</span> ms</td>
89
- <td>rendered in <span id="time13">X</span> ms</td>
90
- </tr>
91
- <tr><td colspan="3"> </td></tr>
92
- <tr><th colspan="3"><hr>Sparkline Charts</th></tr>
93
- <tr><td colspan="3">
94
- Sparkline charts support 'NULL' values, so the charts can indicate that values are missing.
95
- Sparkline charts stretch the values to show the variations between values in more detail.
96
- They also have mouse-hover support.
97
- <br/>
98
- Sparklines are fantastic. You can inline charts in text. For example this
99
- <div data-netdata="system.cpu"
100
- data-chart-library="sparkline"
101
- data-width="60"
102
- data-height="20"
103
- data-after="-30"
104
- ></div> is my current cpu usage,
105
- <br/>
106
- while this
107
- <div data-netdata="netdata.net"
108
- data-dimensions="out"
109
- data-chart-library="sparkline"
110
- data-width="60"
111
- data-height="20"
112
- data-after="-30"
113
- ></div> is the bandwidth my netdata server is currently transmitting and this
114
-
115
- <div data-netdata="netdata.requests"
116
- data-chart-library="sparkline"
117
- data-width="360"
118
- data-height="20"
119
- data-after="-180"
120
- ></div> is the requests/sec it serves.
121
- </td></tr>
122
- <tr>
123
- <td width="600">
124
- <div data-netdata="system.processes"
125
- data-chart-library="sparkline"
126
- data-width="600"
127
- data-height="30"
128
- data-after="-600"
129
- data-dt-element-name="time21"
130
- ></div>
131
- </td>
132
- <td width="600">
133
- <div data-netdata="system.ipv4"
134
- data-chart-library="sparkline"
135
- data-width="600"
136
- data-height="30"
137
- data-after="-600"
138
- data-dt-element-name="time22"
139
- ></div>
140
- </td>
141
- <td width="600">
142
- <div data-netdata="system.cpu"
143
- data-chart-library="sparkline"
144
- data-width="600"
145
- data-height="30"
146
- data-after="-600"
147
- data-dt-element-name="time23"
148
- ></div>
149
- </td>
150
- </tr>
151
- <tr>
152
- <td>rendered in <span id="time21">X</span> ms</td>
153
- <td>rendered in <span id="time22">X</span> ms</td>
154
- <td>rendered in <span id="time23">X</span> ms</td>
155
- </tr>
156
- <tr><td colspan="3"> </td></tr>
157
- <tr><th colspan="3"><hr>Dygraph Charts</th></tr>
158
- <tr><td colspan="3">
159
- The fastest charting engine that can chart complete charts (not just sparklines).
160
- The charts are zoomable (drag their contents to zoom-in, double click to zoom-out).
161
- For the moment zooming is just on the presentation layer (the data do not become more detailed when you zoom).
162
- </td></tr>
163
- <tr>
164
- <td width="600">
165
- <div data-netdata="system.processes"
166
- data-chart-library="dygraph"
167
- data-width="600"
168
- data-height="200"
169
- data-after="-600"
170
- data-dt-element-name="time31"
171
- ></div>
172
- </td>
173
- <td width="600">
174
- <div data-netdata="system.ipv4"
175
- data-chart-library="dygraph"
176
- data-width="600"
177
- data-height="200"
178
- data-after="-600"
179
- data-dt-element-name="time32"
180
- ></div>
181
- </td>
182
- <td width="600">
183
- <div data-netdata="system.cpu"
184
- data-chart-library="dygraph"
185
- data-width="600"
186
- data-height="200"
187
- data-after="-600"
188
- data-dt-element-name="time33"
189
- ></div>
190
- </td>
191
- </tr>
192
- <tr>
193
- <td>rendered in <span id="time31">X</span> ms</td>
194
- <td>rendered in <span id="time32">X</span> ms</td>
195
- <td>rendered in <span id="time33">X</span> ms</td>
196
- </tr>
197
- <tr><td colspan="3"> </td></tr>
198
- <tr><th colspan="3"><hr>Google Charts</th></tr>
199
- <tr><td colspan="3">
200
- NetData was originaly developed with Google Charts.
201
- NetData is a complete Google Visualization API provider.
202
- </td></tr>
203
- <tr>
204
- <td width="600">
205
- <div data-netdata="system.processes"
206
- data-chart-library="google"
207
- data-width="600"
208
- data-height="200"
209
- data-after="-600"
210
- data-dt-element-name="time51"
211
- ></div>
212
- </td>
213
- <td width="600">
214
- <div data-netdata="system.ipv4"
215
- data-chart-library="google"
216
- data-width="600"
217
- data-height="200"
218
- data-after="-600"
219
- data-dt-element-name="time52"
220
- ></div>
221
- </td>
222
- <td width="600">
223
- <div data-netdata="system.cpu"
224
- data-chart-library="google"
225
- data-width="600"
226
- data-height="200"
227
- data-after="-600"
228
- data-dt-element-name="time53"
229
- ></div>
230
- </td>
231
- </tr>
232
- <tr>
233
- <td>rendered in <span id="time51">X</span> ms</td>
234
- <td>rendered in <span id="time52">X</span> ms</td>
235
- <td>rendered in <span id="time53">X</span> ms</td>
236
- </tr>
237
- <tr><td colspan="3"> </td></tr>
238
- <tr><th colspan="3"><hr>Morris Charts</th></tr>
239
- <tr><td colspan="3">
240
- Unfortunatelly, Morris Charts are veeeeeeeeeeeeeeeery slow! We force them to lower their detail to get acceptable results.
241
- And they have issues with negative numbers in area charts...
242
- </td></tr>
243
- <tr>
244
- <td width="600">
245
- <div data-netdata="system.processes"
246
- data-chart-library="morris"
247
- data-width="600"
248
- data-height="200"
249
- data-after="-600"
250
- data-dt-element-name="time41"
251
- ></div>
252
- </td>
253
- <td width="600">
254
- <div data-netdata="system.ipv4"
255
- data-chart-library="morris"
256
- data-width="600"
257
- data-height="200"
258
- data-after="-600"
259
- data-dt-element-name="time42"
260
- ></div>
261
- </td>
262
- <td width="600">
263
- <div data-netdata="system.cpu"
264
- data-chart-library="morris"
265
- data-width="600"
266
- data-height="200"
267
- data-after="-600"
268
- data-dt-element-name="time43"
269
- ></div>
270
- </td>
271
- </tr>
272
- <tr>
273
- <td>rendered in <span id="time41">X</span> ms</td>
274
- <td>rendered in <span id="time42">X</span> ms</td>
275
- <td>rendered in <span id="time43">X</span> ms</td>
276
- </tr>
277
- </table>
57
+
58
+<hr>
59
+<h1>Sparkline Charts</h1>
60
+Sparkline charts support 'NULL' values, so the charts can indicate that values are missing.
61
+Sparkline charts stretch the values to show the variations between values in more detail.
62
+They also have mouse-hover support.
63
+<br/>
64
+<b>Sparklines are fantastic</b>. You can inline charts in text. For example this
65
+ <div data-netdata="system.cpu"
66
+ data-chart-library="sparkline"
67
+ data-width="5%"
68
+ data-height="20"
69
+ data-after="-30"
70
+ ></div> is my current cpu usage (last 30 seconds),
71
+ while this
72
+ <div data-netdata="netdata.net"
73
+ data-dimensions="out"
74
+ data-chart-library="sparkline"
75
+ data-width="10%"
76
+ data-height="20"
77
+ data-after="-60"
78
+ ></div> is the bandwidth my netdata server is currently transmitting (last minute)
79
+ and this
80
+ <div data-netdata="netdata.requests"
81
+ data-chart-library="sparkline"
82
+ data-width="20%"
83
+ data-height="20"
84
+ data-after="-180"
85
+ ></div> is the requests/sec it serves (last 3 minutes).
86
+
87
+<br/>
88
+<div style="width: 32%; display: inline-block;">
89
+ <div data-netdata="system.processes"
90
+ data-chart-library="sparkline"
91
+ data-width="100%"
92
+ data-height="30"
93
+ data-after="-600"
94
+ data-dt-element-name="time101"
95
+ ></div>
96
+ <br/>
97
+ <small>rendered in <span id="time101">X</span> ms</small>
98
+</div>
99
+<div style="width: 32%; display: inline-block;">
100
+ <div data-netdata="system.ipv4"
101
+ data-chart-library="sparkline"
102
+ data-width="100%"
103
+ data-height="30"
104
+ data-after="-600"
105
+ data-dt-element-name="time102"
106
+ ></div>
107
+ <br/>
108
+ <small>rendered in <span id="time102">X</span> ms</small>
109
+</div>
110
+<div style="width: 32%; display: inline-block;">
111
+ <div data-netdata="system.cpu"
112
+ data-chart-library="sparkline"
113
+ data-width="100%"
114
+ data-height="30"
115
+ data-after="-600"
116
+ data-dt-element-name="time103"
117
+ ></div>
118
+ <br/>
119
+ <small>rendered in <span id="time103">X</span> ms</small>
120
+</div>
121
+
122
+
123
+
124
+<hr>
125
+<h1>Peity Charts</h1>
126
+Peity charts do not support 'NULL' values, so the charts cannot indicate that values are missing.
127
+Peity charts cannot have multiple dimensions on the charts - so netdata will use 'min2max' to show
128
+the total of all dimensions.
129
+<br/>
130
+<div style="width: 32%; display: inline-block;">
131
+ <div data-netdata="system.processes"
132
+ data-chart-library="peity"
133
+ data-width="100%"
134
+ data-height="30"
135
+ data-after="-600"
136
+ data-dt-element-name="time001"
137
+ ></div>
138
+ <br/>
139
+ <small>rendered in <span id="time001">X</span> ms</small>
140
+</div>
141
+<div style="width: 32%; display: inline-block;">
142
+ <div data-netdata="system.ipv4"
143
+ data-chart-library="peity"
144
+ data-width="100%"
145
+ data-height="30"
146
+ data-after="-600"
147
+ data-dt-element-name="time002"
148
+ ></div>
149
+ <br/>
150
+ <small>rendered in <span id="time002">X</span> ms</small>
151
+</div>
152
+<div style="width: 32%; display: inline-block;">
153
+ <div data-netdata="system.cpu"
154
+ data-chart-library="peity"
155
+ data-width="100%"
156
+ data-height="30"
157
+ data-after="-600"
158
+ data-dt-element-name="time003"
159
+ ></div>
160
+ <br/>
161
+ <small>rendered in <span id="time003">X</span> ms</small>
162
+</div>
163
+
164
+
165
+
166
+
167
+<hr>
168
+<h1>Dygraph Charts</h1>
169
+The fastest charting engine that can chart complete charts (not just sparklines).
170
+The charts are zoomable (drag their contents to zoom-in, double click to zoom-out).
171
+For the moment zooming is just on the presentation layer (the data do not become more detailed when you zoom).
172
+<br/>
173
+<div style="width: 32%; display: inline-block;">
174
+ <div data-netdata="system.processes"
175
+ data-chart-library="dygraph"
176
+ data-width="100%"
177
+ data-height="200"
178
+ data-after="-600"
179
+ data-dt-element-name="time201"
180
+ ></div>
181
+ <br/>
182
+ <small>rendered in <span id="time201">X</span> ms</small>
183
+</div>
184
+<div style="width: 32%; display: inline-block;">
185
+ <div data-netdata="system.ipv4"
186
+ data-chart-library="dygraph"
187
+ data-width="100%"
188
+ data-height="200"
189
+ data-after="-600"
190
+ data-dt-element-name="time202"
191
+ ></div>
192
+ <br/>
193
+ <small>rendered in <span id="time202">X</span> ms</small>
194
+</div>
195
+<div style="width: 32%; display: inline-block;">
196
+ <div data-netdata="system.cpu"
197
+ data-chart-library="dygraph"
198
+ data-width="100%"
199
+ data-height="200"
200
+ data-after="-600"
201
+ data-dt-element-name="time203"
202
+ ></div>
203
+ <br/>
204
+ <small>rendered in <span id="time203">X</span> ms</small>
205
+</div>
206
+
207
+
208
+
209
+
210
+<hr>
211
+<h1>Google Charts</h1>
212
+NetData was originaly developed with Google Charts.
213
+NetData is a complete Google Visualization API provider.
214
+<br/>
215
+<div style="width: 32%; display: inline-block;">
216
+ <div data-netdata="system.processes"
217
+ data-chart-library="google"
218
+ data-width="100%"
219
+ data-height="200"
220
+ data-after="-600"
221
+ data-dt-element-name="time301"
222
+ ></div>
223
+ <br/>
224
+ <small>rendered in <span id="time301">X</span> ms</small>
225
+</div>
226
+<div style="width: 32%; display: inline-block;">
227
+ <div data-netdata="system.ipv4"
228
+ data-chart-library="google"
229
+ data-width="100%"
230
+ data-height="200"
231
+ data-after="-600"
232
+ data-dt-element-name="time302"
233
+ ></div>
234
+ <br/>
235
+ <small>rendered in <span id="time302">X</span> ms</small>
236
+</div>
237
+<div style="width: 32%; display: inline-block;">
238
+ <div data-netdata="system.cpu"
239
+ data-chart-library="google"
240
+ data-width="100%"
241
+ data-height="200"
242
+ data-after="-600"
243
+ data-dt-element-name="time303"
244
+ ></div>
245
+ <br/>
246
+ <small>rendered in <span id="time303">X</span> ms</small>
247
+</div>
248
+
249
+
250
+
251
+
252
+
253
+
254
+<hr>
255
+<h1>Morris Charts</h1>
256
+Unfortunatelly, Morris Charts are veeeeeeeeeeeeeeeery slow! We force them to lower their detail to get acceptable results.
257
+<br/>
258
+<div style="width: 32%; display: inline-block;">
259
+ <div data-netdata="system.processes"
260
+ data-chart-library="morris"
261
+ data-width="100%"
262
+ data-height="200"
263
+ data-after="-600"
264
+ data-dt-element-name="time401"
265
+ ></div>
266
+ <br/>
267
+ <small>rendered in <span id="time401">X</span> ms</small>
268
+</div>
269
+<div style="width: 32%; display: inline-block;">
270
+ <div data-netdata="system.ipv4"
271
+ data-chart-library="morris"
272
+ data-width="100%"
273
+ data-height="200"
274
+ data-after="-600"
275
+ data-dt-element-name="time402"
276
+ ></div>
277
+ <br/>
278
+ <small>rendered in <span id="time402">X</span> ms</small>
279
+</div>
280
+<div style="width: 32%; display: inline-block;">
281
+ <div data-netdata="system.cpu"
282
+ data-chart-library="morris"
283
+ data-width="100%"
284
+ data-height="200"
285
+ data-after="-600"
286
+ data-dt-element-name="time403"
287
+ ></div>
288
+ <br/>
289
+ <small>rendered in <span id="time403">X</span> ms</small>
290
+</div>
291
+
292
+
293
+
294
+
295
296
</body>
297
</html>
web/dashboard.js
+212
-167
@@ -16,6 +16,9 @@
16
17
(function(window)
18
{
19
+ // fix IE bug with console
20
+ if(!window.console){ window.console = {log: function(){} }; }
21
+
22
var NETDATA = window.NETDATA || {};
23
24
// ----------------------------------------------------------------------------------------------------------------
@@ -76,25 +79,26 @@
79
80
NETDATA.chartDefaults = {
81
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
+ width: '100%', // the chart width
83
+ height: '100%', // the chart height
84
+ library: 'dygraph', // the graphing library to use
85
method: 'average', // the grouping method
86
before: 0, // panning
87
after: -600, // panning
85
- pixels_per_point: 1, // the detail of the chart
88
+ pixels_per_point: 1 // the detail of the chart
89
}
90
91
NETDATA.options = {
89
- targets: null,
92
+ targets: null,
93
updated_dom: 1,
94
debug: 1,
95
+ last_paused: 0,
96
97
current: {
98
pixels_per_point: 1,
95
- idle_between_charts: 50,
96
- idle_between_loops: 100,
97
- debug: 1
99
+ idle_between_charts: 100,
100
+ idle_between_loops: 500,
101
+ fast_render_timeframe: 200 // render continously for these many ms
102
}
103
}
104
@@ -108,12 +112,12 @@
112
100: { message: "Cannot load chart library", alert: true },
113
101: { message: "Cannot load jQuery", alert: true },
114
402: { message: "Chart library not found", alert: false },
111
- 404: { message: "Chart not found", alert: false },
115
+ 404: { message: "Chart not found", alert: false }
116
};
117
NETDATA.errorLast = {
118
code: 0,
119
message: "",
116
- datetime: 0,
120
+ datetime: 0
121
};
122
123
NETDATA.error = function(code, msg) {
@@ -133,19 +137,18 @@
137
NETDATA.errorLast.datetime = 0;
138
}
139
136
- NETDATA.chartContainer = function(element, width, height) {
140
+ NETDATA.messageInABox = function(element, message) {
141
self = $(element);
138
- self.css('width', width)
139
- .css('height', height)
140
- .css('display', 'inline-block')
141
- .css('overflow', 'hidden');
142
- }
142
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>'
143
+ bgcolor = ""
144
+ if(NETDATA.options.debug)
145
+ bgcolor = " background-color: lightgrey;";
146
+
147
+ element.innerHTML = '<div style="overflow: hidden;' + bgcolor + ' width: 100%; height: 100%;"><small>'
148
+ message
149
+ '</small></div>';
150
+
151
+ self.data('created', false);
152
}
153
154
// ----------------------------------------------------------------------------------------------------------------
@@ -171,63 +174,77 @@
174
callback();
175
}
176
174
- NETDATA.generateChartDataURL = function(options) {
177
+ NETDATA.generateChartDataURL = function() {
178
+ self = $(this);
179
+
180
+ var chart = self.data('chart');
181
+ var host = self.data('host') || NETDATA.chartDefaults.host;
182
+ var width = self.width();
183
+ var height = self.height();
184
+ var method = self.data('method') || NETDATA.chartDefaults.method;
185
+ var after = self.data('after') || NETDATA.chartDefaults.after;
186
+ var before = self.data('before') || NETDATA.chartDefaults.before;
187
+ var library = self.data('chart-library') || NETDATA.chartDefaults.library;
188
+ var dimensions = self.data('dimensions') || null;
189
+ var pixels_per_point = self.data('pixels-per-point') || NETDATA.chartLibraries[library].pixels_per_point;
190
+
191
+ // force an options provided detail
192
+ if(pixels_per_point < NETDATA.options.current.pixels_per_point)
193
+ pixels_per_point = NETDATA.options.current.pixels_per_point
194
+
195
+ var points = self.data('points') || Math.round(width / pixels_per_point);
196
+
197
// build the data URL
176
- var url = options.host + options.url;
177
- url += "&points=";
178
- url += options.points.toString();
179
- url += "&group=";
180
- url += options.method;
181
- url += "&after=";
182
- url += options.after || "0";
183
- url += "&before=";
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;
188
-
189
- if(options.dimensions)
190
- url += "&dimensions=" + options.dimensions;
191
-
192
- if(NETDATA.options.debug) console.log('generateChartDataURL(' + options + ') = ' + url );
198
+ var url = host + chart.data_url;
199
+ url += "&format=" + NETDATA.chartLibraries[library].format;
200
+ url += "&points=" + points.toString();
201
+ url += "&options=" + NETDATA.chartLibraries[library].options;
202
+ url += "&group=" + method;
203
+
204
+ if(after)
205
+ url += "&after=" + after.toString();
206
+
207
+ if(before)
208
+ url += "&before=" + before.toString();
209
+
210
+ if(dimensions)
211
+ url += "&dimensions=" + dimensions;
212
+
213
+ self.data('calculated-width', width)
214
+ .data('calculated-height', height)
215
+ .data('calculated-points', points)
216
+ .data('calculated-url', url);
217
+
218
+ if(NETDATA.options.debug) console.log('generateChartDataURL(): ' + url + ' WxH:' + width + 'x' + height + ' points: ' + points + ' library: ' + library);
219
return url;
220
}
221
196
- NETDATA.parseDomCharts = function(targets, index, callback) {
197
- if(NETDATA.options.debug) console.log('parseDomCharts() working on ' + index);
222
+ NETDATA.validateDomCharts = function(targets, index, callback) {
223
+ if(NETDATA.options.debug) console.log('validateDomCharts() working on ' + index);
224
225
var target = targets.get(index);
226
if(target == null) {
201
- if(NETDATA.options.debug) console.log('parseDomCharts(): all ' + (index - 1) + ' charts parsed.');
227
+ if(NETDATA.options.debug) console.log('validateDomCharts(): all ' + (index - 1) + ' charts parsed.');
228
if(typeof callback == 'function') callback();
229
}
230
else {
231
var self = $(target);
232
if(!self.data('prepared')) {
207
- self.data('prepared', true);
233
+ self.data('prepared', true)
234
+ .data('updated', 0)
235
+ .data('created', false)
236
+ .data('enabled', false);
237
238
var id = self.data('netdata');
239
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;
240
var library = self.data('chart-library') || NETDATA.chartDefaults.library;
217
- var dimensions = self.data('dimensions') || null;
241
219
- NETDATA.chartContainer(target, width, height);
220
- if(NETDATA.options.debug) console.log('parseDomCharts() parsing ' + id + ' of type ' + library);
242
+ if(NETDATA.options.debug) console.log('validateDomCharts() parsing ' + id + ' of type ' + library);
243
244
if(typeof NETDATA.chartLibraries[library] == 'undefined') {
223
- self.data('created', false)
224
- .data('updated', 0)
225
- .data('enabled', false);
226
-
245
NETDATA.error(402, library);
228
- NETDATA.messageInABox(target, width, height, 'chart library "' + library + '" is not found');
229
-
230
- NETDATA.parseDomCharts(targets, ++index, callback);
246
+ NETDATA.messageInABox(target, 'chart library "' + library + '" is not found');
247
+ NETDATA.validateDomCharts(targets, ++index, callback);
248
}
249
else {
250
var url = host + "/api/v1/chart?chart=" + id;
@@ -237,93 +254,96 @@
254
crossDomain: true
255
})
256
.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);
242
-
243
- var url = NETDATA.generateChartDataURL({
244
- host: host,
245
- url: chart.data_url,
246
- dimensions: dimensions,
247
- library: library,
248
- method: method,
249
- before: before,
250
- points: points,
251
- after: after,
252
- non_zero: null
253
- });
254
-
255
- // done processing of this DIV
256
- // store the processing result, in
257
- // 'data' sections in the DIV
257
self.data('chart', chart)
259
- .data('chart-url', url)
258
.data('update-every', chart.update_every * 1000)
261
- .data('created', false)
262
- .data('updated', 0)
259
.data('enabled', true)
260
.data('host', host)
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)
272
- ;
273
-
274
- NETDATA.messageInABox(target, width, height, 'chart "' + id + '" is loading...');
261
+ .data('chart-library', library);
262
})
263
.fail(function() {
277
- self.data('created', false)
278
- .data('enabled', false);
279
-
264
NETDATA.error(404, url);
281
- NETDATA.messageInABox(target, width, height, 'chart "' + id + '" not found on url "' + url + '"');
265
+ NETDATA.messageInABox(target, 'chart "' + id + '" not found on url "' + url + '"');
266
})
267
.always(function() {
284
- self.data('updated', 0);
285
- NETDATA.parseDomCharts(targets, ++index, callback);
268
+ NETDATA.validateDomCharts(targets, ++index, callback);
269
});
270
}
271
}
272
}
273
}
274
275
+ NETDATA.sizeDomCharts = function(targets, index, callback) {
276
+ // this is used to quickly size all charts to their size
277
+
278
+ if(NETDATA.options.debug) console.log('sizeDomCharts() working on ' + index);
279
+
280
+ var target = targets.get(index);
281
+ if(target == null) {
282
+ if(NETDATA.options.debug) console.log('sizeDomCharts(): all ' + (index - 1) + ' charts sized.');
283
+ if(typeof callback == 'function') callback();
284
+ }
285
+ else {
286
+ var self = $(target);
287
+
288
+ var id = self.data('netdata');
289
+ var width = self.data('width') || NETDATA.chartDefaults.width;
290
+ var height = self.data('height') || NETDATA.chartDefaults.height;
291
+
292
+ self.css('width', width)
293
+ .css('height', height)
294
+ .css('display', 'inline-block')
295
+ .css('overflow', 'hidden');
296
+
297
+ NETDATA.messageInABox(target, 'chart "' + id + '" is loading...');
298
+ NETDATA.sizeDomCharts(targets, ++index, callback);
299
+ }
300
+ }
301
+
302
NETDATA.domUpdated = function(callback) {
303
NETDATA.options.updated_dom = 0;
304
295
- NETDATA.options.targets = $('div[data-netdata]') // .filter(':visible')
305
+ NETDATA.options.targets = $('div[data-netdata]').filter(':visible')
306
.bind('create', function(event, data) {
307
var self = $(this);
298
- try {
308
+
309
+ if(NETDATA.options.debug)
310
NETDATA.chartLibraries[self.data('chart-library')].create(this, data);
300
- }
301
- catch(err) {
302
- NETDATA.messageInABox(this, self.data('width'), self.data('height'), 'chart "' + id + '" failed to be created as ' + self.data('chart-library'));
311
+ else {
312
+ try {
313
+ NETDATA.chartLibraries[self.data('chart-library')].create(this, data);
314
+ }
315
+ catch(err) {
316
+ NETDATA.messageInABox(this, 'chart "' + self.data('netdata') + '" failed to be created as ' + self.data('chart-library'));
317
+ self.data('created', false);
318
+ }
319
}
320
})
321
.bind('update', function(event, data) {
322
var self = $(this);
307
- try {
323
+ if(NETDATA.options.debug)
324
NETDATA.chartLibraries[self.data('chart-library')].update(this, data);
309
- }
310
- catch(err) {
311
- NETDATA.messageInABox(this, self.data('width'), self.data('height'), 'chart "' + id + '" failed to be updated as ' + self.data('chart-library'));
325
+ else {
326
+ try {
327
+ NETDATA.chartLibraries[self.data('chart-library')].update(this, data);
328
+ }
329
+ catch(err) {
330
+ NETDATA.messageInABox(this, 'chart "' + self.data('netdata') + '" failed to be updated as ' + self.data('chart-library'));
331
+ self.data('created', false);
332
+ }
333
}
334
});
335
336
if(NETDATA.options.debug)
337
console.log('DOM updated - there are ' + NETDATA.options.targets.length + ' charts on page.');
338
318
- NETDATA.parseDomCharts(NETDATA.options.targets, 0, callback);
339
+ NETDATA.sizeDomCharts(NETDATA.options.targets, 0, function() {
340
+ NETDATA.validateDomCharts(NETDATA.options.targets, 0, callback);
341
+ });
342
}
343
344
NETDATA.init = function() {
345
+ // this should be called only once
346
NETDATA.domUpdated(function() {
323
- // done processing all netdata DIVs in this page
324
- // call the refresh handler
325
-
326
- // FIXME
347
NETDATA.chartRefresher(0);
348
});
349
}
@@ -358,7 +378,7 @@
378
else {
379
console.log(self.data('netdata') + ' is visible, downloading data...');
380
$.ajax( {
361
- url: self.data('chart-url'),
381
+ url: NETDATA.generateChartDataURL.call(element), // self.data('chart-url'),
382
crossDomain: true
383
})
384
.then(function(data) {
@@ -391,7 +411,7 @@
411
}
412
})
413
.fail(function() {
394
- NETDATA.messageInABox(element, self.data('width'), self.data('height'), 'cannot download chart "' + self.data('netdata') + '" values from url "' + self.data('chart-url') + '"');
414
+ NETDATA.messageInABox(element, 'cannot download chart "' + self.data('netdata') + '" values from url "' + self.data('chart-url') + '"');
415
})
416
.always(function() {
417
if(typeof callback == 'function') callback();
@@ -402,6 +422,8 @@
422
NETDATA.chartRefresher = function(index) {
423
// if(NETDATA.options.debug) console.log('NETDATA.chartRefresher(<targets, ' + index + ')');
424
425
+ now = new Date().getTime();
426
+
427
if(NETDATA.options.updated_dom) {
428
NETDATA.domUpdated(function() {
429
NETDATA.chartRefresher(0);
@@ -410,9 +432,9 @@
432
else {
433
var target = NETDATA.options.targets.get(index);
434
if(target == null) {
413
- console.log('waiting to restart main loop...');
435
+ if(NETDATA.options.debug) console.log('waiting to restart main loop...');
436
+ NETDATA.options.last_paused = now;
437
415
- // finished, restart
438
setTimeout(function() {
439
NETDATA.chartRefresher(0);
440
}, NETDATA.options.current.idle_between_loops);
@@ -423,11 +445,23 @@
445
NETDATA.chartRefresher(++index);
446
}
447
else {
426
- setTimeout(function() {
448
+ if(now - NETDATA.options.last_paused < NETDATA.options.current.fast_render_timeframe) {
449
+ if(NETDATA.options.debug) console.log('fast rendering...');
450
+
451
NETDATA.chartValuesDownloader(target, function() {
452
NETDATA.chartRefresher(++index);
453
});
430
- }, NETDATA.options.current.idle_between_charts);
454
+ }
455
+ else {
456
+ if(NETDATA.options.debug) console.log('waiting for next refresh...');
457
+ NETDATA.options.last_paused = now;
458
+
459
+ setTimeout(function() {
460
+ NETDATA.chartValuesDownloader(target, function() {
461
+ NETDATA.chartRefresher(++index);
462
+ });
463
+ }, NETDATA.options.current.idle_between_charts);
464
+ }
465
}
466
}
467
}
@@ -466,21 +500,39 @@
500
501
NETDATA.peityChartUpdate = function(element, data) {
502
var self = $(element);
469
- var instance = self.html(data).not('[data-created]');
470
- instance.change();
503
+ var instance = self.data('peity-instance');
504
+ var ins = $(instance);
505
+ ins.html(data);
506
+
507
+ // peity.change() does not accept options
508
+ // to pass width and height
509
+ //ins.change();
510
+ ins.peity('line', { width: self.data('calculated-width'), height: self.data('calculated-height') })
511
}
512
513
NETDATA.peityChartCreate = function(element, data) {
514
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]');
515
479
- instance.peity('line', {
480
- width: width,
481
- height: height
482
- })
483
- .data('created', true);
516
+ if(!NETDATA.chartLibraries.peity.initialized) {
517
+ if(!NETDATA.chartLibraries.peity.enabled) {
518
+ NETDATA.messageInABox(element, 'peity is disabled.');
519
+ }
520
+ else {
521
+ NETDATA.messageInABox(element, 'peity is initializing...');
522
+
523
+ }
524
+ }
525
+
526
+ var uuid = NETDATA.guid();
527
+ element.innerHTML = '<div id="' + uuid + '">' + data + '</div>';
528
+ var instance = document.getElementById(uuid);
529
+ var ins = $(instance);
530
+
531
+ ins.peity('line', { width: self.data('calculated-width'), height: self.data('calculated-height') })
532
+
533
+ self.data('peity-uuid', uuid)
534
+ .data('peity-instance', instance)
535
+ .data('created', true);
536
}
537
538
// ----------------------------------------------------------------------------------------------------------------
@@ -507,14 +559,14 @@
559
NETDATA.sparklineChartUpdate = function(element, data) {
560
var self = $(element);
561
var options = self.data('sparkline-options');
562
+ options.width = self.data('calculated-width');
563
+ options.height = self.data('calculated-height');
564
self.sparkline(data, options);
565
}
566
567
NETDATA.sparklineChartCreate = function(element, data) {
568
var self = $(element);
569
var chart = self.data('chart');
516
- var width = self.data('width') || NETDATA.chartDefaults.width;
517
- var height = self.data('height') || NETDATA.chartDefaults.height;
570
var type = self.data('sparkline-type') || 'line';
571
var lineColor = self.data('sparkline-lineColor') || undefined;
572
var fillColor = self.data('sparkline-fillColor') || (chart.chart_type == 'line')?'#FFF':undefined;
@@ -609,8 +661,8 @@
661
numberDecimalMark: numberDecimalMark,
662
numberDigitGroupCount: numberDigitGroupCount,
663
animatedZooms: animatedZooms,
612
- width: width,
613
- height: height
664
+ width: self.data('calculated-width'),
665
+ height: self.data('calculated-height')
666
};
667
668
var uuid = NETDATA.guid();
@@ -674,7 +726,11 @@
726
727
if(dygraph != null) {
728
console.log('updating dygraphs');
677
- dygraph.updateOptions( { 'file': data.data, 'labels': data.labels } );
729
+ dygraph.updateOptions({
730
+ file: data.data,
731
+ labels: data.labels,
732
+ labelsDivWidth: self.width() - 70
733
+ });
734
}
735
else
736
console.log('not updating dygraphs');
@@ -682,8 +738,6 @@
738
739
NETDATA.dygraphChartCreate = function(element, data) {
740
var self = $(element);
685
- var width = self.data('width') || NETDATA.chartDefaults.width;
686
- var height = self.data('height') || NETDATA.chartDefaults.height;
741
var chart = self.data('chart');
742
var title = self.data('dygraph-title') || chart.title;
743
var titleHeight = self.data('dygraph-titleHeight') || 20;
@@ -695,8 +749,9 @@
749
var hideOverlayOnMouseOut = self.data('dygraph-hideOverlayOnMouseOut') || true;
750
var fillGraph = self.data('dygraph-fillGraph') || (chart.chart_type == 'area')?true:false;
751
var drawPoints = self.data('dygraph-drawPoints') || false;
698
- var labelsDivStyles = self.data('dygraph-labelsDivStyles') || { 'fontSize':'10' };
699
- var labelsDivWidth = self.data('dygraph-labelsDivWidth') || 250;
752
+ var labelsDivStyles = self.data('dygraph-labelsDivStyles') || { 'fontSize':'10px' };
753
+ // var labelsDivWidth = self.data('dygraph-labelsDivWidth') || 250;
754
+ var labelsDivWidth = self.width() - 70;
755
var labelsSeparateLines = self.data('dygraph-labelsSeparateLines') || false;
756
var labelsShowZeroValues = self.data('dygraph-labelsShowZeroValues') || true;
757
var legend = self.data('dygraph-legend') || 'onmouseover';
@@ -780,8 +835,6 @@
835
showRoller: showRoller,
836
valueFormatter: valueFormatter,
837
rightGap: rightGap,
783
- width: width,
784
- height: height,
838
labels: data.labels,
839
axes: {
840
x: {
@@ -796,21 +849,21 @@
849
}
850
},
851
y: {
799
- pixelsPerLabel: 15,
852
+ pixelsPerLabel: 15
853
}
854
}
855
};
856
857
var uuid = NETDATA.guid();
805
- self.html('<div id="' + uuid + '"></div>');
858
+ self.html('<div id="' + uuid + '" style="width: 100%; height: 100%;"></div>');
859
860
var dchart = new Dygraph(document.getElementById(uuid),
861
data.data, options);
862
863
self.data('dygraph-instance', dchart)
811
- .data('dygraph-options', options)
812
- .data('uuid', uuid)
813
- .data('created', true);
864
+ .data('dygraph-options', options)
865
+ .data('uuid', uuid)
866
+ .data('created', true);
867
868
//NETDATA.dygraphAllCharts.push(dchart);
869
//if(NETDATA.dygraphAllCharts.length > 1)
@@ -848,8 +901,6 @@
901
902
NETDATA.morrisChartUpdate = function(element, data) {
903
var self = $(element);
851
- var width = self.data('width') || NETDATA.chartDefaults.width;
852
- var height = self.data('height') || NETDATA.chartDefaults.height;
904
var morris = self.data('morris-instance');
905
906
if(typeof data.update_every != 'undefined')
@@ -865,17 +916,16 @@
916
917
NETDATA.morrisChartCreate = function(element, data) {
918
var self = $(element);
868
- var width = self.data('width') || NETDATA.chartDefaults.width;
869
- var height = self.data('height') || NETDATA.chartDefaults.height;
919
var chart = self.data('chart');
920
872
- self.html('<div id="morris-' + chart.id + '" style="width: ' + width + 'px; height: ' + height + 'px;"></div>');
921
+ var uuid = NETDATA.guid();
922
+ self.html('<div id="' + uuid + '" style="width: ' + self.data('calculated-width') + 'px; height: ' + self.data('calculated-height') + 'px;"></div>');
923
924
// remove the 'time' element from the labels
925
data.labels.splice(0, 1);
926
927
var options = {
878
- element: 'morris-' + chart.id,
928
+ element: uuid,
929
data: data.data,
930
xkey: 'time',
931
ykeys: data.labels,
@@ -886,9 +936,7 @@
936
hideHover: 'auto',
937
parseTime: true,
938
continuousLine: false,
889
- behaveLikeLine: false,
890
- width: width,
891
- height: height
939
+ behaveLikeLine: false
940
};
941
942
var morris;
@@ -929,23 +977,19 @@
977
978
NETDATA.raphaelChartUpdate = function(element, data) {
979
var self = $(element);
932
- var width = self.data('width') || NETDATA.chartDefaults.width;
933
- var height = self.data('height') || NETDATA.chartDefaults.height;
980
981
self.raphael(data, {
936
- width: width,
937
- height: height
982
+ width: self.data('calculated-width'),
983
+ height: self.data('calculated-height')
984
})
985
};
986
987
NETDATA.raphaelChartCreate = function(element, data) {
988
var self = $(element);
943
- var width = self.data('width') || NETDATA.chartDefaults.width;
944
- var height = self.data('height') || NETDATA.chartDefaults.height;
989
990
self.raphael(data, {
947
- width: width,
948
- height: height
991
+ width: self.data('calculated-width'),
992
+ height: self.data('calculated-height')
993
})
994
.data('created', true);
995
};
@@ -965,8 +1009,6 @@
1009
1010
NETDATA.googleChartUpdate = function(element, data) {
1011
var self = $(element);
968
- var width = self.data('width') || NETDATA.chartDefaults.width;
969
- var height = self.data('height') || NETDATA.chartDefaults.height;
1012
var gchart = self.data('google-instance');
1013
var options = self.data('google-options');
1014
@@ -980,16 +1022,15 @@
1022
1023
NETDATA.googleChartCreate = function(element, data) {
1024
var self = $(element);
983
- var width = self.data('width') || NETDATA.chartDefaults.width;
984
- var height = self.data('height') || NETDATA.chartDefaults.height;
1025
var chart = self.data('chart');
1026
1027
var datatable = new google.visualization.DataTable(data);
1028
var gchart;
1029
1030
var options = {
991
- width: width,
992
- height: height,
1031
+ // do not set width, height - the chart resizes itself
1032
+ //width: self.data('calculated-width'),
1033
+ //height: self.data('calculated-height'),
1034
lineWidth: 1,
1035
title: chart.title,
1036
fontSize: 11,
@@ -1046,10 +1087,13 @@
1087
isStacked: false
1088
};
1089
1090
+ var uuid = NETDATA.guid();
1091
+ self.html('<div id="' + uuid + '" style="width: 100%; height: 100%;"></div>');
1092
+
1093
switch(chart.chart_type) {
1094
case "area":
1095
options.vAxis.viewWindowMode = 'maximized';
1052
- gchart = new google.visualization.AreaChart(element);
1096
+ gchart = new google.visualization.AreaChart(document.getElementById(uuid));
1097
break;
1098
1099
case "stacked":
@@ -1058,21 +1102,22 @@
1102
options.vAxis.viewWindowMode = 'maximized';
1103
options.vAxis.minValue = null;
1104
options.vAxis.maxValue = null;
1061
- gchart = new google.visualization.AreaChart(element);
1105
+ gchart = new google.visualization.AreaChart(document.getElementById(uuid));
1106
break;
1107
1108
default:
1109
case "line":
1110
options.lineWidth = 2;
1067
- gchart = new google.visualization.LineChart(element);
1111
+ gchart = new google.visualization.LineChart(document.getElementById(uuid));
1112
break;
1113
}
1114
1115
gchart.draw(datatable, options);
1116
1117
self.data('google-instance', gchart)
1074
- .data('google-options', options)
1075
- .data('created', true);
1118
+ .data('google-options', options)
1119
+ .data('uuid', uuid)
1120
+ .data('created', true);
1121
};
1122
1123
// ----------------------------------------------------------------------------------------------------------------