Просмотр исходного кода

feat(tablepanel): added time series aggregations transform mode, #3219

Torkel Ödegaard 10 лет назад
Родитель
Сommit
93851a9a0f

+ 2 - 2
public/app/panels/table/editor.html

@@ -16,7 +16,7 @@
 				</ul>
 				<div class="clearfix"></div>
 			</div>
-			<div class="tight-form" ng-if="panel.transform === 'json'">
+			<div class="tight-form" ng-if="showColumnOptions">
 				<ul class="tight-form-list">
 					<li class="tight-form-item" style="width: 140px">
 						Columns
@@ -24,7 +24,7 @@
 					<li class="tight-form-item" ng-repeat="column in panel.columns">
 						<i class="pointer fa fa-remove" ng-click="removeColumn(column)"></i>
 						<span>
-							{{column.name}}
+							{{column.text}}
 						</span>
 					</li>
 					<li class="dropdown" dropdown-typeahead="columnsMenu" dropdown-typeahead-on-select="addColumn($item, $subItem)">

+ 8 - 28
public/app/panels/table/editor.ts

@@ -37,48 +37,26 @@ export function tablePanelEditor() {
       ];
 
       scope.updateColumnsMenu = function(data) {
-        scope.columnsMenu = [];
-        if (!data || data.length === 0) {
-          return;
-        }
-
-        var names =  {};
-        for (var i = 0; i < data.length; i++) {
-          var series = data[i];
-          if (series.type !== 'docs') {
-            continue;
-          }
-
-          for (var y = 0; y < series.datapoints.length; y++) {
-            var doc = series.datapoints[y];
-            for (var propName in doc) {
-              names[propName] = true;
-            }
-          }
-        }
-
-        _.each(names, function(value, key) {
-          scope.columnsMenu.push({text: key});
-        });
-      };
-
-      scope.updateColumnsMenu(scope.dataRaw);
+        scope.columnsMenu = transformers[scope.panel.transform].getColumns(data);
+        scope.showColumnOptions = scope.columnsMenu.length > 0;
+     };
 
       scope.$on('render', function(event, table, rawData) {
         scope.updateColumnsMenu(rawData);
       });
 
       scope.addColumn = function(menuItem) {
-        scope.panel.columns.push({name: menuItem.text});
+        scope.panel.columns.push({text: menuItem.text, value: menuItem.value});
         scope.render();
       };
 
       scope.transformChanged = function() {
+        scope.updateColumnsMenu();
         scope.render();
       };
 
       scope.removeColumn = function(column) {
-        scope.panel.column = _.without(scope.panel.column, column);
+        scope.panel.columns = _.without(scope.panel.columns, column);
         scope.render();
       };
 
@@ -114,6 +92,8 @@ export function tablePanelEditor() {
           return col.text;
         });
       };
+
+      scope.updateColumnsMenu(scope.dataRaw);
     }
   };
 }

+ 20 - 20
public/app/panels/table/specs/transformers_specs.ts

@@ -39,7 +39,7 @@ describe('when transforming time series table', () => {
       it('should return 3 rows', () => {
         expect(table.columns.length).to.be(3);
         expect(table.columns[0].text).to.be('Time');
-        expect(table.columns[1].text).to.be('Series');
+        expect(table.columns[1].text).to.be('Metric');
         expect(table.columns[2].text).to.be('Value');
       });
     });
@@ -71,36 +71,36 @@ describe('when transforming time series table', () => {
       });
     });
 
