From b18ed0b98f1918374c6e4d222cc5c4885c2ef01c Mon Sep 17 00:00:00 2001 From: Alexander Zobnin Date: Fri, 31 Mar 2017 12:51:43 +0300 Subject: [PATCH] heatmap: calculate bucket size automatically for ES histogram --- .../app/plugins/panel/heatmap/heatmap_ctrl.ts | 54 ++++++++----------- .../panel/heatmap/heatmap_data_converter.ts | 11 +++- public/app/plugins/panel/heatmap/rendering.ts | 2 +- 3 files changed, 33 insertions(+), 34 deletions(-) diff --git a/public/app/plugins/panel/heatmap/heatmap_ctrl.ts b/public/app/plugins/panel/heatmap/heatmap_ctrl.ts index c7572b38745..6eedbbaf9c4 100644 --- a/public/app/plugins/panel/heatmap/heatmap_ctrl.ts +++ b/public/app/plugins/panel/heatmap/heatmap_ctrl.ts @@ -7,7 +7,7 @@ import TimeSeries from 'app/core/time_series'; import {axesEditor} from './axes_editor'; import {heatmapDisplayEditor} from './display_editor'; import rendering from './rendering'; -import { convertToHeatMap, elasticHistogramToHeatmap, getMinLog} from './heatmap_data_converter'; +import { convertToHeatMap, elasticHistogramToHeatmap, calculateBucketSize, getMinLog} from './heatmap_data_converter'; let X_BUCKET_NUMBER_DEFAULT = 30; let Y_BUCKET_NUMBER_DEFAULT = 10; @@ -140,41 +140,33 @@ export class HeatmapCtrl extends MetricsPanelCtrl { let xBucketSize, yBucketSize, heatmapStats, bucketsData; let logBase = this.panel.yAxis.logBase; - let xBucketNumber = this.panel.xBucketNumber || X_BUCKET_NUMBER_DEFAULT; - let xBucketSizeByNumber = Math.floor((this.range.to - this.range.from) / xBucketNumber); - - // Parse X bucket size (number or interval) - let isIntervalString = kbn.interval_regex.test(this.panel.xBucketSize); - if (isIntervalString) { - xBucketSize = kbn.interval_to_ms(this.panel.xBucketSize); - } else if (isNaN(Number(this.panel.xBucketSize)) || this.panel.xBucketSize === '' || this.panel.xBucketSize === null) { - xBucketSize = xBucketSizeByNumber; - } else { - xBucketSize = Number(this.panel.xBucketSize); - } if (this.panel.dataFormat === 'es_histogram') { heatmapStats = this.parseHistogramSeries(this.series); - - // Calculate Y bucket size - let yBucketNumber = this.panel.yBucketNumber || Y_BUCKET_NUMBER_DEFAULT; - if (logBase !== 1) { - yBucketSize = this.panel.yAxis.splitFactor; - } else { - if (heatmapStats.max === heatmapStats.min) { - if (heatmapStats.max) { - yBucketSize = heatmapStats.max / Y_BUCKET_NUMBER_DEFAULT; - } else { - yBucketSize = 1; - } - } else { - yBucketSize = (heatmapStats.max - heatmapStats.min) / yBucketNumber; - } - yBucketSize = this.panel.yBucketSize || yBucketSize; - } - bucketsData = elasticHistogramToHeatmap(this.series); + + // Calculate bucket size based on ES heatmap data + let xBucketBoundSet = _.map(_.keys(bucketsData), key => Number(key)); + let yBucketBoundSet = _.map(this.series, series => Number(series.alias)); + xBucketSize = calculateBucketSize(xBucketBoundSet); + yBucketSize = calculateBucketSize(yBucketBoundSet, logBase); + if (logBase !== 1) { + // Use yBucketSize in meaning of "Split factor" for log scales + yBucketSize = 1 / yBucketSize; + } } else { + let xBucketNumber = this.panel.xBucketNumber || X_BUCKET_NUMBER_DEFAULT; + let xBucketSizeByNumber = Math.floor((this.range.to - this.range.from) / xBucketNumber); + + // Parse X bucket size (number or interval) + let isIntervalString = kbn.interval_regex.test(this.panel.xBucketSize); + if (isIntervalString) { + xBucketSize = kbn.interval_to_ms(this.panel.xBucketSize); + } else if (isNaN(Number(this.panel.xBucketSize)) || this.panel.xBucketSize === '' || this.panel.xBucketSize === null) { + xBucketSize = xBucketSizeByNumber; + } else { + xBucketSize = Number(this.panel.xBucketSize); + } // Calculate Y bucket size heatmapStats = this.parseSeries(this.series); diff --git a/public/app/plugins/panel/heatmap/heatmap_data_converter.ts b/public/app/plugins/panel/heatmap/heatmap_data_converter.ts index 54db6be5838..800eb26f322 100644 --- a/public/app/plugins/panel/heatmap/heatmap_data_converter.ts +++ b/public/app/plugins/panel/heatmap/heatmap_data_converter.ts @@ -155,10 +155,17 @@ function mergeZeroBuckets(buckets, minValue) { let newBucket = { y: 0, bounds: {bottom: minValue, top: minBucket.bounds.top || minValue}, - values: nullBucket.values.concat(minBucket.values), - points: nullBucket.points.concat(minBucket.points) + values: [], + points: [] }; + if (nullBucket.values) { + newBucket.values = nullBucket.values.concat(minBucket.values); + } + if (nullBucket.points) { + newBucket.points = nullBucket.points.concat(minBucket.points); + } + let newYBuckets = {}; _.forEach(yBuckets, (bucket, bound) => { bound = Number(bound); diff --git a/public/app/plugins/panel/heatmap/rendering.ts b/public/app/plugins/panel/heatmap/rendering.ts index afc92375018..19e6dedfdd0 100644 --- a/public/app/plugins/panel/heatmap/rendering.ts +++ b/public/app/plugins/panel/heatmap/rendering.ts @@ -449,7 +449,7 @@ export default function link(scope, elem, attrs, ctrl) { if (panel.yAxis.logBase !== 1) { let base = panel.yAxis.logBase; - let splitFactor = panel.yAxis.splitFactor || 1; + let splitFactor = data.yBucketSize || 1; yGridSize = Math.floor((yScale(1) - yScale(base)) / splitFactor); }