diff --git a/public/app/core/settings.js b/public/app/core/settings.js
index b7fb6e53c14..e452b59b904 100644
--- a/public/app/core/settings.js
+++ b/public/app/core/settings.js
@@ -10,6 +10,7 @@ function (_) {
window_title_prefix : 'Grafana - ',
panels : {
'graph': { path: 'app/panels/graph', name: 'Graph' },
+ 'table': { path: 'app/panels/table', name: 'Table' },
'singlestat': { path: 'app/panels/singlestat', name: 'Single stat' },
'text': { path: 'app/panels/text', name: 'Text' },
'dashlist': { path: 'app/panels/dashlist', name: 'Dashboard list' },
diff --git a/public/app/core/time_series.js b/public/app/core/time_series.ts
similarity index 77%
rename from public/app/core/time_series.js
rename to public/app/core/time_series.ts
index 9465232c200..30086be622a 100644
--- a/public/app/core/time_series.js
+++ b/public/app/core/time_series.ts
@@ -1,11 +1,46 @@
-define([
- 'lodash',
- 'app/core/utils/kbn'
-],
-function (_, kbn) {
- 'use strict';
+///
- function TimeSeries(opts) {
+import _ = require('lodash');
+import kbn = require('app/core/utils/kbn');
+
+function matchSeriesOverride(aliasOrRegex, seriesAlias) {
+ if (!aliasOrRegex) { return false; }
+
+ if (aliasOrRegex[0] === '/') {
+ var regex = kbn.stringToJsRegex(aliasOrRegex);
+ return seriesAlias.match(regex) != null;
+ }
+
+ return aliasOrRegex === seriesAlias;
+}
+
+function translateFillOption(fill) {
+ return fill === 0 ? 0.001 : fill/10;
+}
+
+class TimeSeries {
+ datapoints: any;
+ id: string;
+ label: string;
+ alias: string;
+ color: string;
+ valueFormater: any;
+ stats: any;
+ legend: boolean;
+ allIsNull: boolean;
+ decimals: number;
+ scaledDecimals: number;
+
+ lines: any;
+ bars: any;
+ points: any;
+ yaxis: any;
+ zindex: any;
+ stack: any;
+ fillBelowTo: any;
+ transform: any;
+
+ constructor(opts) {
this.datapoints = opts.datapoints;
this.label = opts.alias;
this.id = opts.alias;
@@ -16,22 +51,7 @@ function (_, kbn) {
this.legend = true;
}
- function matchSeriesOverride(aliasOrRegex, seriesAlias) {
- if (!aliasOrRegex) { return false; }
-
- if (aliasOrRegex[0] === '/') {
- var regex = kbn.stringToJsRegex(aliasOrRegex);
- return seriesAlias.match(regex) != null;
- }
-
- return aliasOrRegex === seriesAlias;
- }
-
- function translateFillOption(fill) {
- return fill === 0 ? 0.001 : fill/10;
- }
-
- TimeSeries.prototype.applySeriesOverrides = function(overrides) {
+ applySeriesOverrides(overrides) {
this.lines = {};
this.points = {};
this.bars = {};
@@ -64,7 +84,7 @@ function (_, kbn) {
}
};
- TimeSeries.prototype.getFlotPairs = function (fillStyle) {
+ getFlotPairs(fillStyle) {
var result = [];
this.stats.total = 0;
@@ -124,18 +144,17 @@ function (_, kbn) {
}
return result;
- };
+ }
- TimeSeries.prototype.updateLegendValues = function(formater, decimals, scaledDecimals) {
+ updateLegendValues(formater, decimals, scaledDecimals) {
this.valueFormater = formater;
this.decimals = decimals;
this.scaledDecimals = scaledDecimals;
- };
+ }
- TimeSeries.prototype.formatValue = function(value) {
+ formatValue(value) {
return this.valueFormater(value, this.decimals, this.scaledDecimals);
- };
+ }
+}
- return TimeSeries;
-
-});
+export = TimeSeries;
diff --git a/public/app/panels/graph/module.html b/public/app/panels/graph/module.html
index b0793780fa8..9c49c42741d 100644
--- a/public/app/panels/graph/module.html
+++ b/public/app/panels/graph/module.html
@@ -3,10 +3,6 @@
-
-
-
-
No datapoints No datapoints returned from metric query
diff --git a/public/app/panels/table/module.html b/public/app/panels/table/module.html
new file mode 100644
index 00000000000..0463d751817
--- /dev/null
+++ b/public/app/panels/table/module.html
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/public/app/panels/table/module.ts b/public/app/panels/table/module.ts
new file mode 100644
index 00000000000..e65278d44a8
--- /dev/null
+++ b/public/app/panels/table/module.ts
@@ -0,0 +1,136 @@
+///
+
+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');
+
+var panelDefaults = {
+ targets: [{}],
+};
+
+export class TablePanelCtrl {
+
+ constructor($scope, $rootScope, $q, panelSrv, panelHelper) {
+ $scope.ctrl = this;
+
+ $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');
+
+ _.defaults($scope.panel, panelDefaults);
+
+ $scope.refreshData = function(datasource) {
+ var data = {
+ columns: [],
+ rows: [],
+ };
+
+ data.columns.push({text: 'Time'});
+ data.columns.push({text: 'Value'});
+ data.columns.push({text: 'Value2'});
+ data.rows.push([
+ moment().format('LLL'), 17.2, 15.12
+ ]);
+ data.rows.push([
+ moment().format('LLL'), 12.2, 122.3244
+ ]);
+ data.rows.push([
+ moment().format('LLL'), 111.2, 2312.22
+ ]);
+
+ panelHelper.broadcastRender($scope, data);
+
+ // panelHelper.updateTimeRange($scope);
+ //
+ // return panelHelper.issueMetricQuery($scope, datasource)
+ // .then($scope.dataHandler, function(err) {
+ // $scope.seriesList = [];
+ // $scope.render([]);
+ // throw err;
+ // });
+ };
+
+ $scope.dataHandler = function(results) {
+ $scope.seriesList = _.map(results.data, $scope.seriesHandler);
+ panelHelper.broadcastRender($scope, $scope.seriesList);
+ };
+
+ $scope.seriesHandler = function(seriesData, index) {
+ var datapoints = seriesData.datapoints;
+ var alias = seriesData.target;
+ var colorIndex = index % $rootScope.colors.length;
+ var color = $scope.panel.aliasColors[alias] || $rootScope.colors[colorIndex];
+
+ var series = new TimeSeries({
+ datapoints: datapoints,
+ alias: alias,
+ color: color,
+ });
+
+ return series;
+ };
+
+ panelSrv.init($scope);
+ }
+}
+
+export function tablePanelDirective() {
+ 'use strict';
+ return {
+ restrict: 'E',
+ templateUrl: 'app/panels/table/module.html',
+ controller: TablePanelCtrl,
+ link: function(scope, elem) {
+ var data;
+
+ function renderPanel() {
+ var rootDiv = elem.find('.table-panel-container');
+ var tableDiv = $('');
+ var i, y, rowElem, colElem, column, row;
+
+ rowElem = $('
');
+ for (i = 0; i < data.columns.length; i++) {
+ column = data.columns[i];
+ colElem = $('' + column.text + ' | ');
+ rowElem.append(colElem);
+ }
+
+ tableDiv.append(rowElem);
+
+ for (y = 0; y < data.rows.length; y++) {
+ row = data.rows[y];
+ rowElem = $('
|
')
+ for (i = 0; i < data.columns.length; i++) {
+ colElem = $('
' + row[i] + ' | ');
+ rowElem.append(colElem);
+ }
+ tableDiv.append(rowElem);
+ }
+
+ rootDiv.empty();
+ rootDiv.append(tableDiv);
+ }
+
+ scope.$on('render', function(event, renderData) {
+ data = renderData || data;
+ if (!data) {
+ scope.get_data();
+ return;
+ }
+ renderPanel();
+ });
+ }
+ };
+}
+
+angular.module('grafana.directives').directive('grafanaPanelTable', tablePanelDirective);
+