瀏覽代碼

feat(tablepanel): work on table panel options

Torkel Ödegaard 10 年之前
父節點
當前提交
60c7bfe9a7

+ 1 - 1
public/app/core/utils/kbn.js

@@ -192,7 +192,7 @@ function($, _) {
 
   kbn.stringToJsRegex = function(str) {
     if (str[0] !== '/') {
-      return new RegExp(str);
+      return new RegExp('^' + str + '$');
     }
 
     var match = str.match(new RegExp('^/(.*?)/(g?i?m?y?)$'));

+ 79 - 0
public/app/panels/table/controller.ts

@@ -0,0 +1,79 @@
+///<reference path="../../headers/common.d.ts" />
+
+import angular = require('angular');
+import _ = require('lodash');
+import moment = require('moment');
+import kbn = require('app/core/utils/kbn');
+import PanelMeta = require('app/features/panel/panel_meta');
+
+import {TableModel} from './table_model';
+import {transformers} from './transformers';
+
+export class TablePanelCtrl {
+
+  constructor($scope, $rootScope, $q, panelSrv, panelHelper) {
+    $scope.ctrl = this;
+    $scope.transformers = transformers;
+    $scope.pageIndex = 0;
+    $scope.unitFormats = kbn.getUnitFormats();
+    $scope.colorModes = {
+      'cell': {text: 'Cell'},
+      'value': {text: 'Value'},
+      'row': {text: 'Row'},
+    };
+
+    $scope.panelMeta = new PanelMeta({
+      panelName: 'Table',
+      editIcon:  "fa fa-table",
+      fullscreen: true,
+      metricsEditor: true,
+    });
+
+    $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',
+      pageSize: 50,
+      showHeader: true,
+      columns: [{
+        pattern: '/.*/',
+        unit: 'short',
+        decimals: 2,
+        colors: ["rgba(245, 54, 54, 0.9)", "rgba(237, 129, 40, 0.89)", "rgba(50, 172, 45, 0.97)"],
+      }],
+    };
+
+    _.defaults($scope.panel, panelDefaults);
+
+    $scope.setUnitFormat = function(column, subItem) {
+      column.unit = subItem.value;
+      $scope.render();
+    };
+
+    $scope.refreshData = function(datasource) {
+      panelHelper.updateTimeRange($scope);
+
+      return panelHelper.issueMetricQuery($scope, datasource)
+      .then($scope.dataHandler, function(err) {
+        $scope.seriesList = [];
+        $scope.render([]);
+        throw err;
+      });
+    };
+
+    $scope.dataHandler = function(results) {
+      $scope.dataRaw = results.data;
+      $scope.render();
+    };
+
+    $scope.render = function() {
+      $scope.table = TableModel.transform($scope.dataRaw, $scope.panel);
+      panelHelper.broadcastRender($scope, $scope.table);
+    };
+
+    panelSrv.init($scope);
+  }
+}
+

+ 46 - 62
public/app/panels/table/module.ts

@@ -3,63 +3,9 @@
 import angular = require('angular');
 import $ = require('jquery');
 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';
-import {transformers} from './transformers';
-
-export class TablePanelCtrl {
-
-  constructor($scope, $rootScope, $q, panelSrv, panelHelper) {
-    $scope.ctrl = this;
-    $scope.transformers = transformers;
-    $scope.pageIndex = 0;
-
-    $scope.panelMeta = new PanelMeta({
-      panelName: 'Table',
-      editIcon:  "fa fa-table",
-      fullscreen: true,
-      metricsEditor: true,
-    });
-
-    $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',
-      pageSize: 50,
-      showHeader: true,
-    };
-
-    _.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;
-      });
-    };
-
-    $scope.dataHandler = function(results) {
-      $scope.dataRaw = results.data;
-      $scope.render();
-    };
+import kbn = require('app/core/utils/kbn');
 
