瀏覽代碼

DataFrame: Fixes to dealing with empty results (#19119)

* DataFrame: Fixes to dealing with empty results

* review feedback fixes
Torkel Ödegaard 6 年之前
父節點
當前提交
e968a2aa86

+ 23 - 2
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: {

+ 6 - 4
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));

+ 3 - 1
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[] },

+ 1 - 1
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,