diff --git a/public/app/core/utils/kbn.js b/public/app/core/utils/kbn.js
index ad2d4c3c422..a8d8c8584df 100644
--- a/public/app/core/utils/kbn.js
+++ b/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?)$'));
diff --git a/public/app/panels/table/controller.ts b/public/app/panels/table/controller.ts
new file mode 100644
index 00000000000..281deec2852
--- /dev/null
+++ b/public/app/panels/table/controller.ts
@@ -0,0 +1,79 @@
+///
+
+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);
+ }
+}
+
diff --git a/public/app/panels/table/module.ts b/public/app/panels/table/module.ts
index deae2aaed89..b804336efc4 100644
--- a/public/app/panels/table/module.ts
+++ b/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 kbn = require('app/core/utils/kbn');
-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();
- };
-
- $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 = $('
');
+ let row = data.rows[y];
+ let rowElem = $('
');
for (var i = 0; i < data.columns.length; i++) {
- var colElem = $('' + row[i] + ' | ');
+ var colValue = formatColumnValue(i, row[i]);
+ let colElem = $(' ' + colValue + ' | ');
rowElem.append(colElem);
}
rowElements.append(rowElem);
diff --git a/public/app/panels/table/options.html b/public/app/panels/table/options.html
index 8c91cc1ecf9..f92241d53ec 100644
--- a/public/app/panels/table/options.html
+++ b/public/app/panels/table/options.html
@@ -1,70 +1,117 @@
-
-
-
-
-
-
+
+
Column Styles
+
+
+
+
+
+
diff --git a/public/app/panels/table/transformers.ts b/public/app/panels/table/transformers.ts
index 41e43fd0815..afca521c942 100644
--- a/public/app/panels/table/transformers.ts
+++ b/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}
+
+
diff --git a/public/less/panel_table.less b/public/less/panel_table.less
index 1a0583f420f..58fb6376f5c 100644
--- a/public/less/panel_table.less
+++ b/public/less/panel_table.less
@@ -18,7 +18,6 @@
.table-panel-footer {
text-align: center;
- background: @grafanaListAccent;
font-size: 80%;
line-height: 2px;