Browse Source

heatmap: sort series before converting to heatmap.

This allows to use histogram series from arbitrary datasource and display it properly.
Alexander Zobnin 7 years ago
parent
commit
5037f93a78

+ 9 - 2
public/app/plugins/panel/heatmap/heatmap_ctrl.ts

@@ -5,7 +5,13 @@ import TimeSeries from 'app/core/time_series2';
 import { axesEditor } from './axes_editor';
 import { heatmapDisplayEditor } from './display_editor';
 import rendering from './rendering';
-import { convertToHeatMap, convertToCards, histogramToHeatmap, calculateBucketSize } from './heatmap_data_converter';
+import {
+  convertToHeatMap,
+  convertToCards,
+  histogramToHeatmap,
+  calculateBucketSize,
+  sortSeriesByLabel,
+} from './heatmap_data_converter';
 
 let X_BUCKET_NUMBER_DEFAULT = 30;
 let Y_BUCKET_NUMBER_DEFAULT = 10;
@@ -205,9 +211,10 @@ export class HeatmapCtrl extends MetricsPanelCtrl {
 
     // Convert histogram to heatmap. Each histogram bucket represented by the series which name is
     // a top (or bottom, depends of datasource) bucket bound. Further, these values will be used as X axis labels.
+    this.series.sort(sortSeriesByLabel);
     bucketsData = histogramToHeatmap(this.series);
-    tsBuckets = _.map(this.series, 'label');
 
+    tsBuckets = _.map(this.series, 'label');
     if (this.datasource && this.datasource.type === 'prometheus') {
       // Prometheus labels are upper inclusive bounds, so add empty bottom bucket label.
       tsBuckets = [''].concat(tsBuckets);

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

@@ -56,6 +56,39 @@ function histogramToHeatmap(seriesList) {
   return heatmap;
 }
 
+/**
+ * Sort series representing histogram by label value.
+ */
+function sortSeriesByLabel(s1, s2) {
+  let label1, label2;
+
+  try {
+    // fail if not integer. might happen with bad queries
+    label1 = parseHistogramLabel(s1.label);
+    label2 = parseHistogramLabel(s2.label);
+  } catch (err) {
+    console.log(err);
+    return 0;
+  }
+
+  if (label1 > label2) {
+    return 1;
+  }
+
+  if (label1 < label2) {
+    return -1;
+  }
+
+  return 0;
+}
+
+function parseHistogramLabel(label: string): number {
+  if (label === '+Inf') {
+    return +Infinity;
+  }
+  return parseInt(label);
+}
+
 /**
  * Convert buckets into linear array of "cards" - objects, represented heatmap elements.
  * @param  {Object} buckets
@@ -444,4 +477,5 @@ export {
   getValueBucketBound,
   isHeatmapDataEqual,
   calculateBucketSize,
+  sortSeriesByLabel,
 };