mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Feat: Angular panels & SeriesData to Table/TimeSeries (#16266)
Similar to how the react panels make sure all data is SeriesData before passing it to the react panels, this makes sure SeriesData is converted to TableData|TimeSeries before passing it to the angular panels. It also changes the typing to encourage using SeriesData for future development
This commit is contained in:
committed by
Torkel Ödegaard
parent
236074ea47
commit
03951c00cb
@@ -2,7 +2,12 @@ import { TimeRange, RawTimeRange } from './time';
|
|||||||
import { PluginMeta } from './plugin';
|
import { PluginMeta } from './plugin';
|
||||||
import { TableData, TimeSeries, SeriesData } from './data';
|
import { TableData, TimeSeries, SeriesData } from './data';
|
||||||
|
|
||||||
export type DataQueryResponseData = TimeSeries | TableData | SeriesData | any;
|
/**
|
||||||
|
* Starting in v6.2 SeriesData can represent both TimeSeries and TableData
|
||||||
|
*/
|
||||||
|
export type LegacyResponseData = TimeSeries | TableData | any;
|
||||||
|
|
||||||
|
export type DataQueryResponseData = SeriesData | LegacyResponseData;
|
||||||
|
|
||||||
export interface DataQueryResponse {
|
export interface DataQueryResponse {
|
||||||
data: DataQueryResponseData[];
|
data: DataQueryResponseData[];
|
||||||
|
|||||||
@@ -1,5 +1,12 @@
|
|||||||
import { toSeriesData, guessFieldTypes, guessFieldTypeFromValue } from './processSeriesData';
|
import {
|
||||||
import { FieldType } from '../types/data';
|
isSeriesData,
|
||||||
|
toLegacyResponseData,
|
||||||
|
isTableData,
|
||||||
|
toSeriesData,
|
||||||
|
guessFieldTypes,
|
||||||
|
guessFieldTypeFromValue,
|
||||||
|
} from './processSeriesData';
|
||||||
|
import { FieldType, TimeSeries } from '../types/data';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
|
||||||
describe('toSeriesData', () => {
|
describe('toSeriesData', () => {
|
||||||
@@ -63,3 +70,33 @@ describe('toSeriesData', () => {
|
|||||||
expect(norm.fields[3].type).toBe(FieldType.time); // based on name
|
expect(norm.fields[3].type).toBe(FieldType.time); // based on name
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('SerisData backwards compatibility', () => {
|
||||||
|
it('converts TimeSeries to series and back again', () => {
|
||||||
|
const timeseries = {
|
||||||
|
target: 'Field Name',
|
||||||
|
datapoints: [[100, 1], [200, 2]],
|
||||||
|
};
|
||||||
|
const series = toSeriesData(timeseries);
|
||||||
|
expect(isSeriesData(timeseries)).toBeFalsy();
|
||||||
|
expect(isSeriesData(series)).toBeTruthy();
|
||||||
|
|
||||||
|
const roundtrip = toLegacyResponseData(series) as TimeSeries;
|
||||||
|
expect(isSeriesData(roundtrip)).toBeFalsy();
|
||||||
|
expect(roundtrip.target).toBe(timeseries.target);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('converts TableData to series and back again', () => {
|
||||||
|
const table = {
|
||||||
|
columns: [{ text: 'a', unit: 'ms' }, { text: 'b', unit: 'zz' }, { text: 'c', unit: 'yy' }],
|
||||||
|
rows: [[100, 1, 'a'], [200, 2, 'a']],
|
||||||
|
};
|
||||||
|
const series = toSeriesData(table);
|
||||||
|
expect(isTableData(table)).toBeTruthy();
|
||||||
|
expect(isSeriesData(series)).toBeTruthy();
|
||||||
|
|
||||||
|
const roundtrip = toLegacyResponseData(series) as TimeSeries;
|
||||||
|
expect(isTableData(roundtrip)).toBeTruthy();
|
||||||
|
expect(roundtrip).toMatchObject(table);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -157,6 +157,32 @@ export const toSeriesData = (data: any): SeriesData => {
|
|||||||
throw new Error('Unsupported data format');
|
throw new Error('Unsupported data format');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const toLegacyResponseData = (series: SeriesData): TimeSeries | TableData => {
|
||||||
|
const { fields, rows } = series;
|
||||||
|
|
||||||
|
if (fields.length === 2) {
|
||||||
|
const type = guessFieldTypeFromTable(series, 1);
|
||||||
|
if (type === FieldType.time) {
|
||||||
|
return {
|
||||||
|
target: fields[0].name || series.name,
|
||||||
|
datapoints: rows,
|
||||||
|
unit: fields[0].unit,
|
||||||
|
} as TimeSeries;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
columns: fields.map(f => {
|
||||||
|
return {
|
||||||
|
text: f.name,
|
||||||
|
filterable: f.filterable,
|
||||||
|
unit: f.unit,
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
rows,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
export function sortSeriesData(data: SeriesData, sortIndex?: number, reverse = false): SeriesData {
|
export function sortSeriesData(data: SeriesData, sortIndex?: number, reverse = false): SeriesData {
|
||||||
if (isNumber(sortIndex)) {
|
if (isNumber(sortIndex)) {
|
||||||
const copy = {
|
const copy = {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { PanelCtrl } from 'app/features/panel/panel_ctrl';
|
|||||||
import { getExploreUrl } from 'app/core/utils/explore';
|
import { getExploreUrl } from 'app/core/utils/explore';
|
||||||
import { applyPanelTimeOverrides, getResolution } from 'app/features/dashboard/utils/panel';
|
import { applyPanelTimeOverrides, getResolution } from 'app/features/dashboard/utils/panel';
|
||||||
import { ContextSrv } from 'app/core/services/context_srv';
|
import { ContextSrv } from 'app/core/services/context_srv';
|
||||||
|
import { toLegacyResponseData, isSeriesData } from '@grafana/ui';
|
||||||
|
|
||||||
class MetricsPanelCtrl extends PanelCtrl {
|
class MetricsPanelCtrl extends PanelCtrl {
|
||||||
scope: any;
|
scope: any;
|
||||||
@@ -188,7 +189,14 @@ class MetricsPanelCtrl extends PanelCtrl {
|
|||||||
result = { data: [] };
|
result = { data: [] };
|
||||||
}
|
}
|
||||||
|
|
||||||
this.events.emit('data-received', result.data);
|
// Make sure the data is TableData | TimeSeries
|
||||||
|
const data = result.data.map(v => {
|
||||||
|
if (isSeriesData(v)) {
|
||||||
|
return toLegacyResponseData(v);
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
});
|
||||||
|
this.events.emit('data-received', data);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleDataStream(stream) {
|
handleDataStream(stream) {
|
||||||
|
|||||||
Reference in New Issue
Block a user