diff --git a/packages/grafana-data/src/utils/processDataFrame.test.ts b/packages/grafana-data/src/utils/processDataFrame.test.ts index babf7f5ee6c..a71dff6e9ca 100644 --- a/packages/grafana-data/src/utils/processDataFrame.test.ts +++ b/packages/grafana-data/src/utils/processDataFrame.test.ts @@ -106,7 +106,7 @@ describe('toDataFrame', () => { }); describe('SerisData backwards compatibility', () => { - it('converts TimeSeries to series and back again', () => { + it('can convert TimeSeries to series and back again', () => { const timeseries = { target: 'Field Name', datapoints: [[100, 1], [200, 2]], @@ -120,6 +120,17 @@ describe('SerisData backwards compatibility', () => { expect(roundtrip.target).toBe(timeseries.target); }); + it('can convert empty table to DataFrame then back to legacy', () => { + const table = { + columns: [], + rows: [], + }; + + const series = toDataFrame(table); + const roundtrip = toLegacyResponseData(series) as TableData; + expect(roundtrip.columns.length).toBe(0); + }); + it('converts TableData to series and back again', () => { const table = { columns: [{ text: 'a', unit: 'ms' }, { text: 'b', unit: 'zz' }, { text: 'c', unit: 'yy' }], @@ -135,7 +146,17 @@ describe('SerisData backwards compatibility', () => { expect(roundtrip).toMatchObject(table); }); - it('converts DataFrame to TableData to series and back again', () => { + it('can convert empty TableData to DataFrame', () => { + const table = { + columns: [], + rows: [], + }; + + const series = toDataFrame(table); + expect(series.fields.length).toBe(0); + }); + + it('can convert DataFrame to TableData to series and back again', () => { const json: DataFrameDTO = { refId: 'Z', meta: { diff --git a/packages/grafana-data/src/utils/processDataFrame.ts b/packages/grafana-data/src/utils/processDataFrame.ts index 542fb950721..e88bb54ddec 100644 --- a/packages/grafana-data/src/utils/processDataFrame.ts +++ b/packages/grafana-data/src/utils/processDataFrame.ts @@ -32,12 +32,13 @@ function convertTableToDataFrame(table: TableData): DataFrame { type: FieldType.other, }; }); - // Fill in the field values + for (const row of table.rows) { for (let i = 0; i < fields.length; i++) { fields[i].values.buffer.push(row[i]); } } + for (const f of fields) { const t = guessFieldTypeForField(f); if (t) { @@ -50,7 +51,7 @@ function convertTableToDataFrame(table: TableData): DataFrame { refId: table.refId, meta: table.meta, name: table.name, - length: fields[0].values.length, + length: table.rows.length, }; } @@ -258,9 +259,10 @@ export const toDataFrame = (data: any): DataFrame => { export const toLegacyResponseData = (frame: DataFrame): TimeSeries | TableData => { const { fields } = frame; - const length = fields[0].values.length; + const rowCount = frame.length; const rows: any[][] = []; - for (let i = 0; i < length; i++) { + + for (let i = 0; i < rowCount; i++) { const row: any[] = []; for (let j = 0; j < fields.length; j++) { row.push(fields[j].values.get(i)); diff --git a/public/app/features/explore/utils/ResultProcessor.test.ts b/public/app/features/explore/utils/ResultProcessor.test.ts index 08fcea79c2b..30860f5d772 100644 --- a/public/app/features/explore/utils/ResultProcessor.test.ts +++ b/public/app/features/explore/utils/ResultProcessor.test.ts @@ -38,9 +38,11 @@ const testContext = (options: any = {}) => { ], }); + const emptyTable = toDataFrame({ name: 'empty-table', refId: 'A', fields: [] }); + const defaultOptions = { mode: ExploreMode.Metrics, - dataFrames: [timeSeries, table], + dataFrames: [timeSeries, table, emptyTable], graphResult: [] as TimeSeries[], tableResult: new TableModel(), logsResult: { hasUniqueLabels: false, rows: [] as LogRowModel[] }, diff --git a/public/app/features/explore/utils/ResultProcessor.ts b/public/app/features/explore/utils/ResultProcessor.ts index 453fc540cbf..4e62d44ba22 100644 --- a/public/app/features/explore/utils/ResultProcessor.ts +++ b/public/app/features/explore/utils/ResultProcessor.ts @@ -45,7 +45,7 @@ export class ResultProcessor { const tables = onlyTables.map(frame => { const { fields } = frame; const fieldCount = fields.length; - const rowCount = fields[0].values.length; + const rowCount = frame.length; const columns = fields.map(field => ({ text: field.name,