From cb8ecb2d5faec9c1ac8b3f4d8dcc466c65da3fa3 Mon Sep 17 00:00:00 2001 From: Alexander Zobnin Date: Tue, 25 Jul 2017 17:28:29 +0300 Subject: [PATCH] Heatmap fixes (adapted for v4.4.x branch) (#8920) * heatmap: fix converting error when series contains 0 and log scale is selected, issue #8884 * heatmap: fix app crash when Y min set to 0 with log scale * heatmap: fix tooltip for 'zero' buckets in log scale * heatmap: fix tooltip histogram for log scales * heatmap: fix flicker of the highlighted element this was caused by too often fired mouseenter/mouseleave events * heatmap: fix missing X axis option for log scales * heatmap: fix missing zero bucket in tooltip histogram --- .../panel/heatmap/heatmap_data_converter.ts | 2 + .../plugins/panel/heatmap/heatmap_tooltip.ts | 14 ++-- .../panel/heatmap/partials/axes_editor.html | 68 +++++++++---------- public/app/plugins/panel/heatmap/rendering.ts | 2 +- public/sass/components/_panel_heatmap.scss | 9 +++ 5 files changed, 55 insertions(+), 40 deletions(-) diff --git a/public/app/plugins/panel/heatmap/heatmap_data_converter.ts b/public/app/plugins/panel/heatmap/heatmap_data_converter.ts index d9e6bbb7d43..ef405ea5508 100644 --- a/public/app/plugins/panel/heatmap/heatmap_data_converter.ts +++ b/public/app/plugins/panel/heatmap/heatmap_data_converter.ts @@ -214,12 +214,14 @@ function pushToYBuckets(buckets, bucketNum, value, point, bounds) { } if (buckets[bucketNum]) { buckets[bucketNum].values.push(value); + buckets[bucketNum].points.push(point); buckets[bucketNum].count += count; } else { buckets[bucketNum] = { y: bucketNum, bounds: bounds, values: [value], + points: [point], count: count, }; } diff --git a/public/app/plugins/panel/heatmap/heatmap_tooltip.ts b/public/app/plugins/panel/heatmap/heatmap_tooltip.ts index 5ec0a8fa308..0d3f65cbf4d 100644 --- a/public/app/plugins/panel/heatmap/heatmap_tooltip.ts +++ b/public/app/plugins/panel/heatmap/heatmap_tooltip.ts @@ -83,7 +83,10 @@ export class HeatmapTooltip { let boundBottom, boundTop, valuesNumber; 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 time = this.dashboard.formatDate(xData.x, tooltipTimeFormat); @@ -105,7 +108,9 @@ export class HeatmapTooltip { if (yData) { 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); valuesNumber = yData.count; tooltipHtml += `
@@ -165,7 +170,7 @@ export class HeatmapTooltip { let yBucketSize = this.scope.ctrl.data.yBucketSize; let {min, max, ticks} = this.scope.ctrl.data.yAxis; let histogramData = _.map(xBucket.buckets, bucket => { - return [bucket.y, bucket.values.length]; + return [bucket.bounds.bottom, bucket.values.length]; }); histogramData = _.filter(histogramData, d => { return d[0] >= min && d[0] <= max; @@ -180,7 +185,8 @@ export class HeatmapTooltip { if (this.panel.yAxis.logBase === 1) { barWidth = Math.floor(HISTOGRAM_WIDTH / (max - min) * yBucketSize * 0.9); } 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); diff --git a/public/app/plugins/panel/heatmap/partials/axes_editor.html b/public/app/plugins/panel/heatmap/partials/axes_editor.html index 10af1977af7..5d25bedd667 100644 --- a/public/app/plugins/panel/heatmap/partials/axes_editor.html +++ b/public/app/plugins/panel/heatmap/partials/axes_editor.html @@ -33,43 +33,26 @@
Buckets
-
-
-
- - - -
-
- - -
-
-
-
- - - -
-
- - -
-
-
-
+
- + +
+
+ + +
+
+ + +
+
+
+
+
+ + + +
+
+ + +
+
diff --git a/public/app/plugins/panel/heatmap/rendering.ts b/public/app/plugins/panel/heatmap/rendering.ts index b928173eafe..de2c2fde719 100644 --- a/public/app/plugins/panel/heatmap/rendering.ts +++ b/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 {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; // Set default Y min and max if no data diff --git a/public/sass/components/_panel_heatmap.scss b/public/sass/components/_panel_heatmap.scss index cf55c91ab7c..9d07e6a363c 100644 --- a/public/sass/components/_panel_heatmap.scss +++ b/public/sass/components/_panel_heatmap.scss @@ -18,6 +18,15 @@ stroke: $text-color-weak; } } + + // This hack prevents mouseenter/mouseleave events get fired too often + svg { + pointer-events: none; + + rect { + pointer-events: visiblePainted; + } + } } .heatmap-tooltip {