Commit 93851a9a by Torkel Ödegaard

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

parent 00a479de
......@@ -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)">
......
......@@ -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);
}
};
}
......
......@@ -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', () => {
......
......@@ -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) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment