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

feat(tablepanel): work on table panel

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

+ 1 - 1
public/app/panels/graph/styleEditor.html

@@ -63,7 +63,7 @@
 <div class="editor-row">
   <div class="section">
 		<h5>Series specific overrides <tip>Regex match example: /server[0-3]/i </tip></h5>
-		<div>
+		<div class="tight-form-container">
 			<div class="tight-form" ng-repeat="override in panel.seriesOverrides" ng-controller="SeriesOverridesCtrl">
 				<ul class="tight-form-list">
 					<li class="tight-form-item">

+ 18 - 11
public/app/panels/table/module.ts

@@ -6,16 +6,13 @@ import _ = require('lodash');
 import moment = require('moment');
 import PanelMeta = require('app/features/panel/panel_meta');
 import TimeSeries = require('app/core/time_series');
-import {TableModel} from './table_model';
-
-var panelDefaults = {
-  targets: [{}],
-};
+import {TableModel, transformers} from './table_model';
 
 export class TablePanelCtrl {
 
   constructor($scope, $rootScope, $q, panelSrv, panelHelper) {
     $scope.ctrl = this;
+    $scope.transformers = transformers;
 
     $scope.panelMeta = new PanelMeta({
       panelName: 'Table',
@@ -27,21 +24,31 @@ export class TablePanelCtrl {
     $scope.panelMeta.addEditorTab('Options', 'app/panels/table/options.html');
     $scope.panelMeta.addEditorTab('Time range', 'app/features/panel/partials/panelTime.html');
 
+    var panelDefaults = {
+      targets: [{}],
+      transform: 'timeseries_to_rows'
+    };
+
     _.defaults($scope.panel, panelDefaults);
 
     $scope.refreshData = function(datasource) {
       panelHelper.updateTimeRange($scope);
 
       return panelHelper.issueMetricQuery($scope, datasource)
-        .then($scope.dataHandler, function(err) {
-          $scope.seriesList = [];
-          $scope.render([]);
-          throw err;
-        });
+      .then($scope.dataHandler, function(err) {
+        $scope.seriesList = [];
+        $scope.render([]);
+        throw err;
+      });
     };
 
     $scope.dataHandler = function(results) {
-      $scope.tableModel = TableModel.transform(results.data, $scope.panel);
+      $scope.dataRaw = results.data;
+      $scope.render();
+    };
+
+    $scope.render = function() {
+      $scope.tableModel = TableModel.transform($scope.dataRaw, $scope.panel);
       panelHelper.broadcastRender($scope, $scope.tableModel);
     };
 

+ 58 - 0
public/app/panels/table/options.html

@@ -0,0 +1,58 @@
+<div class="editor-row">
+	<div class="tight-form-section">
+		<h5>Data Table</h5>
+		<div class="tight-form">
+			<ul class="tight-form-list">
+				<li class="tight-form-item" style="width: 170px">
+					Data to Table Transform
+				</li>
+				<li>
+					<select class="input-xlarge tight-form-input"
+						ng-model="panel.transform"
+						ng-options="k as v.description for (k, v) in transformers"
+						ng-change="render()"></select>
+				</li>
+			</ul>
+			<div class="clearfix"></div>
+		</div>
+	</div>
+</div>
+
+<div class="editor-row">
+	<div class="tight-form-section">
+		<h5>Table Display</h5>
+	</div>
+</div>
+
+<div class="editor-row">
+	<div class="tight-form-section">
+		<h5>Column Styles</h5>
+
+		<div class="tight-form-container">
+			<div class="tight-form" ng-repeat="column panel.columns">
+				<ul class="tight-form-list">
+					<li class="tight-form-item">
+						<i class="fa fa-remove pointer" ng-click="removeSeriesOverride(override)"></i>
+					</li>
+
+					<li class="tight-form-item">
+						alias or regex
+					</li>
+
+					<li>
+						<input type="text" ng-model="override.alias" bs-typeahead="getColumnNames" ng-blur="render()" data-min-length=0 data-items=100 class="input-medium tight-form-input" >
+					</li>
+
+					<li class="dropdown" dropdown-typeahead="overrideMenu" dropdown-typeahead-on-select="setOverride($item, $subItem)">
+					</li>
+				</ul>
+				<div class="clearfix"></div>
+			</div>
+		</div>
+
+		<button class="btn btn-inverse" style="margin-top: 20px" ng-click="addSeriesOverride()">
+			Add column display rule
+		</button>
+	</div>
+</div>
+

+ 43 - 6
public/app/panels/table/specs/table_model_specs.ts

@@ -4,25 +4,62 @@ import {TableModel} from '../table_model';
 
 describe('when getting tableData', () => {
 
-  describe('simple time series', () => {
+  describe('timeseries_to_rows', () => {
     var panel = {
+      transform: 'timeseries_to_rows'
     };
 
-    it ('should return 2 columns', () => {
+    it ('should return 2 rows', () => {
       var data = TableModel.transform([
         {
-          target: 'test',
+          target: 'series1',
+          datapoints: [[12.12, new Date().getTime()]],
+        },
+        {
+          target: 'series2',
           datapoints: [[12.12, new Date().getTime()]],
         }
       ], panel);
 
-      expect(data.columns.length).to.be(2);
-      expect(data.rows.length).to.be(1);
+      expect(data.columns.length).to.be(3);
+      expect(data.rows.length).to.be(2);
 
       expect(data.columns[0].text).to.be('Time');
-      expect(data.columns[1].text).to.be('Value');
+      expect(data.columns[1].text).to.be('Series');
+      expect(data.columns[2].text).to.be('Value');
+      expect(data.rows[0][1]).to.be('series1');
+      expect(data.rows[0][2]).to.be('12.12');
+
+      expect(data.rows[1][1]).to.be('series2');
     });
+  });
 
+  describe('timeseries_to_rows', () => {
+    var panel = {
+      transform: 'timeseries_to_columns'
+    };
+
+    it ('should return 3 columns', () => {
+      var data = TableModel.transform([
+        {
+          target: 'series1',
+          datapoints: [[12.12, new Date().getTime()]],
+        },
+        {
+          target: 'series2',
+          datapoints: [[16.12, new Date().getTime()]],
+        }
+      ], panel);
+
+      expect(data.columns.length).to.be(3);
+      expect(data.rows.length).to.be(1);
+
+      expect(data.columns[0].text).to.be('Time');
+      expect(data.columns[1].text).to.be('series1');
+      expect(data.columns[2].text).to.be('series2');
+      expect(data.rows[0][1]).to.be('12.12');
+      expect(data.rows[0][2]).to.be('16.12');
+    });
   });
 
 });

+ 68 - 13
public/app/panels/table/table_model.ts

@@ -3,21 +3,17 @@
 import moment = require('moment');
 import _ = require('lodash');
 
-export class TableModel {
-  columns: any[];
-  rows: any[];
-
-  static transform(data, panel) {
-    var model = new TableModel();
-
-    if (!data || data.length === 0) {
-      return model;
-    }
+var transformers = {};
 
+transformers['timeseries_to_rows'] = {
+  description: 'Time series to rows',
+  transform: function(data, panel, model) {
     model.columns = [
       {text: 'Time'},
+      {text: 'Series'},
       {text: 'Value'},
     ];
+
     model.rows = [];
 
     for (var i = 0; i < data.length; i++) {
@@ -32,12 +28,71 @@ export class TableModel {
           value = value.toFixed(2);
         }
 
-        model.rows.push([time, value]);
+        model.rows.push([time, series.target, value]);
       }
     }
+  },
+};
 
-    return model;
+transformers['timeseries_to_columns'] = {
+  description: 'Time series to columns',
+  transform: function(data, panel, model) {
+    model.columns = [{text: 'Time'}];
+    model.rows = [];
+
+    var points = {};
+
+    for (var i = 0; i < data.length; i++) {
+      var series = data[i];
+      model.columns.push({text: series.target});
+
+      for (var y = 0; y < series.datapoints.length; y++) {
+        var dp = series.datapoints[y];
+        var time = dp[1];
+        if (!points[time]) {
+          points[time] = {};
+          points[time][i] = [dp[0]];
+        }
+        else {
+          points[time][i] = dp[0];
+        }
+      }
+    }
+
+    for (var time in points) {
+      var point = points[time];
+      var values = [time];
+
+      for (var i = 0; i < data.length; i++) {
+        if (point[i] !== undefined) {
+          values.push(point[i]);
+        }
+      }
+
+      model.rows.push(values);
+    }
   }
-}
+};
+
+export {transformers}
 
+export class TableModel {
+  columns: any[];
+  rows: any[];
 
+  static transform(data, panel) {
+    var model = new TableModel();
+
+    if (!data || data.length === 0) {
+      return model;
+    }
+
+    var transformer = transformers[panel.transform];
+    if (!transformer) {
+      throw {message: 'Transformer ' + panel.transformer + ' not found'};
+    }
+
+    transformer.transform(data, panel, model);
+    return model;
+  }
+}

+ 0 - 1
public/less/panel_table.less

@@ -17,7 +17,6 @@
 
 .gf-table-panel {
   width: 100%;
-  table-layout: fixed;
   border-collapse: collapse;
 }