-    $scope.render = function() {
-      $scope.table = TableModel.transform($scope.dataRaw, $scope.panel);
-      panelHelper.broadcastRender($scope, $scope.table);
-    };
-
-    panelSrv.init($scope);
-  }
-}
+import {TablePanelCtrl} from './controller';
 
 export function tablePanelDirective() {
   'use strict';
@@ -70,6 +16,7 @@ export function tablePanelDirective() {
     link: function(scope, elem) {
       var data;
       var panel = scope.panel;
+      var formaters = [];
 
       function getTableHeight() {
         var panelHeight = scope.height || scope.panel.height || scope.row.height;
@@ -93,16 +40,53 @@ export function tablePanelDirective() {
         headElem.appendTo(tableElem);
       }
 
+      function createColumnFormater(style) {
+        return function(v) {
+          if (v === null) {
+            return '-';
+          }
+          if (_.isString(v)) {
+            return v;
+          }
+          let valueFormater = kbn.valueFormats[style.unit];
+          return valueFormater(v, style.decimals);
+        };
+      }
+
+      function formatColumnValue(colIndex, value) {
+        if (formaters[colIndex]) {
+          return formaters[colIndex](value);
+        }
+
+        for (let i = 0; i < panel.columns.length; i++) {
+          let style = panel.columns[i];
+          let column = data.columns[colIndex];
+          var regex = kbn.stringToJsRegex(style.pattern);
+          if (column.text.match(regex)) {
+            formaters[colIndex] = createColumnFormater(style);
+            return formaters[colIndex](value);
+          }
+        }
+
+        formaters[colIndex] = function(v) {
+          return v;
+        };
+
+        return formaters[colIndex](value);
+      }
+
       function appendTableRows(tbodyElem) {
-        var rowElements = $(document.createDocumentFragment());
-        var rowEnd = Math.min(panel.pageSize, data.rows.length);
-        var rowStart = 0;
+        let rowElements = $(document.createDocumentFragment());
+        let rowEnd = Math.min(panel.pageSize, data.rows.length);
+        let rowStart = 0;
+
 
         for (var y = rowStart; y < rowEnd; y++) {
-          var row = data.rows[y];
-          var rowElem = $('<tr></tr>');
+          let row = data.rows[y];
+          let rowElem = $('<tr></tr>');
           for (var i = 0; i < data.columns.length; i++) {
-            var colElem = $('<td>' + row[i] + '</td>');
+            var colValue = formatColumnValue(i, row[i]);
+            let colElem = $('<td> ' + colValue +  '</td>');
             rowElem.append(colElem);
           }
           rowElements.append(rowElem);

+ 94 - 47
public/app/panels/table/options.html

@@ -1,70 +1,117 @@
 <div class="editor-row">
-	<div class="tight-form-section">
+	<div class="section">
 		<h5>Data</h5>
+		<div class="tight-form-container">
+			<div class="tight-form">
+				<ul class="tight-form-list">
+					<li class="tight-form-item" style="width: 170px">
+						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="section">
+		<h5>Table Display</h5>
+		<div class="tight-form-container">
+			<div class="tight-form">
+				<ul class="tight-form-list">
+					<li class="tight-form-item">
+						Pagination (Page size)
+					</li>
+					<li>
+						<input type="text" class="input-small tight-form-input" placeholder="50"
+						empty-to-null ng-model="panel.pageSize" ng-change="render()" ng-model-onblur>
+					</li>
+				</ul>
+				<div class="clearfix"></div>
+			</div>
+		</div>
+	</div>
+</div>
+
+<div class="editor-row" style="margin-top: 20px">
+	<h5>Column Styles</h5>
+
+	<div class="tight-form-container" ng-repeat="column in panel.columns">
 		<div class="tight-form">
 			<ul class="tight-form-list">
-				<li class="tight-form-item" style="width: 170px">
-					To Table Transform
+				<li class="tight-form-item">
+					<i class="fa fa-remove pointer" ng-click="removeColumnStyle(column)"></i>
 				</li>
+
+				<li class="tight-form-item">
+					Name or regex
+				</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>
+					<input type="text" ng-model="column.pattern" bs-typeahead="getColumnNames" ng-blur="render()" data-min-length=0 data-items=100 class="input-medium tight-form-input">
+				</li>
+
+				<li class="tight-form-item">
+					Unit
+				</li>
+				<li class="dropdown"
+					ng-model="column.unit"
+					dropdown-typeahead="unitFormats"
+					dropdown-typeahead-on-select="setUnitFormat(column, $subItem)">
+				</li>
+				<li class="tight-form-item">
+					Decimals
+				</li>
+				<li style="width: 105px">
+					<input type="number" class="input-mini tight-form-input" ng-model="column.decimals" ng-change="render()" ng-model-onblur>
 				</li>
 			</ul>
 			<div class="clearfix"></div>
 		</div>
-	</div>
-</div>
-
-<div class="editor-row">
-	<div class="tight-form-section">
-		<h5>Table Display</h5>
 		<div class="tight-form">
 			<ul class="tight-form-list">
 				<li class="tight-form-item">
-					Pagination (Page size)
+					<i class="fa fa-remove pointer invisible"></i>
+				</li>
+				<li class="tight-form-item">
+					Coloring
 				</li>
 				<li>
-					<input type="text" class="input-small tight-form-input" placeholder="50"
-					empty-to-null ng-model="panel.pageSize" ng-change="render()" ng-model-onblur>
+					<select class="input-small tight-form-input"
+							ng-model="panel.transform"
+							ng-options="k as v.text for (k, v) in colorModes"
+							ng-change="render()"></select>
+				</li>
+				<li class="tight-form-item">
+					Thresholds<tip>Comma seperated values</tip>
+				</li>
+				<li>
+					<input type="text" class="input-small tight-form-input" ng-model="column.thresholds" ng-blur="render()" placeholder="0,50,80"></input>
+				</li>
+				<li class="tight-form-item">
+					Colors
+				</li>
+				<li class="tight-form-item">
+					<spectrum-picker ng-model="column.colors[0]" ng-change="render()" ></spectrum-picker>
+					<spectrum-picker ng-model="column.colors[1]" ng-change="render()" ></spectrum-picker>
+					<spectrum-picker ng-model="column.colors[2]" ng-change="render()" ></spectrum-picker>
+				</li>
+				<li class="tight-form-item last">
+					<a class="pointer" ng-click="invertColorOrder()">invert order</a>
 				</li>
 			</ul>
 			<div class="clearfix"></div>
 		</div>
-	</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>
+
+	<button class="btn btn-inverse" style="margin-top: 20px" ng-click="addSeriesOverride()">
+		Add column display rule
+	</button>
 </div>
 

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

@@ -22,12 +22,6 @@ transformers['timeseries_to_rows'] = {
         var dp = series.datapoints[y];
         var time = moment(dp[1]).format('LLL');
         var value = dp[0];
-        if (value === null) {
-          value = 'null';
-        } else if (_.isNumber(value)) {
-          value = value.toFixed(2);
-        }
-
         model.rows.push([time, series.target, value]);
       }
     }
@@ -67,11 +61,7 @@ transformers['timeseries_to_columns'] = {
 
       for (var i = 0; i < data.length; i++) {
         var value = point[i];
-        if (_.isNumber(value)) {
-          values.push(value.toFixed(2));
-        } else {
-          values.push('-');
-        }
+        values.push(value);
       }
 
       model.rows.push(values);
@@ -88,3 +78,5 @@ transformers['json'] = {
 };
 
 export {transformers}
+
+

+ 0 - 1
public/less/panel_table.less

@@ -18,7 +18,6 @@
 
 .table-panel-footer {
   text-align: center;
-  background: @grafanaListAccent;
   font-size: 80%;
   line-height: 2px;