Daniel Lee 8 лет назад
Родитель
Сommit
22758d5112

+ 2 - 0
public/app/plugins/panel/heatmap/heatmap_data_converter.ts

@@ -214,12 +214,14 @@ function pushToYBuckets(buckets, bucketNum, value, point, bounds) {
   }
   }
   if (buckets[bucketNum]) {
   if (buckets[bucketNum]) {
     buckets[bucketNum].values.push(value);
     buckets[bucketNum].values.push(value);
+    buckets[bucketNum].points.push(point);
     buckets[bucketNum].count += count;
     buckets[bucketNum].count += count;
   } else {
   } else {
     buckets[bucketNum] = {
     buckets[bucketNum] = {
       y: bucketNum,
       y: bucketNum,
       bounds: bounds,
       bounds: bounds,
       values: [value],
       values: [value],
+      points: [point],
       count: count,
       count: count,
     };
     };
   }
   }

+ 10 - 4
public/app/plugins/panel/heatmap/heatmap_tooltip.ts

@@ -83,7 +83,10 @@ export class HeatmapTooltip {
 
 
     let boundBottom, boundTop, valuesNumber;
     let boundBottom, boundTop, valuesNumber;
     let xData = data.buckets[xBucketIndex];
     let xData = data.buckets[xBucketIndex];
-    let yData = xData.buckets[yBucketIndex];
+    // Search in special 'zero' bucket also
+    let yData = _.find(xData.buckets, (bucket, bucketIndex) => {
+      return bucket.bounds.bottom === yBucketIndex || bucketIndex === yBucketIndex;
+    });
 
 
     let tooltipTimeFormat = 'YYYY-MM-DD HH:mm:ss';
     let tooltipTimeFormat = 'YYYY-MM-DD HH:mm:ss';
     let time = this.dashboard.formatDate(xData.x, tooltipTimeFormat);
     let time = this.dashboard.formatDate(xData.x, tooltipTimeFormat);
@@ -105,7 +108,9 @@ export class HeatmapTooltip {
 
 
     if (yData) {
     if (yData) {
       if (yData.bounds) {
       if (yData.bounds) {
-        boundBottom = valueFormatter(yData.bounds.bottom);
+        // Display 0 if bucket is a special 'zero' bucket
+        let bottom = yData.y ? yData.bounds.bottom : 0;
+        boundBottom = valueFormatter(bottom);
         boundTop = valueFormatter(yData.bounds.top);
         boundTop = valueFormatter(yData.bounds.top);
         valuesNumber = yData.count;
         valuesNumber = yData.count;
         tooltipHtml += `<div>
         tooltipHtml += `<div>
@@ -165,7 +170,7 @@ export class HeatmapTooltip {
     let yBucketSize = this.scope.ctrl.data.yBucketSize;
     let yBucketSize = this.scope.ctrl.data.yBucketSize;
     let {min, max, ticks} = this.scope.ctrl.data.yAxis;
     let {min, max, ticks} = this.scope.ctrl.data.yAxis;
     let histogramData = _.map(xBucket.buckets, bucket => {
     let histogramData = _.map(xBucket.buckets, bucket => {
-      return [bucket.y, bucket.values.length];
+      return [bucket.bounds.bottom, bucket.values.length];
     });
     });
     histogramData = _.filter(histogramData, d => {
     histogramData = _.filter(histogramData, d => {
       return d[0] >= min && d[0] <= max;
       return d[0] >= min && d[0] <= max;
@@ -180,7 +185,8 @@ export class HeatmapTooltip {
     if (this.panel.yAxis.logBase === 1) {
     if (this.panel.yAxis.logBase === 1) {
       barWidth = Math.floor(HISTOGRAM_WIDTH / (max - min) * yBucketSize * 0.9);
       barWidth = Math.floor(HISTOGRAM_WIDTH / (max - min) * yBucketSize * 0.9);
     } else {
     } else {
-      barWidth = Math.floor(HISTOGRAM_WIDTH / ticks / yBucketSize * 0.9);
+      let barNumberFactor = yBucketSize ? yBucketSize : 1;
+      barWidth = Math.floor(HISTOGRAM_WIDTH / ticks / barNumberFactor * 0.9);
     }
     }
     barWidth = Math.max(barWidth, 1);
     barWidth = Math.max(barWidth, 1);
 
 

+ 32 - 34
public/app/plugins/panel/heatmap/partials/axes_editor.html

@@ -33,43 +33,26 @@
 
 
   <div class="section gf-form-group" ng-if="ctrl.panel.dataFormat == 'timeseries'">
   <div class="section gf-form-group" ng-if="ctrl.panel.dataFormat == 'timeseries'">
     <h5 class="section-heading">Buckets</h5>
     <h5 class="section-heading">Buckets</h5>
-    <div ng-show="ctrl.panel.yAxis.logBase === 1">
-      <div class="gf-form-inline">
-        <div class="gf-form">
-          <label class="gf-form-label">Y Axis</label>
-          <label class="gf-form-label">Buckets</label>
-          <input type="number" class="gf-form-input width-5" placeholder="auto" data-placement="right"
-                                                                                bs-tooltip="'Number of buckets for Y axis.'"
-                                                                                ng-model="ctrl.panel.yBucketNumber" ng-change="ctrl.refresh()" ng-model-onblur>
-        </div>
-        <div class="gf-form">
-          <label class="gf-form-label">Size</label>
-          <input type="number" class="gf-form-input width-5" placeholder="auto" data-placement="right"
-                                                                                bs-tooltip="'Size of bucket. Has priority over Buckets option.'"
-                                                                                ng-model="ctrl.panel.yBucketSize" ng-change="ctrl.refresh()" ng-model-onblur>
-        </div>
+    <div class="gf-form-inline">
+      <div class="gf-form">
+        <label class="gf-form-label width-5">Y Axis</label>
       </div>
       </div>
-      <div class="gf-form-inline">
-        <div class="gf-form">
-          <label class="gf-form-label">X Axis</label>
-          <label class="gf-form-label">Buckets</label>
-          <input type="number" class="gf-form-input width-5" placeholder="auto" data-placement="right"
-                                                                                bs-tooltip="'Number of buckets for Y axis.'"
-                                                                                ng-model="ctrl.panel.xBucketNumber" ng-change="ctrl.refresh()" ng-model-onblur>
-        </div>
-        <div class="gf-form">
-          <label class="gf-form-label">Size</label>
-          <input type="text" class="gf-form-input width-5" placeholder="auto" data-placement="right"
-                                                                              bs-tooltip="'Size of bucket. Number or interval (10s, 5m, 1h, etc). Supported intervals: ms, s, m, h, d, w, M, y. Has priority over Buckets option.'"
-                                                                              ng-model="ctrl.panel.xBucketSize" ng-change="ctrl.refresh()" ng-model-onblur>
-        </div>
+      <div class="gf-form" ng-show="ctrl.panel.yAxis.logBase === 1">
+        <label class="gf-form-label width-5">Buckets</label>
+        <input type="number" class="gf-form-input width-5" placeholder="auto" data-placement="right"
+                                                                              bs-tooltip="'Number of buckets for Y axis.'"
+                                                                              ng-model="ctrl.panel.yBucketNumber" ng-change="ctrl.refresh()" ng-model-onblur>
       </div>
       </div>
-    </div>
-    <div ng-show="ctrl.panel.yAxis.logBase !== 1">
-      <div class="gf-form">
-        <label class="gf-form-label width-7">Split Factor</label>
+      <div class="gf-form" ng-show="ctrl.panel.yAxis.logBase === 1">
+        <label class="gf-form-label width-4">Size</label>
+        <input type="number" class="gf-form-input width-5" placeholder="auto" data-placement="right"
+                                                                              bs-tooltip="'Size of bucket. Has priority over Buckets option.'"
+                                                                              ng-model="ctrl.panel.yBucketSize" ng-change="ctrl.refresh()" ng-model-onblur>
+      </div>
+      <div class="gf-form" ng-show="ctrl.panel.yAxis.logBase !== 1">
+        <label class="gf-form-label width-10">Split Factor</label>
         <input type="number"
         <input type="number"
-               class="gf-form-input width-3"
+               class="gf-form-input width-9"
                placeholder="1"
                placeholder="1"
                data-placement="right"
                data-placement="right"
                bs-tooltip="'For log scales only. By default Y values is splitted by integer powers of log base (1, 2, 4, 8, 16, ... for log2). This option allows to split each default bucket into specified number of buckets.'"
                bs-tooltip="'For log scales only. By default Y values is splitted by integer powers of log base (1, 2, 4, 8, 16, ... for log2). This option allows to split each default bucket into specified number of buckets.'"
@@ -77,6 +60,21 @@
         </input>
         </input>
       </div>
       </div>
     </div>
     </div>
+    <div class="gf-form-inline">
+      <div class="gf-form">
+        <label class="gf-form-label width-5">X Axis</label>
+        <label class="gf-form-label width-5">Buckets</label>
+        <input type="number" class="gf-form-input width-5" placeholder="auto" data-placement="right"
+                                                                              bs-tooltip="'Number of buckets for X axis.'"
+                                                                              ng-model="ctrl.panel.xBucketNumber" ng-change="ctrl.refresh()" ng-model-onblur>
+      </div>
+      <div class="gf-form">
+        <label class="gf-form-label width-4">Size</label>
+        <input type="text" class="gf-form-input width-5" placeholder="auto" data-placement="right"
+                                                                            bs-tooltip="'Size of bucket. Number or interval (10s, 5m, 1h, etc). Supported intervals: ms, s, m, h, d, w, M, y. Has priority over Buckets option.'"
+                                                                            ng-model="ctrl.panel.xBucketSize" ng-change="ctrl.refresh()" ng-model-onblur>
+      </div>
+    </div>
   </div>
   </div>
 
 
   <div class="section gf-form-group">
   <div class="section gf-form-group">

+ 1 - 1
public/app/plugins/panel/heatmap/rendering.ts

@@ -210,7 +210,7 @@ export default function link(scope, elem, attrs, ctrl) {
     let log_base = panel.yAxis.logBase;
     let log_base = panel.yAxis.logBase;
     let {y_min, y_max} = adjustLogRange(data.heatmapStats.minLog, data.heatmapStats.max, log_base);
     let {y_min, y_max} = adjustLogRange(data.heatmapStats.minLog, data.heatmapStats.max, log_base);
 
 
-    y_min = panel.yAxis.min !== null ? adjustLogMin(panel.yAxis.min, log_base) : y_min;
+    y_min = panel.yAxis.min && panel.yAxis.min !== '0' ? adjustLogMin(panel.yAxis.min, log_base) : y_min;
     y_max = panel.yAxis.max !== null ? adjustLogMax(panel.yAxis.max, log_base) : y_max;
     y_max = panel.yAxis.max !== null ? adjustLogMax(panel.yAxis.max, log_base) : y_max;
 
 
     // Set default Y min and max if no data
     // Set default Y min and max if no data

+ 18 - 2
public/app/plugins/panel/singlestat/specs/singlestat_panel_spec.ts

@@ -14,11 +14,27 @@ describe('grafanaSingleStat', function() {
         expect(getColorForValue(data, 5)).to.be('green');
         expect(getColorForValue(data, 5)).to.be('green');
       });
       });
 
 
-      it('25 should return green', () => {
+      it('19.9 should return green', () => {
+        expect(getColorForValue(data, 19.9)).to.be('green');
+      });
+
+      it('20 should return yellow', () => {
+        expect(getColorForValue(data, 20)).to.be('yellow');
+      });
+
+      it('20.1 should return yellow', () => {
+        expect(getColorForValue(data, 20.1)).to.be('yellow');
+      });
+
+      it('25 should return yellow', () => {
         expect(getColorForValue(data, 25)).to.be('yellow');
         expect(getColorForValue(data, 25)).to.be('yellow');
       });
       });
 
 
-      it('55 should return green', () => {
+      it('50 should return red', () => {
+        expect(getColorForValue(data, 50)).to.be('red');
+      });
+
+      it('55 should return red', () => {
         expect(getColorForValue(data, 55)).to.be('red');
         expect(getColorForValue(data, 55)).to.be('red');
       });
       });
     });
     });

+ 1 - 1
public/app/plugins/panel/singlestat/specs/singlestat_specs.ts

@@ -108,7 +108,7 @@ describe('SingleStatCtrl', function() {
     });
     });
   });
   });
 
 
-  singleStatScenario('When range to text mapping is specifiedfor first range', function(ctx) {
+  singleStatScenario('When range to text mapping is specified for first range', function(ctx) {
     ctx.setup(function() {
     ctx.setup(function() {
       ctx.data = [
       ctx.data = [
         {target: 'test.cpu1', datapoints: [[41,50]]}
         {target: 'test.cpu1', datapoints: [[41,50]]}

+ 9 - 0
public/sass/components/_panel_heatmap.scss

@@ -18,6 +18,15 @@
       stroke: $text-color-weak;
       stroke: $text-color-weak;
     }
     }
   }
   }
+
+  // This hack prevents mouseenter/mouseleave events get fired too often
+  svg {
+    pointer-events: none;
+
+    rect {
+      pointer-events: visiblePainted;
+    }
+  }
 }
 }
 
 
 .heatmap-tooltip {
 .heatmap-tooltip {

+ 34 - 34
public/vendor/flot/jquery.flot.gauge.js

@@ -85,17 +85,17 @@
          * @return the calculated layout properties
          * @return the calculated layout properties
          */
          */
         Gauge.prototype.calculateLayout = function() {
         Gauge.prototype.calculateLayout = function() {
-            
+
             var canvasWidth = placeholder.width();
             var canvasWidth = placeholder.width();
             var canvasHeight = placeholder.height();
             var canvasHeight = placeholder.height();
-            
-            
+
+
 
 
             // calculate cell size
             // calculate cell size
             var columns = Math.min(series.length, gaugeOptions.layout.columns);
             var columns = Math.min(series.length, gaugeOptions.layout.columns);
             var rows = Math.ceil(series.length / columns);
             var rows = Math.ceil(series.length / columns);
-            
-            
+
+
 
 
             var margin = gaugeOptions.layout.margin;
             var margin = gaugeOptions.layout.margin;
             var hMargin = gaugeOptions.layout.hMargin;
             var hMargin = gaugeOptions.layout.hMargin;
@@ -107,8 +107,8 @@
                 cellWidth = cell;
                 cellWidth = cell;
                 cellHeight = cell;
                 cellHeight = cell;
             }
             }
-            
-            
+
+
 
 
             // calculate 'auto' values
             // calculate 'auto' values
             calculateAutoValues(gaugeOptions, cellWidth);
             calculateAutoValues(gaugeOptions, cellWidth);
@@ -155,13 +155,13 @@
             var maxRadiusV = outerRadiusV - (thresholdLabelMargin * 2) - thresholdLabelFontSize - thresholdWidth;
             var maxRadiusV = outerRadiusV - (thresholdLabelMargin * 2) - thresholdLabelFontSize - thresholdWidth;
 
 
             var radius = Math.min(maxRadiusH, maxRadiusV);
             var radius = Math.min(maxRadiusH, maxRadiusV);
-            
+
 
 
             var width = gaugeOptions.gauge.width;
             var width = gaugeOptions.gauge.width;
             if (width >= radius) {
             if (width >= radius) {
                 width = Math.max(3, radius / 3);
                 width = Math.max(3, radius / 3);
             }
             }
-            
+
 
 
             var outerRadius = (thresholdLabelMargin * 2) + thresholdLabelFontSize + thresholdWidth + radius;
             var outerRadius = (thresholdLabelMargin * 2) + thresholdLabelFontSize + thresholdWidth + radius;
             var gaugeOuterHeight = Math.max(outerRadius * (1 + heightRatioV), outerRadius + valueMargin + (valueFontSize / 2));
             var gaugeOuterHeight = Math.max(outerRadius * (1 + heightRatioV), outerRadius + valueMargin + (valueFontSize / 2));
@@ -198,7 +198,7 @@
          * @param  {Number} cellWidth the width of cell
          * @param  {Number} cellWidth the width of cell
          */
          */
         function calculateAutoValues(gaugeOptionsi, cellWidth) {
         function calculateAutoValues(gaugeOptionsi, cellWidth) {
-            
+
             if (gaugeOptionsi.gauge.width === "auto") {
             if (gaugeOptionsi.gauge.width === "auto") {
                 gaugeOptionsi.gauge.width = Math.max(5, cellWidth / 8);
                 gaugeOptionsi.gauge.width = Math.max(5, cellWidth / 8);
             }
             }
@@ -223,7 +223,7 @@
             if (gaugeOptionsi.threshold.label.font.size === "auto") {
             if (gaugeOptionsi.threshold.label.font.size === "auto") {
                 gaugeOptionsi.threshold.label.font.size = Math.max(5, cellWidth / 15);
                 gaugeOptionsi.threshold.label.font.size = Math.max(5, cellWidth / 15);
             }
             }
-            
+
         }
         }
         Gauge.prototype.calculateAutoValues = calculateAutoValues;
         Gauge.prototype.calculateAutoValues = calculateAutoValues;
 
 
@@ -237,7 +237,7 @@
          * @return the calculated cell layout properties
          * @return the calculated cell layout properties
          */
          */
         Gauge.prototype.calculateCellLayout = function(gaugeOptionsi, layout, i) {
         Gauge.prototype.calculateCellLayout = function(gaugeOptionsi, layout, i) {
-            
+
             // calculate top, left and center
             // calculate top, left and center
             var c = col(layout.columns, i);
             var c = col(layout.columns, i);
             var r = row(layout.columns, i);
             var r = row(layout.columns, i);
@@ -276,7 +276,7 @@
          * @param  {Object} layout the layout properties
          * @param  {Object} layout the layout properties
          */
          */
         Gauge.prototype.drawBackground = function(layout) {
         Gauge.prototype.drawBackground = function(layout) {
-            
+
             if (!gaugeOptions.frame.show) {
             if (!gaugeOptions.frame.show) {
                 return;
                 return;
             }
             }
@@ -299,7 +299,7 @@
          * @param  {Object} cellLayout the cell layout properties
          * @param  {Object} cellLayout the cell layout properties
          */
          */
         Gauge.prototype.drawCellBackground = function(gaugeOptionsi, cellLayout) {
         Gauge.prototype.drawCellBackground = function(gaugeOptionsi, cellLayout) {
-            
+
             context.save();
             context.save();
             if (gaugeOptionsi.cell.border && gaugeOptionsi.cell.border.show && gaugeOptionsi.cell.border.color && gaugeOptionsi.cell.border.width) {
             if (gaugeOptionsi.cell.border && gaugeOptionsi.cell.border.show && gaugeOptionsi.cell.border.color && gaugeOptionsi.cell.border.width) {
                 context.strokeStyle = gaugeOptionsi.cell.border.color;
                 context.strokeStyle = gaugeOptionsi.cell.border.color;
@@ -324,10 +324,10 @@
          * @param  {Number} data the value of the gauge
          * @param  {Number} data the value of the gauge
          */
          */
         Gauge.prototype.drawGauge = function(gaugeOptionsi, layout, cellLayout, label, data) {
         Gauge.prototype.drawGauge = function(gaugeOptionsi, layout, cellLayout, label, data) {
-            
+
 
 
             var blur = gaugeOptionsi.gauge.shadow.show ? gaugeOptionsi.gauge.shadow.blur : 0;
             var blur = gaugeOptionsi.gauge.shadow.show ? gaugeOptionsi.gauge.shadow.blur : 0;
-            
+
 
 
             // draw gauge frame
             // draw gauge frame
             drawArcWithShadow(
             drawArcWithShadow(
@@ -371,7 +371,7 @@
             for (var i = 0; i < gaugeOptionsi.threshold.values.length; i++) {
             for (var i = 0; i < gaugeOptionsi.threshold.values.length; i++) {
                 var threshold = gaugeOptionsi.threshold.values[i];
                 var threshold = gaugeOptionsi.threshold.values[i];
                 color = threshold.color;
                 color = threshold.color;
-                if (data <= threshold.value) {
+                if (data < threshold.value) {
                     break;
                     break;
                 }
                 }
             }
             }
@@ -410,7 +410,7 @@
          * @param  {Object} cellLayout the cell layout properties
          * @param  {Object} cellLayout the cell layout properties
          */
          */
         Gauge.prototype.drawThreshold = function(gaugeOptionsi, layout, cellLayout) {
         Gauge.prototype.drawThreshold = function(gaugeOptionsi, layout, cellLayout) {
-            
+
             var a1 = gaugeOptionsi.gauge.startAngle;
             var a1 = gaugeOptionsi.gauge.startAngle;
             for (var i = 0; i < gaugeOptionsi.threshold.values.length; i++) {
             for (var i = 0; i < gaugeOptionsi.threshold.values.length; i++) {
                 var threshold = gaugeOptionsi.threshold.values[i];
                 var threshold = gaugeOptionsi.threshold.values[i];
@@ -478,7 +478,7 @@
          * @param  {Object} item the item of the series
          * @param  {Object} item the item of the series
          */
          */
         Gauge.prototype.drawLable = function(gaugeOptionsi, layout, cellLayout, i, item) {
         Gauge.prototype.drawLable = function(gaugeOptionsi, layout, cellLayout, i, item) {
-            
+
             drawText(
             drawText(
                 cellLayout.cx,
                 cellLayout.cx,
                 cellLayout.y + cellLayout.cellMargin + layout.labelMargin + cellLayout.offsetY,
                 cellLayout.y + cellLayout.cellMargin + layout.labelMargin + cellLayout.offsetY,
@@ -498,7 +498,7 @@
          * @param  {Object} item the item of the series
          * @param  {Object} item the item of the series
          */
          */
         Gauge.prototype.drawValue = function(gaugeOptionsi, layout, cellLayout, i, item) {
         Gauge.prototype.drawValue = function(gaugeOptionsi, layout, cellLayout, i, item) {
-            
+
             drawText(
             drawText(
                 cellLayout.cx,
                 cellLayout.cx,
                 cellLayout.cy - (gaugeOptionsi.value.font.size / 2),
                 cellLayout.cy - (gaugeOptionsi.value.font.size / 2),
@@ -517,7 +517,7 @@
          * @param  {Number} i the index of the series
          * @param  {Number} i the index of the series
          */
          */
         Gauge.prototype.drawThresholdValues = function(gaugeOptionsi, layout, cellLayout, i) {
         Gauge.prototype.drawThresholdValues = function(gaugeOptionsi, layout, cellLayout, i) {
-            
+
             // min, max
             // min, max
             drawThresholdValue(gaugeOptionsi, layout, cellLayout, "Min" + i, gaugeOptionsi.gauge.min, gaugeOptionsi.gauge.startAngle);
             drawThresholdValue(gaugeOptionsi, layout, cellLayout, "Min" + i, gaugeOptionsi.gauge.min, gaugeOptionsi.gauge.startAngle);
             drawThresholdValue(gaugeOptionsi, layout, cellLayout, "Max" + i, gaugeOptionsi.gauge.max, gaugeOptionsi.gauge.endAngle);
             drawThresholdValue(gaugeOptionsi, layout, cellLayout, "Max" + i, gaugeOptionsi.gauge.max, gaugeOptionsi.gauge.endAngle);
@@ -729,8 +729,8 @@
         plot.hooks.processOptions.push(function(plot, options) {
         plot.hooks.processOptions.push(function(plot, options) {
             var logger = getLogger(options.series.gauges.debug);
             var logger = getLogger(options.series.gauges.debug);
 
 
-            
-            
+
+
 
 
             // turn 'grid' and 'legend' off
             // turn 'grid' and 'legend' off
             if (options.series.gauges.show) {
             if (options.series.gauges.show) {
@@ -740,7 +740,7 @@
 
 
             // sort threshold
             // sort threshold
             var thresholds = options.series.gauges.threshold.values;
             var thresholds = options.series.gauges.threshold.values;
-            
+
             thresholds.sort(function(a, b) {
             thresholds.sort(function(a, b) {
                 if (a.value < b.value) {
                 if (a.value < b.value) {
                     return -1;
                     return -1;
@@ -750,9 +750,9 @@
                     return 0;
                     return 0;
                 }
                 }
             });
             });
-            
 
 
-            
+
+
         });
         });
 
 
         // add draw hook
         // add draw hook
@@ -761,14 +761,14 @@
             var gaugeOptions = options.series.gauges;
             var gaugeOptions = options.series.gauges;
 
 
             var logger = getLogger(gaugeOptions.debug);
             var logger = getLogger(gaugeOptions.debug);
-            
+
 
 
             if (!gaugeOptions.show) {
             if (!gaugeOptions.show) {
                 return;
                 return;
             }
             }
 
 
             var series = plot.getData();
             var series = plot.getData();
-            
+
             if (!series || !series.length) {
             if (!series || !series.length) {
                 return; // if no series were passed
                 return; // if no series were passed
             }
             }
@@ -777,10 +777,10 @@
 
 
             // calculate layout
             // calculate layout
             var layout = gauge.calculateLayout();
             var layout = gauge.calculateLayout();
-            
+
             // debug layout
             // debug layout
             if (gaugeOptions.debug.layout) {
             if (gaugeOptions.debug.layout) {
-                
+
             }
             }
 
 
             // draw background
             // draw background
@@ -789,21 +789,21 @@
             // draw cells (label, gauge, value, threshold)
             // draw cells (label, gauge, value, threshold)
             for (var i = 0; i < series.length; i++) {
             for (var i = 0; i < series.length; i++) {
                 var item = series[i];
                 var item = series[i];
-                
+
                 var gaugeOptionsi = $.extend({}, gaugeOptions, item.gauges);
                 var gaugeOptionsi = $.extend({}, gaugeOptions, item.gauges);
                 if (item.gauges) {
                 if (item.gauges) {
                     // re-calculate 'auto' values
                     // re-calculate 'auto' values
                     gauge.calculateAutoValues(gaugeOptionsi, layout.cellWidth);
                     gauge.calculateAutoValues(gaugeOptionsi, layout.cellWidth);
                 }
                 }
-                
+
                 // calculate cell layout
                 // calculate cell layout
                 var cellLayout = gauge.calculateCellLayout(gaugeOptionsi, layout, i);
                 var cellLayout = gauge.calculateCellLayout(gaugeOptionsi, layout, i);
-                
+
                 // draw cell background
                 // draw cell background
                 gauge.drawCellBackground(gaugeOptionsi, cellLayout)
                 gauge.drawCellBackground(gaugeOptionsi, cellLayout)
                 // debug layout
                 // debug layout
                 if (gaugeOptionsi.debug.layout) {
                 if (gaugeOptionsi.debug.layout) {
-                    
+
                 }
                 }
                 // draw label
                 // draw label
                 if (gaugeOptionsi.label.show) {
                 if (gaugeOptionsi.label.show) {