added gauge.js and adapted dashboard to use it
Costa Tsaousis (ktsaou) committed
Jan 9, 2016 at 05:46 UTC
ae676be6beb76e5bc9c0d977057348a3c78cf3e2
8 files changed
+557
-61
LICENSE.md
+6
@@ -37,6 +37,12 @@ connectivity is not available.
37
[MIT License](https://github.com/rendro/easy-pie-chart/blob/master/LICENSE)
38
39
40
+- [Guage.js](http://bernii.github.io/gauge.js/)
41
+
42
+ Copyright, Bernard Kobos
43
+ [MIT License](http://bernii.github.io/gauge.js/)
44
+
45
+
46
- [jQuery](https://jquery.org/)
47
48
Copyright 2015, jQuery Foundation
src/web_client.c
+6
-5
@@ -1754,14 +1754,15 @@ void *web_client_main(void *ptr)
1754
break;
1755
}
1756
1757
- global_statistics_lock();
1758
- global_statistics.bytes_received += bytes;
1759
- global_statistics_unlock();
1760
-
1757
if(w->mode == WEB_CLIENT_MODE_NORMAL) {
1762
- debug(D_WEB_CLIENT, "%llu: Attempting to process received data.", w->id);
1758
+ debug(D_WEB_CLIENT, "%llu: Attempting to process received data (%ld bytes).", w->id, bytes);
1759
+ // info("%llu: Attempting to process received data (%ld bytes).", w->id, bytes);
1760
web_client_process(w);
1761
}
1762
+
1763
+ global_statistics_lock();
1764
+ global_statistics.bytes_received += bytes;
1765
+ global_statistics_unlock();
1766
}
1767
}
1768
web/Makefile.am
+1
@@ -40,6 +40,7 @@ dist_weblib_DATA = \
40
lib/bootstrap-toggle.min.js \
41
lib/c3.min.js \
42
lib/d3.min.js \
43
+ lib/gauge.min.js \
44
$(NULL)
45
46
webcssdir=$(webdir)/css
web/dashboard.css
+78
@@ -330,6 +330,7 @@ html {
330
display: inline-block;
331
position: absolute;
332
float: left;
333
+ left: 0;
334
width: 100%;
335
text-align: center;
336
color: #333333;
@@ -340,6 +341,7 @@ html {
341
display: inline-block;
342
position: absolute;
343
float: left;
344
+ left: 0;
345
width: 64%;
346
margin-left: 18%;
347
text-align: center;
@@ -351,9 +353,85 @@ html {
353
display: inline-block;
354
position: absolute;
355
float: left;
356
+ left: 0;
357
width: 60%;
358
margin-left: 20%;
359
text-align: center;
360
color: #999999;
361
font-weight: normal;
362
}
363
+
364
+
365
+.gaugeChart {
366
+ position: relative;
367
+ text-align: center;
368
+}
369
+
370
+.gaugeChart canvas {
371
+ position: absolute;
372
+ top: 0;
373
+ left: 0;
374
+ z-index: 0;
375
+}
376
+
377
+.gaugeChartLabel {
378
+ display: inline-block;
379
+ position: absolute;
380
+ float: left;
381
+ left: 0;
382
+ width: 100%;
383
+ text-align: center;
384
+ color: #FFFFFF;
385
+ font-weight: bold;
386
+ z-index: 1;
387
+}
388
+
389
+.gaugeChartTitle {
390
+ display: inline-block;
391
+ position: absolute;
392
+ float: left;
393
+ left: 0;
394
+ width: 100%;
395
+ text-align: center;
396
+ color: #999999;
397
+ font-weight: bold;
398
+}
399
+
400
+.gaugeChartUnits {
401
+ display: inline-block;
402
+ position: absolute;
403
+ float: left;
404
+ left: 0;
405
+ bottom: 0;
406
+ width: 100%;
407
+ text-align: left;
408
+ margin-left: 5%;
409
+ color: #999999;
410
+ font-weight: normal;
411
+}
412
+
413
+.gaugeChartMin {
414
+ display: inline-block;
415
+ position: absolute;
416
+ float: left;
417
+ left: 0;
418
+ bottom: 10%;
419
+ width: 92%;
420
+ margin-left: 8%;
421
+ text-align: left;
422
+ color: #999999;
423
+ font-weight: normal;
424
+}
425
+
426
+.gaugeChartMax {
427
+ display: inline-block;
428
+ position: absolute;
429
+ float: left;
430
+ left: 0;
431
+ bottom: 10%;
432
+ width: 95%;
433
+ margin-right: 5%;
434
+ text-align: right;
435
+ color: #999999;
436
+ font-weight: normal;
437
+}
web/dashboard.html
+84
@@ -422,6 +422,90 @@ Sparklines using dygraphs
422
</div>
423
</div>
424
425
+
426
+<hr>
427
+<h1>Gauge.js</h1>
428
+<br/>
429
+<div style="width: 33%; display: inline-block;">
430
+ <div style="display: inline-block; position: relative;">
431
+ <div data-netdata="system.processes"
432
+ data-chart-library="gauge"
433
+ data-width="250"
434
+ data-height="200"
435
+ data-after="-300"
436
+ data-points="300"
437
+ data-dt-element-name="time701"
438
+ ></div>
439
+ <br/>
440
+ <small>rendered in <span id="time701">X</span> ms</small>
441
+ </div>
442
+ <div style="display: inline-block; position: relative;">
443
+ <div data-netdata="system.processes"
444
+ data-chart-library="gauge"
445
+ data-width="125"
446
+ data-height="100"
447
+ data-after="-300"
448
+ data-points="150"
449
+ data-dt-element-name="time701a"
450
+ ></div>
451
+ <br/>
452
+ <small>rendered in <span id="time701a">X</span> ms</small>
453
+ </div>
454
+</div>
455
+<div style="width: 33%; display: inline-block;">
456
+ <div style="display: inline-block; position: relative;">
457
+ <div data-netdata="system.ipv4"
458
+ data-chart-library="gauge"
459
+ data-width="250"
460
+ data-height="200"
461
+ data-after="-300"
462
+ data-points="300"
463
+ data-dt-element-name="time702"
464
+ ></div>
465
+ <br/>
466
+ <small>rendered in <span id="time702">X</span> ms</small>
467
+ </div>
468
+ <div style="display: inline-block; position: relative;">
469
+ <div data-netdata="system.ipv4"
470
+ data-chart-library="gauge"
471
+ data-width="125"
472
+ data-height="100"
473
+ data-after="-300"
474
+ data-points="150"
475
+ data-dt-element-name="time702a"
476
+ ></div>
477
+ <br/>
478
+ <small>rendered in <span id="time702a">X</span> ms</small>
479
+ </div>
480
+</div>
481
+<div style="width: 33%; display: inline-block;">
482
+ <div style="display: inline-block; position: relative;">
483
+ <div data-netdata="system.cpu"
484
+ data-chart-library="gauge"
485
+ data-width="250"
486
+ data-height="200"
487
+ data-after="-300"
488
+ data-points="300"
489
+ data-dt-element-name="time703"
490
+ ></div>
491
+ <br/>
492
+ <small>rendered in <span id="time703">X</span> ms</small>
493
+ </div>
494
+ <div style="display: inline-block; position: relative;">
495
+ <div data-netdata="system.cpu"
496
+ data-chart-library="gauge"
497
+ data-width="125"
498
+ data-height="100"
499
+ data-after="-300"
500
+ data-points="150"
501
+ data-dt-element-name="time703a"
502
+ ></div>
503
+ <br/>
504
+ <small>rendered in <span id="time703a">X</span> ms</small>
505
+ </div>
506
+</div>
507
+
508
+
509
<hr>
510
<h1>Google Charts</h1>
511
NetData was originaly developed with Google Charts.
web/dashboard.js
+284
-37
@@ -6,6 +6,7 @@
6
// var netdataNoGoogleCharts = true; // do not use google
7
// var netdataNoMorris = true; // do not use morris
8
// var netdataNoEasyPieChart = true; // do not use easy pie chart
9
+// var netdataNoGauge = true; // do not use gauge.js
10
// var netdataNoD3 = true; // do not use D3
11
// var netdataNoC3 = true; // do not use C3
12
// var netdataNoBootstrap = true; // do not load bootstrap
@@ -76,6 +77,7 @@
77
NETDATA.peity_js = NETDATA.serverDefault + 'lib/jquery.peity.min.js';
78
NETDATA.sparkline_js = NETDATA.serverDefault + 'lib/jquery.sparkline.min.js';
79
NETDATA.easypiechart_js = NETDATA.serverDefault + 'lib/jquery.easypiechart.min.js';
80
+ NETDATA.gauge_js = NETDATA.serverDefault + 'lib/gauge.min.js';
81
NETDATA.dygraph_js = NETDATA.serverDefault + 'lib/dygraph-combined.js';
82
NETDATA.dygraph_smooth_js = NETDATA.serverDefault + 'lib/dygraph-smooth-plotter.js';
83
NETDATA.raphael_js = NETDATA.serverDefault + 'lib/raphael-min.js';
@@ -1356,6 +1358,7 @@
1358
1359
1360
var noDataToShow = function() {
1361
+ showMessageIcon('<i class="fa fa-warning"></i> empty');
1362
that.legendUpdateDOM();
1363
that.tm.last_autorefreshed = new Date().getTime();
1364
that.data_update_every = 30 * 1000;
@@ -4144,6 +4147,21 @@
4147
return true;
4148
};
4149
4150
+ // ----------------------------------------------------------------------------------------------------------------
4151
+
4152
+ NETDATA.percentFromValueMax = function(value, max) {
4153
+ if(value === null) value = 0;
4154
+ if(max < value) max = value;
4155
+
4156
+ var pcent = 0;
4157
+ if(max !== 0) {
4158
+ pcent = Math.round(value * 100 / max);
4159
+ if(pcent === 0 && value > 0) pcent = 1;
4160
+ }
4161
+
4162
+ return pcent;
4163
+ }
4164
+
4165
// ----------------------------------------------------------------------------------------------------------------
4166
// easy-pie-chart
4167
@@ -4200,20 +4218,6 @@
4218
if(slot < 0 || slot >= state.data.result.length)
4219
return NETDATA.easypiechartClearSelection(state);
4220
4203
- var value = state.data.result[slot];
4204
- if(value === null) value = 0;
4205
-
4206
- var max = (state.easyPieChartMax === null)?state.data.max:state.easyPieChartMax;
4207
- if(max < value) max = value;
4208
-
4209
- var pcent = 0;
4210
- if(max !== 0) {
4211
- pcent = Math.round(value * 100 / max);
4212
- if(pcent === 0 && value > 0) pcent = 1;
4213
- }
4214
-
4215
- // console.log('slot = ' + slot + ' value = ' + value + ' max = ' + max + ' pcent = ' + pcent);
4216
-
4221
if(typeof state.easyPieChartEvent === 'undefined') {
4222
state.easyPieChartEvent = {
4223
timer: null,
@@ -4222,6 +4226,10 @@
4226
};
4227
}
4228
4229
+ var value = state.data.result[slot];
4230
+ var max = (state.easyPieChartMax === null)?state.data.max:state.easyPieChartMax;
4231
+ var pcent = NETDATA.percentFromValueMax(value, max);
4232
+
4233
state.easyPieChartEvent.value = value;
4234
state.easyPieChartEvent.pcent = pcent;
4235
state.easyPieChartLabel.innerHTML = state.legendFormatValue(value);
@@ -4248,16 +4256,8 @@
4256
}
4257
else {
4258
value = data.result[0];
4251
- if(value === null) value = 0;
4252
-
4259
max = (state.easyPieChartMax === null)?data.max:state.easyPieChartMax;
4254
- if(max < value) max = value;
4255
-
4256
- pcent = 0;
4257
- if(max !== 0) {
4258
- pcent = Math.round(value * 100 / max);
4259
- if(pcent === 0 && value > 0) pcent = 1;
4260
- }
4260
+ pcent = NETDATA.percentFromValueMax(value, max);
4261
}
4262
4263
state.easyPieChartLabel.innerHTML = state.legendFormatValue(value);
@@ -4270,29 +4270,28 @@
4270
var chart = $(state.element_chart);
4271
4272
var value = data.result[0];
4273
- if(value === null) value = 0;
4274
-
4273
var max = self.data('easypiechart-max-value') || null;
4274
+ var adjust = self.data('easypiechart-adjust') || null;
4275
+
4276
if(max === null) {
4277
max = data.max;
4278
state.easyPieChartMax = null;
4279
}
4280
- else {
4280
+ else
4281
state.easyPieChartMax = max;
4282
- }
4283
- if(max < value) max = value;
4282
4285
- var pcent = 0;
4286
- if(max !== 0) {
4287
- pcent = Math.round(value * 100 / max);
4288
- if(pcent === 0 && value > 0) pcent = 1;
4289
- }
4283
+ var pcent = NETDATA.percentFromValueMax(value, max);
4284
4291
- // console.log('value = ' + value + ' max = ' + max + ' pcent = ' + pcent);
4285
chart.data('data-percent', pcent);
4286
4294
- var size = Math.min(state.chartWidth(), state.chartHeight());
4295
- if(size < 50) size = state.chartWidth();
4287
+ var size;
4288
+ switch(adjust) {
4289
+ case 'width': size = state.chartHeight(); break;
4290
+ case 'min': size = Math.min(state.chartWidth(), state.chartHeight()); break;
4291
+ case 'max': size = Math.max(state.chartWidth(), state.chartHeight()); break;
4292
+ case 'height':
4293
+ default: size = state.chartWidth(); break;
4294
+ }
4295
state.element.style.width = size + 'px';
4296
state.element.style.height = size + 'px';
4297
@@ -4329,7 +4328,7 @@
4328
4329
chart.easyPieChart({
4330
barColor: self.data('easypiechart-barcolor') || state.chartColors()[0], //'#ef1e25',
4332
- trackColor: self.data('easypiechart-trackcolor') || '#f2f2f2',
4331
+ trackColor: self.data('easypiechart-trackcolor') || '#f0f0f0',
4332
scaleColor: self.data('easypiechart-scalecolor') || '#dfe0e0',
4333
scaleLength: self.data('easypiechart-scalelength') || 5,
4334
lineCap: self.data('easypiechart-linecap') || 'round',
@@ -4354,6 +4353,237 @@
4353
return true;
4354
};
4355
4356
+ // ----------------------------------------------------------------------------------------------------------------
4357
+ // gauge.js
4358
+
4359
+ NETDATA.gaugeInitialize = function(callback) {
4360
+ if(typeof netdataNoGauge === 'undefined' || !netdataNoGauge) {
4361
+ $.ajax({
4362
+ url: NETDATA.gauge_js,
4363
+ cache: true,
4364
+ dataType: "script"
4365
+ })
4366
+ .done(function() {
4367
+ NETDATA.registerChartLibrary('gauge', NETDATA.gauge_js);
4368
+ })
4369
+ .fail(function() {
4370
+ NETDATA.error(100, NETDATA.gauge_js);
4371
+ })
4372
+ .always(function() {
4373
+ if(typeof callback === "function")
4374
+ callback();
4375
+ })
4376
+ }
4377
+ else {
4378
+ NETDATA.chartLibraries.gauge.enabled = false;
4379
+ if(typeof callback === "function")
4380
+ callback();
4381
+ }
4382
+ };
4383
+
4384
+ NETDATA.gaugeClearSelection = function(state) {
4385
+ if(typeof state.gaugeEvent !== 'undefined') {
4386
+ if(state.gaugeEvent.timer !== null)
4387
+ clearTimeout(state.gaugeEvent.timer);
4388
+
4389
+ state.gaugeEvent.timer = null;
4390
+ }
4391
+
4392
+ if(state.isAutoRefreshed() === true && state.data !== null) {
4393
+ NETDATA.gaugeChartUpdate(state, state.data);
4394
+ }
4395
+ else {
4396
+ state.gaugeChartLabel.innerHTML = state.legendFormatValue(null);
4397
+ state.gaugeChartMax.innerHTML = state.legendFormatValue(null);
4398
+ state.gauge_instance.animationSpeed = 1;
4399
+ state.gauge_instance.set(0);
4400
+ }
4401
+ state.gauge_instance.animationSpeed = 32;
4402
+
4403
+ return true;
4404
+ };
4405
+
4406
+ NETDATA.gaugeSetSelection = function(state, t) {
4407
+ if(t < state.data_after || t > state.data_before)
4408
+ return NETDATA.gaugeClearSelection(state);
4409
+
4410
+ var slot = Math.floor(state.data.result.length - 1 - (t - state.data_after) / state.data_update_every);
4411
+ if(slot < 0 || slot >= state.data.result.length)
4412
+ return NETDATA.gaugeClearSelection(state);
4413
+
4414
+ if(typeof state.gaugeEvent === 'undefined') {
4415
+ state.gaugeEvent = {
4416
+ timer: null,
4417
+ value: 0,
4418
+ max: 0,
4419
+ };
4420
+ }
4421
+
4422
+ var value = state.data.result[slot];
4423
+ var max = (state.gaugeMax === null)?state.data.max:state.gaugeMax;
4424
+ if(value > max) max = value;
4425
+
4426
+ state.gaugeEvent.value = value;
4427
+ state.gaugeEvent.max = max;
4428
+ state.gaugeChartLabel.innerHTML = state.legendFormatValue(value);
4429
+ state.gaugeChartMax.innerHTML = state.legendFormatValue(max);
4430
+
4431
+ if(state.gaugeEvent.timer === null) {
4432
+ state.gauge_instance.animationSpeed = 1;
4433
+
4434
+ state.gaugeEvent.timer = setTimeout(function() {
4435
+ state.gaugeEvent.timer = null;
4436
+ state.gauge_instance.maxValue = state.gaugeEvent.max;
4437
+ state.gauge_instance.set(state.gaugeEvent.value);
4438
+ }, 50);
4439
+ }
4440
+
4441
+ return true;
4442
+ };
4443
+
4444
+ NETDATA.gaugeChartUpdate = function(state, data) {
4445
+ var value, max;
4446
+
4447
+ if(NETDATA.globalPanAndZoom.isActive() === true || state.isAutoRefreshed() === false) {
4448
+ value = 0;
4449
+ state.gaugeChartLabel.innerHTML = state.legendFormatValue(null);
4450
+ state.gaugeChartMax.innerHTML = state.legendFormatValue(null);
4451
+ state.gauge_instance.set(value);
4452
+ }
4453
+ else {
4454
+ value = data.result[0];
4455
+ max = (state.gaugeMax === null)?data.max:state.gaugeMax;
4456
+ if(value > max) max = value;
4457
+ state.gaugeChartLabel.innerHTML = state.legendFormatValue(value);
4458
+ state.gaugeChartMax.innerHTML = state.legendFormatValue(max);
4459
+ state.gauge_instance.maxValue = max;
4460
+ state.gauge_instance.set(value);
4461
+ }
4462
+
4463
+ return true;
4464
+ };
4465
+
4466
+ NETDATA.gaugeChartCreate = function(state, data) {
4467
+ var self = $(state.element);
4468
+ var chart = $(state.element_chart);
4469
+
4470
+ var value = data.result[0];
4471
+ var max = self.data('gauge-max-value') || null;
4472
+ var adjust = self.data('gauge-adjust') || null;
4473
+
4474
+ if(max === null) {
4475
+ max = data.max;
4476
+ state.gaugeMax = null;
4477
+ }
4478
+ else
4479
+ state.gaugeMax = max;
4480
+
4481
+ var width = state.chartWidth(), height = state.chartHeight(), ratio = 1.5;
4482
+ switch(adjust) {
4483
+ case 'width': width = height * ratio; break;
4484
+ case 'height':
4485
+ default: height = width / ratio; break;
4486
+ }
4487
+ state.element.style.width = width.toString() + 'px';
4488
+ state.element.style.height = height.toString() + 'px';
4489
+
4490
+ var lum_d = 0.05;
4491
+
4492
+ var options = {
4493
+ lines: 12, // The number of lines to draw
4494
+ angle: 0.15, // The length of each line
4495
+ lineWidth: 0.44, // 0.44 The line thickness
4496
+ pointer: {
4497
+ length: 0.8, // 0.9 The radius of the inner circle
4498
+ strokeWidth: 0.035, // The rotation offset
4499
+ color: '#C0C0C0' // Fill color
4500
+ },
4501
+ colorStart: state.chartColors()[0], // Colors
4502
+ colorStop: state.chartColors()[0], // just experiment with them
4503
+ strokeColor: '#F0F0F0', // to see which ones work best for you
4504
+ generateGradient: false,
4505
+ percentColors: [
4506
+ [0.0, NETDATA.colorLuminance(state.chartColors()[0], (lum_d * 10) - (lum_d * 0))],
4507
+ [0.1, NETDATA.colorLuminance(state.chartColors()[0], (lum_d * 10) - (lum_d * 1))],
4508
+ [0.2, NETDATA.colorLuminance(state.chartColors()[0], (lum_d * 10) - (lum_d * 2))],
4509
+ [0.3, NETDATA.colorLuminance(state.chartColors()[0], (lum_d * 10) - (lum_d * 3))],
4510
+ [0.4, NETDATA.colorLuminance(state.chartColors()[0], (lum_d * 10) - (lum_d * 4))],
4511
+ [0.5, NETDATA.colorLuminance(state.chartColors()[0], (lum_d * 10) - (lum_d * 5))],
4512
+ [0.6, NETDATA.colorLuminance(state.chartColors()[0], (lum_d * 10) - (lum_d * 6))],
4513
+ [0.7, NETDATA.colorLuminance(state.chartColors()[0], (lum_d * 10) - (lum_d * 7))],
4514
+ [0.8, NETDATA.colorLuminance(state.chartColors()[0], (lum_d * 10) - (lum_d * 8))],
4515
+ [0.9, NETDATA.colorLuminance(state.chartColors()[0], (lum_d * 10) - (lum_d * 9))],
4516
+ [1.0, state.chartColors()[0]]]
4517
+ };
4518
+
4519
+ state.gauge_canvas = document.createElement('canvas');
4520
+ state.gauge_canvas.id = 'gauge-' + state.uuid + '-canvas';
4521
+ state.gauge_canvas.className = 'gaugeChart';
4522
+ state.gauge_canvas.width = width;
4523
+ state.gauge_canvas.height = height;
4524
+ state.element_chart.appendChild(state.gauge_canvas);
4525
+
4526
+ var valuefontsize = Math.floor(height / 6);
4527
+ var valuetop = Math.round((height - valuefontsize - (height / 6)) / 2);
4528
+ state.gaugeChartLabel = document.createElement('span');
4529
+ state.gaugeChartLabel.className = 'gaugeChartLabel';
4530
+ state.gaugeChartLabel.innerHTML = state.legendFormatValue(value);
4531
+ state.gaugeChartLabel.style.fontSize = valuefontsize + 'px';
4532
+ state.gaugeChartLabel.style.top = valuetop.toString() + 'px';
4533
+ state.element_chart.appendChild(state.gaugeChartLabel);
4534
+
4535
+ var titlefontsize = Math.round(valuefontsize / 2);
4536
+ var titletop = 0;
4537
+ state.gaugeChartTitle = document.createElement('span');
4538
+ state.gaugeChartTitle.className = 'gaugeChartTitle';
4539
+ state.gaugeChartTitle.innerHTML = state.title;
4540
+ state.gaugeChartTitle.style.fontSize = titlefontsize + 'px';
4541
+ state.gaugeChartTitle.style.lineHeight = titlefontsize + 'px';
4542
+ state.gaugeChartTitle.style.top = titletop.toString() + 'px';
4543
+ state.element_chart.appendChild(state.gaugeChartTitle);
4544
+
4545
+ var unitfontsize = Math.round(titlefontsize * 0.9);
4546
+ state.gaugeChartUnits = document.createElement('span');
4547
+ state.gaugeChartUnits.className = 'gaugeChartUnits';
4548
+ state.gaugeChartUnits.innerHTML = state.units;
4549
+ state.gaugeChartUnits.style.fontSize = unitfontsize + 'px';
4550
+ state.element_chart.appendChild(state.gaugeChartUnits);
4551
+
4552
+ state.gaugeChartMin = document.createElement('span');
4553
+ state.gaugeChartMin.className = 'gaugeChartMin';
4554
+ state.gaugeChartMin.innerHTML = 0;
4555
+ state.gaugeChartMin.style.fontSize = Math.round(valuefontsize * 0.75).toString() + 'px';
4556
+ state.element_chart.appendChild(state.gaugeChartMin);
4557
+
4558
+ state.gaugeChartMax = document.createElement('span');
4559
+ state.gaugeChartMax.className = 'gaugeChartMax';
4560
+ state.gaugeChartMax.innerHTML = state.legendFormatValue(max);
4561
+ state.gaugeChartMax.style.fontSize = Math.round(valuefontsize * 0.75).toString() + 'px';
4562
+ state.element_chart.appendChild(state.gaugeChartMax);
4563
+
4564
+ // when we just re-create the chart
4565
+ // do not animate the first update
4566
+ var animate = true;
4567
+ if(typeof state.gauge_instance !== 'undefined')
4568
+ animate = false;
4569
+
4570
+ state.gauge_instance = new Gauge(state.gauge_canvas).setOptions(options); // create sexy gauge!
4571
+
4572
+ // set max gauge value
4573
+ state.gauge_instance.maxValue = max;
4574
+
4575
+ // set animation speed (32 is default value)
4576
+ if(animate === false) state.gauge_instance.animationSpeed = 32;
4577
+ else state.gauge_instance.animationSpeed = 1;
4578
+
4579
+ // set actual value
4580
+ state.gauge_instance.set(value);
4581
+
4582
+ // restore animation
4583
+ state.gauge_instance.animationSpeed = 32;
4584
+ return true;
4585
+ };
4586
+
4587
// ----------------------------------------------------------------------------------------------------------------
4588
// Charts Libraries Registration
4589
@@ -4534,6 +4764,23 @@
4764
max_updates_to_recreate: function(state) { return 5000; },
4765
track_colors: function(state) { return false; },
4766
pixels_per_point: function(state) { return 3; }
4767
+ },
4768
+ "gauge": {
4769
+ initialize: NETDATA.gaugeInitialize,
4770
+ create: NETDATA.gaugeChartCreate,
4771
+ update: NETDATA.gaugeChartUpdate,
4772
+ resize: null,
4773
+ setSelection: NETDATA.gaugeSetSelection,
4774
+ clearSelection: NETDATA.gaugeClearSelection,
4775
+ initialized: false,
4776
+ enabled: true,
4777
+ format: function(state) { return 'array'; },
4778
+ options: function(state) { return 'absolute'; },
4779
+ legend: function(state) { return null; },
4780
+ autoresize: function(state) { return false; },
4781
+ max_updates_to_recreate: function(state) { return 5000; },
4782
+ track_colors: function(state) { return false; },
4783
+ pixels_per_point: function(state) { return 3; }
4784
}
4785
};
4786
web/index.html
+97
-19
@@ -253,7 +253,7 @@
253
<!-- <script> netdataServer = "http://box:19999"; </script> -->
254
255
<!-- load the dashboard manager - it will do the rest -->
256
- <script type="text/javascript" src="dashboard.js?v15"></script>
256
+ <script type="text/javascript" src="dashboard.js?v16"></script>
257
</head>
258
259
<body data-spy="scroll" data-target="#sidebar">
@@ -342,6 +342,9 @@
342
<i class="fa fa-circle"></i> <a href="https://rendro.github.io/easy-pie-chart/" target="_blank">Easy Pie Chart</a> web chart library,
343
<i class="fa fa-copyright"></i> Copyright 2013, Robert Fleischmann, <a href="https://github.com/rendro/easy-pie-chart/blob/master/LICENSE" target="_blank">MIT License</a>
344
345
+ <i class="fa fa-circle"></i> <a href="http://bernii.github.io/gauge.js/" target="_blank">Gauge.js</a> web chart library,
346
+ <i class="fa fa-copyright"></i> Copyright, Bernard Kobos, <a href="http://bernii.github.io/gauge.js/" target="_blank">MIT License</a>
347
+
348
<i class="fa fa-circle"></i> <a href="https://jquery.org/" target="_blank">jQuery</a>,
349
<i class="fa fa-copyright"></i> Copyright 2015, jQuery Foundation, <a href="https://jquery.org/license/" target="_blank">MIT License</a>
350
@@ -923,31 +926,33 @@ function prepareScreen(data) {
926
$.each(disks, function(j, c) {
927
sidebar += '<li class><a href="#' + name2id(c.name) + '">' + c.name + '</a></li>';
928
html += '<div class="netdata-group-container" id="disk_' + name2id(c.name) + '" style="display: inline-block; width: ' + pcent_width.toString() + '%"><h2 id="' + name2id(c.name) + '" class="netdata-chart-alignment" role="heading">' + c.name + '</h2>';
926
- var head = '<div class="netdata-chart-alignment">';
929
+ var head = '<div style="width: 100%; text-align: center;">';
930
var all = '';
931
$.each(c.values, function(x, f) {
932
var c = null;
933
var h = options.chartsHeight / 2;
934
switch(f.type) {
935
case 'disk' : h = options.chartsHeight;
933
- head += '<div style="margin-right: 10px;" data-netdata="' + f.id + '"'
936
+ head += '<div data-netdata="' + f.id + '"'
937
+ ' data-dimensions="reads"'
935
- + ' data-chart-library="easypiechart"'
938
+ + ' data-chart-library="gauge"'
939
+ + ' data-gauge-adjust="width"'
940
+ ' data-title="Read"'
937
- + ' data-width="120px"'
938
- + ' data-height="120px"'
941
+ + ' data-width="100px"'
942
+ + ' data-height="100px"'
943
+ ' data-before="0"'
944
+ ' data-after="-' + duration.toString() + '"'
945
+ ' data-points="' + duration.toString() + '"'
946
+ ' data-colors="' + NETDATA.colors[0] + '"'
947
+ ' role="application"></div>';
948
945
- head += '<div style="margin-right: 10px;" data-netdata="' + f.id + '"'
949
+ head += '<div data-netdata="' + f.id + '"'
950
+ ' data-dimensions="writes"'
947
- + ' data-chart-library="easypiechart"'
951
+ + ' data-chart-library="gauge"'
952
+ + ' data-gauge-adjust="width"'
953
+ ' data-title="Write"'
949
- + ' data-width="120px"'
950
- + ' data-height="120px"'
954
+ + ' data-width="100px"'
955
+ + ' data-height="100px"'
956
+ ' data-before="0"'
957
+ ' data-after="-' + duration.toString() + '"'
958
+ ' data-points="' + duration.toString() + '"'
@@ -956,12 +961,13 @@ function prepareScreen(data) {
961
break;
962
case 'disk_backlog': c = '#DD4477'; break;
963
case 'disk_util' : c = '#109618';
959
- head += '<div style="margin-right: 10px;" data-netdata="' + f.id + '"'
960
- + ' data-chart-library="easypiechart"'
964
+ head += '<div data-netdata="' + f.id + '"'
965
+ + ' data-chart-library="gauge"'
966
+ ' data-title="Utilization"'
962
- + ' data-easypiechart-max-value="100"'
963
- + ' data-width="120px"'
964
- + ' data-height="120px"'
967
+ + ' data-gauge-max-value="100"'
968
+ + ' data-gauge-adjust="width"'
969
+ + ' data-width="100px"'
970
+ + ' data-height="100px"'
971
+ ' data-before="0"'
972
+ ' data-after="-' + duration.toString() + '"'
973
+ ' data-points="' + duration.toString() + '"'
@@ -1055,12 +1061,12 @@ function prepareScreen(data) {
1061
}
1062
1063
if(typeof charts['system.cpu'] !== 'undefined')
1058
- head += '<div style="margin-right: 10px;" data-netdata="system.cpu"'
1059
- + ' data-chart-library="easypiechart"'
1064
+ head += '<div data-netdata="system.cpu"'
1065
+ + ' data-chart-library="gauge"'
1066
+ ' data-title="CPU"'
1067
+ ' data-units="%"'
1062
- + ' data-easypiechart-max-value="100"'
1063
- + ' data-width="11%"'
1068
+ + ' data-gauge-max-value="100"'
1069
+ + ' data-width="18%"'
1070
+ ' data-height="49px"'
1071
+ ' data-after="-' + duration.toString() + '"'
1072
+ ' data-points="' + duration.toString() + '"'
@@ -1178,6 +1184,78 @@ function prepareScreen(data) {
1184
});
1185
html += head + all;
1186
}
1187
+ else if(t.name === 'netdata') {
1188
+ var head = '<div style="width: 100%; text-align: center;">';
1189
+ var all = '';
1190
+
1191
+ $.each(t.charts, function(x, f) {
1192
+ switch(f.id) {
1193
+ case 'netdata.net' :
1194
+ head += '<div data-netdata="' + f.id + '"'
1195
+ + ' data-dimensions="in"'
1196
+ + ' data-chart-library="gauge"'
1197
+ + ' data-title="Bytes In"'
1198
+ + ' data-gauge-adjust="width"'
1199
+ + ' data-width="100px"'
1200
+ + ' data-height="100px"'
1201
+ + ' data-before="0"'
1202
+ + ' data-after="-' + duration.toString() + '"'
1203
+ + ' data-points="' + duration.toString() + '"'
1204
+ + ' role="application"></div>';
1205
+
1206
+ head += '<div data-netdata="' + f.id + '"'
1207
+ + ' data-dimensions="out"'
1208
+ + ' data-chart-library="gauge"'
1209
+ + ' data-title="Bytes Out"'
1210
+ + ' data-gauge-adjust="width"'
1211
+ + ' data-width="100px"'
1212
+ + ' data-height="100px"'
1213
+ + ' data-before="0"'
1214
+ + ' data-after="-' + duration.toString() + '"'
1215
+ + ' data-points="' + duration.toString() + '"'
1216
+ + ' role="application"></div>';
1217
+ break;
1218
+
1219
+ case 'netdata.requests' : c = NETDATA.colors[2];
1220
+ head += '<div data-netdata="' + f.id + '"'
1221
+ + ' data-chart-library="gauge"'
1222
+ + ' data-title="Requests / second"'
1223
+ + ' data-gauge-adjust="width"'
1224
+ + ' data-width="100px"'
1225
+ + ' data-height="100px"'
1226
+ + ' data-before="0"'
1227
+ + ' data-after="-' + duration.toString() + '"'
1228
+ + ' data-points="' + duration.toString() + '"'
1229
+ + ' data-colors="' + c + '"'
1230
+ + ' role="application"></div>';
1231
+ break;
1232
+
1233
+ case 'netdata.clients' : c = NETDATA.colors[3];
1234
+ head += '<div data-netdata="' + f.id + '"'
1235
+ + ' data-chart-library="gauge"'
1236
+ + ' data-title="Connections"'
1237
+ + ' data-gauge-adjust="width"'
1238
+ + ' data-width="100px"'
1239
+ + ' data-height="100px"'
1240
+ + ' data-before="0"'
1241
+ + ' data-after="-' + duration.toString() + '"'
1242
+ + ' data-points="' + duration.toString() + '"'
1243
+ + ' data-colors="' + c + '"'
1244
+ + ' role="application"></div>';
1245
+ break;
1246
+ }
1247
+
1248
+ all += getMessage(f.id) + '<div data-netdata="' + f.id + '"'
1249
+ + ' data-width="' + pcent_width.toString() + '%"'
1250
+ + ' data-height="' + options.chartsHeight.toString() + 'px"'
1251
+ + ' data-before="0"'
1252
+ + ' data-after="-' + duration.toString() + '"'
1253
+ + ' data-id="' + name2id(options.hostname + '/' + f.id) + '"'
1254
+ + ' role="application"></div>';
1255
+ });
1256
+ head += '</div>';
1257
+ html += head + all;
1258
+ }
1259
else {
1260
$.each(t.charts, function(x, f) {
1261
html += getMessage(f.id) + '<div data-netdata="' + f.id + '"'
web/lib/gauge.min.js
new
+1
@@ -0,0 +1 @@
1
+(function(){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q={}.hasOwnProperty,r=function(a,b){function c(){this.constructor=a}for(var d in b)q.call(b,d)&&(a[d]=b[d]);return c.prototype=b.prototype,a.prototype=new c,a.__super__=b.prototype,a};!function(){var a,b,c,d,e,f,g;for(g=["ms","moz","webkit","o"],c=0,e=g.length;e>c&&(f=g[c],!window.requestAnimationFrame);c++)window.requestAnimationFrame=window[f+"RequestAnimationFrame"],window.cancelAnimationFrame=window[f+"CancelAnimationFrame"]||window[f+"CancelRequestAnimationFrame"];return a=null,d=0,b={},requestAnimationFrame?window.cancelAnimationFrame?void 0:(a=window.requestAnimationFrame,window.requestAnimationFrame=function(c,e){var f;return f=++d,a(function(){return b[f]?void 0:c()},e),f},window.cancelAnimationFrame=function(a){return b[a]=!0}):(window.requestAnimationFrame=function(a,b){var c,d,e,f;return c=(new Date).getTime(),f=Math.max(0,16-(c-e)),d=window.setTimeout(function(){return a(c+f)},f),e=c+f,d},window.cancelAnimationFrame=function(a){return clearTimeout(a)})}(),String.prototype.hashCode=function(){var a,b,c,d,e;if(b=0,0===this.length)return b;for(c=d=0,e=this.length;e>=0?e>d:d>e;c=e>=0?++d:--d)a=this.charCodeAt(c),b=(b<<5)-b+a,b&=b;return b},o=function(a){var b,c;for(b=Math.floor(a/3600),c=Math.floor((a-3600*b)/60),a-=3600*b+60*c,a+="",c+="";c.length<2;)c="0"+c;for(;a.length<2;)a="0"+a;return b=b?b+":":"",b+c+":"+a},m=function(a){return k(a.toFixed(0))},p=function(a,b){var c,d;for(c in b)q.call(b,c)&&(d=b[c],a[c]=d);return a},n=function(a,b){var c,d,e;d={};for(c in a)q.call(a,c)&&(e=a[c],d[c]=e);for(c in b)q.call(b,c)&&(e=b[c],d[c]=e);return d},k=function(a){var b,c,d,e;for(a+="",c=a.split("."),d=c[0],e="",c.length>1&&(e="."+c[1]),b=/(\d+)(\d{3})/;b.test(d);)d=d.replace(b,"$1,$2");return d+e},l=function(a){return"#"===a.charAt(0)?a.substring(1,7):a},j=function(){function a(a,b){null==a&&(a=!0),this.clear=null!=b?b:!0,a&&AnimationUpdater.add(this)}return a.prototype.animationSpeed=32,a.prototype.update=function(a){var b;return null==a&&(a=!1),a||this.displayedValue!==this.value?(this.ctx&&this.clear&&this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),b=this.value-this.displayedValue,Math.abs(b/this.animationSpeed)<=.001?this.displayedValue=this.value:this.displayedValue=this.displayedValue+b/this.animationSpeed,this.render(),!0):!1},a}(),e=function(a){function b(){return b.__super__.constructor.apply(this,arguments)}return r(b,a),b.prototype.displayScale=1,b.prototype.setTextField=function(a){return this.textField=a instanceof i?a:new i(a)},b.prototype.setMinValue=function(a,b){var c,d,e,f,g;if(this.minValue=a,null==b&&(b=!0),b){for(this.displayedValue=this.minValue,f=this.gp||[],g=[],d=0,e=f.length;e>d;d++)c=f[d],g.push(c.displayedValue=this.minValue);return g}},b.prototype.setOptions=function(a){return null==a&&(a=null),this.options=n(this.options,a),this.textField&&(this.textField.el.style.fontSize=a.fontSize+"px"),this.options.angle>.5&&(this.gauge.options.angle=.5),this.configDisplayScale(),this},b.prototype.configDisplayScale=function(){var a,b,c,d,e;return d=this.displayScale,this.options.highDpiSupport===!1?delete this.displayScale:(b=window.devicePixelRatio||1,a=this.ctx.webkitBackingStorePixelRatio||this.ctx.mozBackingStorePixelRatio||this.ctx.msBackingStorePixelRatio||this.ctx.oBackingStorePixelRatio||this.ctx.backingStorePixelRatio||1,this.displayScale=b/a),this.displayScale!==d&&(e=this.canvas.G__width||this.canvas.width,c=this.canvas.G__height||this.canvas.height,this.canvas.width=e*this.displayScale,this.canvas.height=c*this.displayScale,this.canvas.style.width=e+"px",this.canvas.style.height=c+"px",this.canvas.G__width=e,this.canvas.G__height=c),this},b}(j),i=function(){function a(a){this.el=a}return a.prototype.render=function(a){return this.el.innerHTML=m(a.displayedValue)},a}(),a=function(a){function b(a,b){this.elem=a,this.text=null!=b?b:!1,this.value=1*this.elem.innerHTML,this.text&&(this.value=0)}return r(b,a),b.prototype.displayedValue=0,b.prototype.value=0,b.prototype.setVal=function(a){return this.value=1*a},b.prototype.render=function(){var a;return a=this.text?o(this.displayedValue.toFixed(0)):k(m(this.displayedValue)),this.elem.innerHTML=a},b}(j),b={create:function(b){var c,d,e,f;for(f=[],d=0,e=b.length;e>d;d++)c=b[d],f.push(new a(c));return f}},h=function(a){function b(a){this.gauge=a,this.ctx=this.gauge.ctx,this.canvas=this.gauge.canvas,b.__super__.constructor.call(this,!1,!1),this.setOptions()}return r(b,a),b.prototype.displayedValue=0,b.prototype.value=0,b.prototype.options={strokeWidth:.035,length:.1,color:"#000000"},b.prototype.setOptions=function(a){return null==a&&(a=null),p(this.options,a),this.length=this.canvas.height*this.options.length,this.strokeWidth=this.canvas.height*this.options.strokeWidth,this.maxValue=this.gauge.maxValue,this.minValue=this.gauge.minValue,this.animationSpeed=this.gauge.animationSpeed,this.options.angle=this.gauge.options.angle},b.prototype.render=function(){var a,b,c,d,e,f,g,h,i;return a=this.gauge.getAngle.call(this,this.displayedValue),b=this.canvas.width/2,c=.9*this.canvas.height,h=Math.round(b+this.length*Math.cos(a)),i=Math.round(c+this.length*Math.sin(a)),f=Math.round(b+this.strokeWidth*Math.cos(a-Math.PI/2)),g=Math.round(c+this.strokeWidth*Math.sin(a-Math.PI/2)),d=Math.round(b+this.strokeWidth*Math.cos(a+Math.PI/2)),e=Math.round(c+this.strokeWidth*Math.sin(a+Math.PI/2)),this.ctx.fillStyle=this.options.color,this.ctx.beginPath(),this.ctx.arc(b,c,this.strokeWidth,0,2*Math.PI,!0),this.ctx.fill(),this.ctx.beginPath(),this.ctx.moveTo(f,g),this.ctx.lineTo(h,i),this.ctx.lineTo(d,e),this.ctx.fill()},b}(j),c=function(){function a(a){this.elem=a}return a.prototype.updateValues=function(a){return this.value=a[0],this.maxValue=a[1],this.avgValue=a[2],this.render()},a.prototype.render=function(){var a,b;return this.textField&&this.textField.text(m(this.value)),0===this.maxValue&&(this.maxValue=2*this.avgValue),b=this.value/this.maxValue*100,a=this.avgValue/this.maxValue*100,$(".bar-value",this.elem).css({width:b+"%"}),$(".typical-value",this.elem).css({width:a+"%"})},a}(),g=function(a){function b(a){this.canvas=a,b.__super__.constructor.call(this),this.percentColors=null,"undefined"!=typeof G_vmlCanvasManager&&(this.canvas=window.G_vmlCanvasManager.initElement(this.canvas)),this.ctx=this.canvas.getContext("2d"),this.gp=[new h(this)],this.setOptions(),this.render()}return r(b,a),b.prototype.elem=null,b.prototype.value=[20],b.prototype.maxValue=80,b.prototype.minValue=0,b.prototype.displayedAngle=0,b.prototype.displayedValue=0,b.prototype.lineWidth=40,b.prototype.paddingBottom=.1,b.prototype.percentColors=null,b.prototype.options={colorStart:"#6fadcf",colorStop:void 0,gradientType:0,strokeColor:"#e0e0e0",pointer:{length:.8,strokeWidth:.035},angle:.15,lineWidth:.44,fontSize:40,limitMax:!1},b.prototype.setOptions=function(a){var c,d,e,f;for(null==a&&(a=null),b.__super__.setOptions.call(this,a),this.configPercentColors(),this.lineWidth=this.canvas.height*(1-this.paddingBottom)*this.options.lineWidth,this.radius=this.canvas.height*(1-this.paddingBottom)-this.lineWidth,this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),this.render(),f=this.gp,d=0,e=f.length;e>d;d++)c=f[d],c.setOptions(this.options.pointer),c.render();return this},b.prototype.configPercentColors=function(){var a,b,c,d,e,f,g;if(this.percentColors=null,void 0!==this.options.percentColors){for(this.percentColors=new Array,f=[],c=d=0,e=this.options.percentColors.length-1;e>=0?e>=d:d>=e;c=e>=0?++d:--d)g=parseInt(l(this.options.percentColors[c][1]).substring(0,2),16),b=parseInt(l(this.options.percentColors[c][1]).substring(2,4),16),a=parseInt(l(this.options.percentColors[c][1]).substring(4,6),16),f.push(this.percentColors[c]={pct:this.options.percentColors[c][0],color:{r:g,g:b,b:a}});return f}},b.prototype.set=function(a){var b,c,d,e,f,g,i;if(a instanceof Array||(a=[a]),a.length>this.gp.length)for(b=c=0,g=a.length-this.gp.length;g>=0?g>c:c>g;b=g>=0?++c:--c)this.gp.push(new h(this));for(b=0,f=!1,d=0,e=a.length;e>d;d++)i=a[d],i>this.maxValue&&(this.maxValue=1.1*this.value,f=!0),this.gp[b].value=i,this.gp[b++].setOptions({maxValue:this.maxValue,angle:this.options.angle});return this.value=a[a.length-1],f&&this.options.limitMax?void 0:AnimationUpdater.run()},b.prototype.getAngle=function(a){return(1+this.options.angle)*Math.PI+(a-this.minValue)/(this.maxValue-this.minValue)*(1-2*this.options.angle)*Math.PI},b.prototype.getColorForPercentage=function(a,b){var c,d,e,f,g,h,i;if(0===a)c=this.percentColors[0].color;else for(c=this.percentColors[this.percentColors.length-1].color,e=f=0,h=this.percentColors.length-1;h>=0?h>=f:f>=h;e=h>=0?++f:--f)if(a<=this.percentColors[e].pct){b===!0?(i=this.percentColors[e-1],d=this.percentColors[e],g=(a-i.pct)/(d.pct-i.pct),c={r:Math.floor(i.color.r*(1-g)+d.color.r*g),g:Math.floor(i.color.g*(1-g)+d.color.g*g),b:Math.floor(i.color.b*(1-g)+d.color.b*g)}):c=this.percentColors[e].color;break}return"rgb("+[c.r,c.g,c.b].join(",")+")"},b.prototype.getColorForValue=function(a,b){var c;return c=(a-this.minValue)/(this.maxValue-this.minValue),this.getColorForPercentage(c,b)},b.prototype.render=function(){var a,b,c,d,e,f,g,h,i;for(i=this.canvas.width/2,d=this.canvas.height*(1-this.paddingBottom),a=this.getAngle(this.displayedValue),this.textField&&this.textField.render(this),this.ctx.lineCap="butt",void 0!==this.options.customFillStyle?b=this.options.customFillStyle(this):null!==this.percentColors?b=this.getColorForValue(this.displayedValue,!0):void 0!==this.options.colorStop?(b=0===this.options.gradientType?this.ctx.createRadialGradient(i,d,9,i,d,70):this.ctx.createLinearGradient(0,0,i,0),b.addColorStop(0,this.options.colorStart),b.addColorStop(1,this.options.colorStop)):b=this.options.colorStart,this.ctx.strokeStyle=b,this.ctx.beginPath(),this.ctx.arc(i,d,this.radius,(1+this.options.angle)*Math.PI,a,!1),this.ctx.lineWidth=this.lineWidth,this.ctx.stroke(),this.ctx.strokeStyle=this.options.strokeColor,this.ctx.beginPath(),this.ctx.arc(i,d,this.radius,a,(2-this.options.angle)*Math.PI,!1),this.ctx.stroke(),g=this.gp,h=[],e=0,f=g.length;f>e;e++)c=g[e],h.push(c.update(!0));return h},b}(e),d=function(a){function b(a){this.canvas=a,b.__super__.constructor.call(this),"undefined"!=typeof G_vmlCanvasManager&&(this.canvas=window.G_vmlCanvasManager.initElement(this.canvas)),this.ctx=this.canvas.getContext("2d"),this.setOptions(),this.render()}return r(b,a),b.prototype.lineWidth=15,b.prototype.displayedValue=0,b.prototype.value=33,b.prototype.maxValue=80,b.prototype.minValue=0,b.prototype.options={lineWidth:.1,colorStart:"#6f6ea0",colorStop:"#c0c0db",strokeColor:"#eeeeee",shadowColor:"#d5d5d5",angle:.35},b.prototype.getAngle=function(a){return(1-this.options.angle)*Math.PI+(a-this.minValue)/(this.maxValue-this.minValue)*(2+this.options.angle-(1-this.options.angle))*Math.PI},b.prototype.setOptions=function(a){return null==a&&(a=null),b.__super__.setOptions.call(this,a),this.lineWidth=this.canvas.height*this.options.lineWidth,this.radius=this.canvas.height/2-this.lineWidth/2,this},b.prototype.set=function(a){return this.value=a,this.value>this.maxValue&&(this.maxValue=1.1*this.value),AnimationUpdater.run()},b.prototype.render=function(){var a,b,c,d,e,f;return a=this.getAngle(this.displayedValue),f=this.canvas.width/2,c=this.canvas.height/2,this.textField&&this.textField.render(this),b=this.ctx.createRadialGradient(f,c,39,f,c,70),b.addColorStop(0,this.options.colorStart),b.addColorStop(1,this.options.colorStop),d=this.radius-this.lineWidth/2,e=this.radius+this.lineWidth/2,this.ctx.strokeStyle=this.options.strokeColor,this.ctx.beginPath(),this.ctx.arc(f,c,this.radius,(1-this.options.angle)*Math.PI,(2+this.options.angle)*Math.PI,!1),this.ctx.lineWidth=this.lineWidth,this.ctx.lineCap="round",this.ctx.stroke(),this.ctx.strokeStyle=b,this.ctx.beginPath(),this.ctx.arc(f,c,this.radius,(1-this.options.angle)*Math.PI,a,!1),this.ctx.stroke()},b}(e),f=function(a){function b(){return b.__super__.constructor.apply(this,arguments)}return r(b,a),b.prototype.strokeGradient=function(a,b,c,d){var e;return e=this.ctx.createRadialGradient(a,b,c,a,b,d),e.addColorStop(0,this.options.shadowColor),e.addColorStop(.12,this.options._orgStrokeColor),e.addColorStop(.88,this.options._orgStrokeColor),e.addColorStop(1,this.options.shadowColor),e},b.prototype.setOptions=function(a){var c,d,e,f;return null==a&&(a=null),b.__super__.setOptions.call(this,a),f=this.canvas.width/2,c=this.canvas.height/2,d=this.radius-this.lineWidth/2,e=this.radius+this.lineWidth/2,this.options._orgStrokeColor=this.options.strokeColor,this.options.strokeColor=this.strokeGradient(f,c,d,e),this},b}(d),window.AnimationUpdater={elements:[],animId:null,addAll:function(a){var b,c,d,e;for(e=[],c=0,d=a.length;d>c;c++)b=a[c],e.push(AnimationUpdater.elements.push(b));return e},add:function(a){return AnimationUpdater.elements.push(a)},run:function(){var a,b,c,d,e;for(a=!0,e=AnimationUpdater.elements,c=0,d=e.length;d>c;c++)b=e[c],b.update()&&(a=!1);return a?cancelAnimationFrame(AnimationUpdater.animId):AnimationUpdater.animId=requestAnimationFrame(AnimationUpdater.run)}},"function"==typeof window.define&&null!=window.define.amd?define(function(){return{Gauge:g,Donut:f,BaseDonut:d,TextRenderer:i}}):"undefined"!=typeof module&&null!=module.exports?module.exports={Gauge:g,Donut:f,BaseDonut:d,TextRenderer:i}:(window.Gauge=g,window.Donut=f,window.BaseDonut=d,window.TextRenderer=i)}).call(this);
\ No newline at end of file