@cryptotaxi247 / netdata-1 / commits / dfe78d25e

auto-scaling of units on the dashboard; #2745

Costa Tsaousis (ktsaou) committed Oct 6, 2017 at 01:25 UTC dfe78d25e9ebed4ca70d96219e71661302c1d54b
2 files changed +202 -14
web/dashboard.js
+180 -13
@@ -294,6 +294,8 @@ var NETDATA = window.NETDATA || {};
294 // the current profile
295 // we may have many...
296 current: {
297 + units: 'auto', // can be 'auto' or 'original'
298 +
299 pixels_per_point: isSlowDevice()?5:1, // the minimum pixels per point for all charts
300 // increase this to speed javascript up
301 // each chart library has its own limit too
@@ -1464,6 +1466,119 @@ var NETDATA = window.NETDATA || {};
1466 };
1467
1468
1469 + // ----------------------------------------------------------------------------------------------------------------
1470 + // units conversion
1471 +
1472 + NETDATA.unitsConversion = {
1473 + units: {
1474 + 'kilobits/s': {
1475 + 'bits/s' : 0.001,
1476 + 'kilobits/s': 1,
1477 + 'megabits/s': 1000,
1478 + 'gigabits/s': 1000000
1479 + },
1480 + 'kilobytes/s': {
1481 + 'bytes/s' : 0.001,
1482 + 'kilobytes/s': 1,
1483 + 'megabytes/s': 1000,
1484 + 'gigabytes/s': 1000000
1485 + },
1486 + 'MB': {
1487 + 'B' : 0.000001,
1488 + 'KB': 0.001,
1489 + 'MB': 1,
1490 + 'GB': 1000,
1491 + 'TB': 1000000
1492 + },
1493 + 'GB': {
1494 + 'B' : 0.000000001,
1495 + 'KB': 0.000001,
1496 + 'MB': 0.001,
1497 + 'GB': 1,
1498 + 'TB': 1000
1499 + },
1500 + 'seconds': {
1501 + 'milliseconds': 0.001,
1502 + 'seconds' : 1,
1503 + 'minutes' : 60,
1504 + 'hours' : 3600,
1505 + 'days' : 86400
1506 + }
1507 + },
1508 +
1509 + get: function(min, max, units, desired_units, switch_units_callback) {
1510 + if(typeof units === 'undefined')
1511 + units = 'undefined';
1512 +
1513 + if(typeof desired_units === 'undefined' || desired_units === null)
1514 + desired_units = 'original';
1515 +
1516 + if(desired_units !== 'original' && typeof NETDATA.unitsConversion.units[units] !== 'undefined') {
1517 + // console.log('NETDATA.unitsConversion(' + units.toString() + ', ' + desired_units.toString() + ', function()) decide divider with min = ' + min.toString() + ', max = ' + max.toString());
1518 +
1519 + min = Math.abs(min);
1520 + max = Math.abs(max);
1521 + if (min > max) max = min;
1522 +
1523 + var divider = 1;
1524 + var x;
1525 +
1526 + if (desired_units === 'auto') {
1527 + var tunits = null;
1528 + var tdivider = 0;
1529 +
1530 + for (x in NETDATA.unitsConversion.units[units]) {
1531 + if (!NETDATA.unitsConversion.units[units].hasOwnProperty(x)) continue;
1532 +
1533 + var m = NETDATA.unitsConversion.units[units][x];
1534 +
1535 + if (m <= max && m > tdivider) {
1536 + tunits = x;
1537 + tdivider = m;
1538 + }
1539 + }
1540 +
1541 + if (tunits !== null) {
1542 + switch_units_callback(tunits);
1543 + divider = tdivider;
1544 + }
1545 + }
1546 + else {
1547 + var found = 0;
1548 + for (x in NETDATA.unitsConversion.units[units]) {
1549 + if (!NETDATA.unitsConversion.units[units].hasOwnProperty(x)) continue;
1550 +
1551 + if (x === desired_units) {
1552 + found = 1;
1553 + switch_units_callback(x);
1554 + divider = NETDATA.unitsConversion.units[units][x];
1555 + break;
1556 + }
1557 + }
1558 +
1559 + if(!found)
1560 + console.log('Units conversion from ' + units.toString() + ' to ' + desired_units.toString() + ' is not supported.');
1561 + }
1562 +
1563 + if(divider <= 0 || divider === 1)
1564 + return function (value) {
1565 + return value;
1566 + };
1567 +
1568 + return function (value) {
1569 + // console.log('NETDATA.unitsConversion(' + units.toString() + ', ' + desired_units.toString() + ', function()) decide divider with min = ' + min.toString() + ', max = ' + max.toString() + ', divider = ' + divider.toString() + ', value = ' + value.toString());
1570 + return value / divider;
1571 + };
1572 + }
1573 + else {
1574 + return function (value) {
1575 + // console.log('NETDATA.unitsConversion(' + units.toString() + ', ' + desired_units.toString() + ', function()) dummy divider');
1576 + return value;
1577 + };
1578 + }
1579 + }
1580 + };
1581 +
1582 // ----------------------------------------------------------------------------------------------------------------
1583 // global selection sync
1584
@@ -1677,6 +1792,9 @@ var NETDATA = window.NETDATA || {};
1792
1793 that.title = NETDATA.dataAttribute(that.element, 'title', null); // the title of the chart
1794 that.units = NETDATA.dataAttribute(that.element, 'units', null); // the units of the chart dimensions
1795 + that.units_desired = NETDATA.dataAttribute(that.element, 'desired-units', NETDATA.options.current.units); // the units of the chart dimensions
1796 + that.units_current = that.units;
1797 +
1798 that.append_options = NETDATA.dataAttribute(that.element, 'append-options', null); // additional options to pass to netdata
1799 that.override_options = NETDATA.dataAttribute(that.element, 'override-options', null); // override options to pass to netdata
1800
@@ -2525,6 +2643,30 @@ var NETDATA = window.NETDATA || {};
2643 return ret;
2644 };
2645
2646 + var __unitsConversionLastUnits = undefined;
2647 + var __unitsConversionLastUnitsDesired = undefined;
2648 + var __unitsConversionLastMin = undefined;
2649 + var __unitsConversionLastMax = undefined;
2650 + var __unitsConversion = function(value) { return value; };
2651 + this.unitsConversionSetup = function(min, max) {
2652 + if(this.units !== __unitsConversionLastUnits
2653 + || this.units_desired !== __unitsConversionLastUnitsDesired
2654 + || min !== __unitsConversionLastMin
2655 + || max !== __unitsConversionLastMax) {
2656 +
2657 + __unitsConversionLastUnits = this.units;
2658 + __unitsConversionLastUnitsDesired = this.units_desired;
2659 + __unitsConversionLastMin = min;
2660 + __unitsConversionLastMax = max;
2661 +
2662 + __unitsConversion = NETDATA.unitsConversion.get(min, max, this.units, this.units_desired, function (units) {
2663 + // console.log('switching units from ' + that.units.toString() + ' to ' + units.toString());
2664 + that.units_current = units;
2665 + that.legendSetUnitsString(that.units_current);
2666 + });
2667 + }
2668 + };
2669 +
2670 var __legendFormatValueChartDecimalsLastMin = undefined;
2671 var __legendFormatValueChartDecimalsLastMax = undefined;
2672 var __legendFormatValueChartDecimals = -1;
@@ -2533,6 +2675,12 @@ var NETDATA = window.NETDATA || {};
2675 if(min === __legendFormatValueChartDecimalsLastMin && max === __legendFormatValueChartDecimalsLastMax)
2676 return;
2677
2678 + this.unitsConversionSetup(min, max);
2679 + if(__unitsConversion !== null) {
2680 + min = __unitsConversion(min);
2681 + max = __unitsConversion(max);
2682 + }
2683 +
2684 __legendFormatValueChartDecimalsLastMin = min;
2685 __legendFormatValueChartDecimalsLastMax = max;
2686
@@ -2579,6 +2727,8 @@ var NETDATA = window.NETDATA || {};
2727 this.legendFormatValue = function(value) {
2728 if(typeof value !== 'number') return '-';
2729
2730 + value = __unitsConversion(value);
2731 +
2732 if(__intlNumberFormat !== null)
2733 return __intlNumberFormat.format(value);
2734
@@ -2662,7 +2812,7 @@ var NETDATA = window.NETDATA || {};
2812 }
2813 };
2814
2665 - this.__legendSetUnitsString = function(units) {
2815 + this.legendSetUnitsString = function(units) {
2816 if(units !== this.tmp.__last_shown_legend_units) {
2817 this.element_legend_childs.title_units.innerText = units;
2818 this.tmp.__last_shown_legend_units = units;
@@ -2695,7 +2845,7 @@ var NETDATA = window.NETDATA || {};
2845 this.__legendSetTimeString(this.legendSetDateLast.time);
2846
2847 if(this.element_legend_childs.title_units !== null)
2698 - this.__legendSetUnitsString(this.units)
2848 + this.legendSetUnitsString(this.units_current)
2849 };
2850
2851 this.legendShowUndefined = function() {
@@ -2706,7 +2856,7 @@ var NETDATA = window.NETDATA || {};
2856 this.__legendSetTimeString(this.chart.name);
2857
2858 if(this.element_legend_childs.title_units !== null)
2709 - this.__legendSetUnitsString(' ');
2859 + this.legendSetUnitsString(' ');
2860
2861 if(this.data && this.element_legend_childs.series !== null) {
2862 var labels = this.data.dimension_names;
@@ -3857,8 +4007,10 @@ var NETDATA = window.NETDATA || {};
4007 if(this.title === null)
4008 this.title = chart.title;
4009
3860 - if(this.units === null)
4010 + if(this.units === null) {
4011 this.units = chart.units;
4012 + this.units_current = this.units;
4013 + }
4014 };
4015
4016 // fetch the chart description from the netdata server
@@ -4469,7 +4621,7 @@ var NETDATA = window.NETDATA || {};
4621 var tooltipClassname = NETDATA.dataAttribute(state.element, 'sparkline-tooltipclassname', undefined);
4622 var tooltipFormat = NETDATA.dataAttribute(state.element, 'sparkline-tooltipformat', undefined);
4623 var tooltipPrefix = NETDATA.dataAttribute(state.element, 'sparkline-tooltipprefix', undefined);
4472 - var tooltipSuffix = NETDATA.dataAttribute(state.element, 'sparkline-tooltipsuffix', ' ' + state.units);
4624 + var tooltipSuffix = NETDATA.dataAttribute(state.element, 'sparkline-tooltipsuffix', ' ' + state.units_current);
4625 var tooltipSkipNull = NETDATA.dataAttributeBoolean(state.element, 'sparkline-tooltipskipnull', true);
4626 var tooltipValueLookups = NETDATA.dataAttribute(state.element, 'sparkline-tooltipvaluelookups', undefined);
4627 var tooltipFormatFieldlist = NETDATA.dataAttribute(state.element, 'sparkline-tooltipformatfieldlist', undefined);
@@ -4538,6 +4690,7 @@ var NETDATA = window.NETDATA || {};
4690 };
4691
4692 $(state.element_chart).sparkline(data.result, state.sparkline_options);
4693 +
4694 return true;
4695 };
4696
@@ -4756,7 +4909,7 @@ var NETDATA = window.NETDATA || {};
4909 xRangePad: NETDATA.dataAttribute(state.element, 'dygraph-xrangepad', 0),
4910 yRangePad: NETDATA.dataAttribute(state.element, 'dygraph-yrangepad', 1),
4911 valueRange: NETDATA.dataAttribute(state.element, 'dygraph-valuerange', [ null, null ]),
4759 - ylabel: state.units,
4912 + ylabel: state.units_current,
4913 yLabelWidth: NETDATA.dataAttribute(state.element, 'dygraph-ylabelwidth', 12),
4914
4915 // the function to plot the chart
@@ -5590,7 +5743,7 @@ var NETDATA = window.NETDATA || {};
5743 }
5744 },
5745 vAxis: {
5593 - title: state.units,
5746 + title: state.units_current,
5747 viewWindowMode: 'pretty',
5748 minValue: -0.1,
5749 maxValue: 0.1,
@@ -5672,6 +5825,8 @@ var NETDATA = window.NETDATA || {};
5825 if(min > value) min = value;
5826 if(max < value) max = value;
5827
5828 + state.legendFormatValueDecimalsFromMinMax(min, max);
5829 +
5830 if(state.tmp.easyPieChartMin === null && min > 0) min = 0;
5831 if(state.tmp.easyPieChartMax === null && max < 0) max = 0;
5832
@@ -5825,10 +5980,6 @@ var NETDATA = window.NETDATA || {};
5980 else
5981 state.tmp.easyPieChartMax = max;
5982
5828 - var pcent = NETDATA.easypiechartPercentFromValueMinMax(state, value, min, max);
5829 -
5830 - chart.data('data-percent', pcent);
5831 -
5983 var size = state.chartWidth();
5984 var stroke = Math.floor(size / 22);
5985 if(stroke < 3) stroke = 2;
@@ -5856,7 +6007,7 @@ var NETDATA = window.NETDATA || {};
6007 var unittop = Math.round(valuetop + (valuefontsize + unitfontsize) + (size / 40));
6008 state.tmp.easyPieChartUnits = document.createElement('span');
6009 state.tmp.easyPieChartUnits.className = 'easyPieChartUnits';
5859 - state.tmp.easyPieChartUnits.innerText = state.units;
6010 + state.tmp.easyPieChartUnits.innerText = state.units_current;
6011 state.tmp.easyPieChartUnits.style.fontSize = unitfontsize + 'px';
6012 state.tmp.easyPieChartUnits.style.top = unittop.toString() + 'px';
6013 state.element_chart.appendChild(state.tmp.easyPieChartUnits);
@@ -5871,6 +6022,13 @@ var NETDATA = window.NETDATA || {};
6022 barColor = tmp;
6023 }
6024
6025 + state.legendSetUnitsString = function(units) {
6026 + state.tmp.easyPieChartUnits.innerText = units;
6027 + };
6028 +
6029 + var pcent = NETDATA.easypiechartPercentFromValueMinMax(state, value, min, max);
6030 + chart.data('data-percent', pcent);
6031 +
6032 chart.easyPieChart({
6033 barColor: barColor,
6034 trackColor: NETDATA.dataAttribute(state.element, 'easypiechart-trackcolor', NETDATA.themes.current.easypiechart_track),
@@ -5955,6 +6113,8 @@ var NETDATA = window.NETDATA || {};
6113 else if(min === max)
6114 max = min + 1;
6115
6116 + state.legendFormatValueDecimalsFromMinMax(min, max);
6117 +
6118 // gauge.js has an issue if the needle
6119 // is smaller than min or larger than max
6120 // when we set the new values
@@ -6216,7 +6376,7 @@ var NETDATA = window.NETDATA || {};
6376 var unitfontsize = Math.round(titlefontsize * 0.9);
6377 state.tmp.gaugeChartUnits = document.createElement('span');
6378 state.tmp.gaugeChartUnits.className = 'gaugeChartUnits';
6219 - state.tmp.gaugeChartUnits.innerText = state.units;
6379 + state.tmp.gaugeChartUnits.innerText = state.units_current;
6380 state.tmp.gaugeChartUnits.style.fontSize = unitfontsize + 'px';
6381 state.element_chart.appendChild(state.tmp.gaugeChartUnits);
6382
@@ -6236,6 +6396,13 @@ var NETDATA = window.NETDATA || {};
6396 if(typeof state.tmp.gauge_instance !== 'undefined')
6397 animate = false;
6398
6399 + state.legendSetUnitsString = function(units) {
6400 + state.tmp.gaugeChartUnits.innerText = units;
6401 + state.tmp.___gaugeOld__.valueLabel = null;
6402 + state.tmp.___gaugeOld__.minLabel = null;
6403 + state.tmp.___gaugeOld__.maxLabel = null;
6404 + };
6405 +
6406 state.tmp.gauge_instance = new Gauge(state.tmp.gauge_canvas).setOptions(options); // create sexy gauge!
6407
6408 state.tmp.___gaugeOld__ = {
web/index.html
+22 -1
@@ -2718,6 +2718,11 @@
2718
2719 self.bootstrapToggle(netdataTheme === 'slate'?'on':'off');
2720 };
2721 + var units_sync_option = function(option) {
2722 + var self = $('#' + option);
2723 +
2724 + self.bootstrapToggle(NETDATA.options.current.units === 'auto'?'on':'off');
2725 + };
2726
2727 sync_option('eliminate_zero_dimensions');
2728 sync_option('destroy_on_hide');
@@ -2731,6 +2736,7 @@
2736 sync_option('pan_and_zoom_data_padding');
2737 sync_option('show_help');
2738 theme_sync_option('netdata_theme_control');
2739 + units_sync_option('units_conversion');
2740
2741 if(NETDATA.getOption('parallel_refresher') === false) {
2742 $('#concurrent_refreshes_row').hide();
@@ -2757,6 +2763,12 @@
2763 });
2764 $('#smooth_plot').change(function() { NETDATA.setOption('smooth_plot', $(this).prop('checked')); });
2765 $('#pan_and_zoom_data_padding').change(function() { NETDATA.setOption('pan_and_zoom_data_padding', $(this).prop('checked')); });
2766 +
2767 + $('#units_conversion').change(function() {
2768 + NETDATA.setOption('units', $(this).prop('checked')?'auto':'original');
2769 + netdataReload();
2770 + });
2771 +
2772 $('#show_help').change(function() {
2773 urlOptions.help = $(this).prop('checked');
2774 urlOptions.hashUpdate();
@@ -3381,6 +3393,15 @@
3393 </small>
3394 </td>
3395 </tr>
3396 + <tr class="option-row">
3397 + <td class="option-control"><input id="units_conversion" type="checkbox" checked data-toggle="toggle" data-on="Scale Units" data-off="Original" data-width="110px"></td>
3398 + <td class="option-info"><strong>Enable auto-conversion of units?</strong><br/>
3399 + <small>When set to <b>Scale Units</b> the values shown will be scaled to the maximum unit (ie. kilobits will be scaled to megabits or even gigabits). When set to <b>Original</b> all the values will be rendered using the original units maintained by the server.
3400 + <br/>
3401 + <b>Switching this will reload the dashboard</b>.
3402 + </small>
3403 + </td>
3404 + </tr>
3405 <tr class="option-row">
3406 <td class="option-control"><input id="pan_and_zoom_data_padding" type="checkbox" checked data-toggle="toggle" data-on="Pad" data-off="Don't Pad" data-width="110px"></td>
3407 <td class="option-info"><strong>Enable data padding when panning and zooming?</strong><br/>
@@ -3533,4 +3554,4 @@
3554 </div>
3555 </body>
3556 </html>
3536 -<script type="text/javascript" src="dashboard.js?v20171003-20"></script>
3557 +<script type="text/javascript" src="dashboard.js?v20171005-1"></script>