@cryptotaxi247 / netdata-1 / commits / ae676be6b

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