-    describe('timeseries_to_summaries', () => {
+    describe('timeseries_aggregations', () => {
       var panel = {
-        transform: 'timeseries_to_summaries',
+        transform: 'timeseries_aggregations',
         sort: {col: 0, desc: true},
+        columns: [{text: 'Max', value: 'max'}, {text: 'Min', value: 'min'}]
       };
 
       beforeEach(() => {
         table = TableModel.transform(timeSeries, panel);
       });
 
-      // it('should return 2 rows', () => {
-      //   expect(table.rows.length).to.be(2);
-      //   expect(table.rows[0][0]).to.be('series1');
-      //   expect(table.rows[0][1]).to.be('Min');
-      //   expect(table.rows[1][0]).to.be('series2');
-      // });
-      //
-      // it('should return 2 columns', () => {
-      //   expect(table.columns.length).to.be(3);
-      //   expect(table.columns[0].text).to.be('Series');
-      //   expect(table.columns[1].text).to.be('Min');
-      //   expect(table.columns[2].text).to.be('Value');
-      // });
-    });
+      it('should return 2 rows', () => {
+        expect(table.rows.length).to.be(2);
+        expect(table.rows[0][0]).to.be('series1');
+        expect(table.rows[0][1]).to.be(14.44);
+        expect(table.rows[0][2]).to.be(12.12);
+      });
 
+      it('should return 2 columns', () => {
+        expect(table.columns.length).to.be(3);
+        expect(table.columns[0].text).to.be('Metric');
+        expect(table.columns[1].text).to.be('Max');
+        expect(table.columns[2].text).to.be('Min');
+      });
+    });
 
     describe('JSON Data', () => {
       var panel = {
         transform: 'json',
-        columns: [{name: 'timestamp'}, {name: 'message'}]
+        columns: [{text: 'Timestamp', value: 'timestamp'}, {text: 'Message', value: 'message'}]
       };
       var rawData = [
         {
@@ -120,8 +120,8 @@ describe('when transforming time series table', () => {
 
       it ('should return 2 columns', () => {
         expect(table.columns.length).to.be(2);
-        expect(table.columns[0].text).to.be('timestamp');
-        expect(table.columns[1].text).to.be('message');
+        expect(table.columns[0].text).to.be('Timestamp');
+        expect(table.columns[1].text).to.be('Message');
       });
 
       it ('should return 2 rows', () => {

+ 76 - 3
public/app/panels/table/transformers.ts

@@ -2,15 +2,19 @@
 
 import moment = require('moment');
 import _ = require('lodash');
+import TimeSeries = require('app/core/time_series');
 
 var transformers = {};
 
 transformers['timeseries_to_rows'] = {
   description: 'Time series to rows',
+  getColumns: function() {
+    return [];
+  },
   transform: function(data, panel, model) {
     model.columns = [
       {text: 'Time', type: 'date'},
-      {text: 'Series'},
+      {text: 'Metric'},
       {text: 'Value'},
     ];
 
@@ -26,6 +30,9 @@ transformers['timeseries_to_rows'] = {
 
 transformers['timeseries_to_columns'] = {
   description: 'Time series to columns',
+  getColumns: function() {
+    return [];
+  },
   transform: function(data, panel, model) {
     model.columns.push({text: 'Time', type: 'date'});
 
@@ -64,8 +71,50 @@ transformers['timeseries_to_columns'] = {
   }
 };
 
+transformers['timeseries_aggregations'] = {
+  description: 'Time series aggregations',
+  getColumns: function() {
+    return [
+      {text: 'Avg', value: 'avg'},
+      {text: 'Min', value: 'min'},
+      {text: 'Max', value: 'max'},
+    ];
+  },
+  transform: function(data, panel, model) {
+    var i, y;
+    model.columns.push({text: 'Metric'});
+
+    if (panel.columns.length === 0) {
+      panel.columns.push({text: 'Avg', value: 'avg'});
+    }
+
+    for (i = 0; i < panel.columns.length; i++) {
+      model.columns.push({text: panel.columns[i].text});
+    }
+
+    for (i = 0; i < data.length; i++) {
+      var series = new TimeSeries({
+        datapoints: data[i].datapoints,
+        alias: data[i].target,
+      });
+
+      series.getFlotPairs('connected');
+      var cells = [series.alias];
+
+      for (y = 0; y < panel.columns.length; y++) {
+        cells.push(series.stats[panel.columns[y].value]);
+      }
+
+      model.rows.push(cells);
+    }
+  }
+};
+
 transformers['annotations'] = {
   description: 'Annotations',
+  getColumns: function() {
+    return [];
+  },
   transform: function(data, panel, model) {
     model.columns.push({text: 'Time', type: 'date'});
     model.columns.push({text: 'Title'});
@@ -85,10 +134,34 @@ transformers['annotations'] = {
 
 transformers['json'] = {
   description: 'JSON Data',
+  getColumns: function(data) {
+    if (!data || data.length === 0) {
+      return [];
+    }
+
+    var names: any = {};
+    for (var i = 0; i < data.length; i++) {
+      var series = data[i];
+      if (series.type === 'docs') {
+        continue;
+      }
+
+      for (var y = 0; y < series.datapoints.length; y++) {
+        var doc = series.datapoints[y];
+        for (var propName in doc) {
+          names[propName] = true;
+        }
+      }
+    }
+
+    return _.map(names, function(value, key) {
+      return {text: key, value: key};
+    });
+  },
   transform: function(data, panel, model) {
     var i, y, z;
     for (i = 0; i < panel.columns.length; i++) {
-      model.columns.push({text: panel.columns[i].name});
+      model.columns.push({text: panel.columns[i].text});
     }
 
     if (model.columns.length === 0) {
@@ -102,7 +175,7 @@ transformers['json'] = {
         var dp = series.datapoints[y];
         var values = [];
         for (z = 0; z < panel.columns.length; z++) {
-          values.push(dp[panel.columns[z].name]);
+          values.push(dp[panel.columns[z].value]);
         }
 
         if (values.length === 0) {