diff --git a/packages/grafana-data/src/dataframe/processDataFrame.test.ts b/packages/grafana-data/src/dataframe/processDataFrame.test.ts index 8038fbe1bdb..bd4b97384bc 100644 --- a/packages/grafana-data/src/dataframe/processDataFrame.test.ts +++ b/packages/grafana-data/src/dataframe/processDataFrame.test.ts @@ -21,16 +21,17 @@ describe('toDataFrame', () => { ], }; let series = toDataFrame(input1); - expect(series.fields[0].name).toBe(input1.target); + expect(series.fields[1].name).toBe(input1.target); const v0 = series.fields[0].values; const v1 = series.fields[1].values; expect(v0.length).toEqual(2); + expect(v0.get(0)).toEqual(1); + expect(v0.get(1)).toEqual(2); + expect(v1.length).toEqual(2); - expect(v0.get(0)).toEqual(100); - expect(v0.get(1)).toEqual(200); - expect(v1.get(0)).toEqual(1); - expect(v1.get(1)).toEqual(2); + expect(v1.get(0)).toEqual(100); + expect(v1.get(1)).toEqual(200); // Should fill a default name if target is empty const input2 = { @@ -42,7 +43,7 @@ describe('toDataFrame', () => { ], }; series = toDataFrame(input2); - expect(series.fields[0].name).toEqual('Value'); + expect(series.fields[1].name).toEqual('Value'); }); it('assumes TimeSeries values are numbers', () => { @@ -54,7 +55,8 @@ describe('toDataFrame', () => { ], }; const data = toDataFrame(input1); - expect(data.fields[0].type).toBe(FieldType.number); + expect(data.fields[0].type).toBe(FieldType.time); + expect(data.fields[1].type).toBe(FieldType.number); }); it('keeps dataFrame unchanged', () => { diff --git a/packages/grafana-data/src/dataframe/processDataFrame.ts b/packages/grafana-data/src/dataframe/processDataFrame.ts index d7182ef2c2b..778a98029be 100644 --- a/packages/grafana-data/src/dataframe/processDataFrame.ts +++ b/packages/grafana-data/src/dataframe/processDataFrame.ts @@ -66,6 +66,12 @@ function convertTimeSeriesToDataFrame(timeSeries: TimeSeries): DataFrame { } const fields = [ + { + name: 'Time', + type: FieldType.time, + config: {}, + values: new ArrayVector(times), + }, { name: timeSeries.target || 'Value', type: FieldType.number, @@ -75,12 +81,6 @@ function convertTimeSeriesToDataFrame(timeSeries: TimeSeries): DataFrame { values: new ArrayVector(values), labels: timeSeries.tags, }, - { - name: 'Time', - type: FieldType.time, - config: {}, - values: new ArrayVector(times), - }, ]; return { @@ -285,23 +285,22 @@ export const toLegacyResponseData = (frame: DataFrame): TimeSeries | TableData = const rowCount = frame.length; const rows: any[][] = []; - 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)); - } - rows.push(row); - } - if (fields.length === 2) { - let type = fields[1].type; - if (!type) { - type = guessFieldTypeForField(fields[1]) || FieldType.other; - } - if (type === FieldType.time) { + const { timeField, timeIndex } = getTimeField(frame); + if (timeField) { + const valueIndex = timeIndex === 0 ? 1 : 0; + + // Make sure it is [value,time] + for (let i = 0; i < rowCount; i++) { + rows.push([ + fields[valueIndex].values.get(i), // value + fields[timeIndex!].values.get(i), // time + ]); + } + return { - alias: fields[0].name || frame.name, - target: fields[0].name || frame.name, + alias: fields[valueIndex].name || frame.name, + target: fields[valueIndex].name || frame.name, datapoints: rows, unit: fields[0].config ? fields[0].config.unit : undefined, refId: frame.refId, @@ -310,6 +309,14 @@ export const toLegacyResponseData = (frame: DataFrame): TimeSeries | TableData = } } + 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)); + } + rows.push(row); + } + if (frame.meta && frame.meta.json) { return { alias: fields[0].name || frame.name, diff --git a/public/app/features/explore/utils/ResultProcessor.test.ts b/public/app/features/explore/utils/ResultProcessor.test.ts index b7fa935baf8..e091e64f2e5 100644 --- a/public/app/features/explore/utils/ResultProcessor.test.ts +++ b/public/app/features/explore/utils/ResultProcessor.test.ts @@ -23,8 +23,8 @@ const testContext = (options: any = {}) => { name: 'A-series', refId: 'A', fields: [ - { name: 'A-series', type: FieldType.number, values: [4, 5, 6] }, { name: 'time', type: FieldType.time, values: [100, 200, 300] }, + { name: 'A-series', type: FieldType.number, values: [4, 5, 6] }, ], }); @@ -100,8 +100,8 @@ describe('ResultProcessor', () => { describe('when calling getGraphResult', () => { it('then it should return correct graph result', () => { const { resultProcessor, dataFrames } = testContext(); - const timeField = dataFrames[0].fields[1]; - const valueField = dataFrames[0].fields[0]; + const timeField = dataFrames[0].fields[0]; + const valueField = dataFrames[0].fields[1]; const theResult = resultProcessor.getGraphResult(); expect(theResult).toEqual([ @@ -164,8 +164,8 @@ describe('ResultProcessor', () => { describe('when calling getLogsResult', () => { it('then it should return correct logs result', () => { const { resultProcessor, dataFrames } = testContext({ mode: ExploreMode.Logs }); - const timeField = dataFrames[0].fields[1]; - const valueField = dataFrames[0].fields[0]; + const timeField = dataFrames[0].fields[0]; + const valueField = dataFrames[0].fields[1]; const logsDataFrame = dataFrames[1]; const theResult = resultProcessor.getLogsResult(); diff --git a/public/app/features/explore/utils/ResultProcessor.ts b/public/app/features/explore/utils/ResultProcessor.ts index a8618a08161..09a604ec5d8 100644 --- a/public/app/features/explore/utils/ResultProcessor.ts +++ b/public/app/features/explore/utils/ResultProcessor.ts @@ -114,7 +114,7 @@ export class ResultProcessor { export function isTimeSeries(frame: DataFrame): boolean { if (frame.fields.length === 2) { - if (frame.fields[1].type === FieldType.time) { + if (frame.fields[0].type === FieldType.time) { return true; } } diff --git a/public/app/plugins/datasource/cloudwatch/specs/datasource.test.ts b/public/app/plugins/datasource/cloudwatch/specs/datasource.test.ts index fd69052b11a..a2e7734990a 100644 --- a/public/app/plugins/datasource/cloudwatch/specs/datasource.test.ts +++ b/public/app/plugins/datasource/cloudwatch/specs/datasource.test.ts @@ -174,7 +174,7 @@ describe('CloudWatchDatasource', () => { it('should return series list', done => { ctx.ds.query(query).then((result: any) => { expect(result.data[0].name).toBe(response.results.A.series[0].name); - expect(result.data[0].fields[0].values.buffer[0]).toBe(response.results.A.series[0].points[0][0]); + expect(result.data[0].fields[1].values.buffer[0]).toBe(response.results.A.series[0].points[0][0]); done(); }); }); @@ -191,8 +191,8 @@ describe('CloudWatchDatasource', () => { response.results['A'].meta.gmdMeta = [{ Expression: `REMOVE_EMPTY(SEARCH('some expression'))`, Period: '300' }]; ctx.ds.query(query).then((result: any) => { expect(result.data[0].name).toBe(response.results.A.series[0].name); - expect(result.data[0].fields[0].config.links[0].title).toBe('View in CloudWatch console'); - expect(decodeURIComponent(result.data[0].fields[0].config.links[0].url)).toContain( + expect(result.data[0].fields[1].config.links[0].title).toBe('View in CloudWatch console'); + expect(decodeURIComponent(result.data[0].fields[1].config.links[0].url)).toContain( `region=us-east-1#metricsV2:graph={"view":"timeSeries","stacked":false,"title":"A","start":"2016-12-31T15:00:00.000Z","end":"2016-12-31T16:00:00.000Z","region":"us-east-1","metrics":[{"expression":"REMOVE_EMPTY(SEARCH(\'some expression\'))"}]}` ); done(); @@ -206,7 +206,7 @@ describe('CloudWatchDatasource', () => { ]; ctx.ds.query(query).then((result: any) => { expect(result.data[0].name).toBe(response.results.A.series[0].name); - expect(result.data[0].fields[0].config.links[0].title).toBe('View in CloudWatch console'); + expect(result.data[0].fields[1].config.links[0].title).toBe('View in CloudWatch console'); expect(decodeURIComponent(result.data[0].fields[0].config.links[0].url)).toContain( `region=us-east-1#metricsV2:graph={"view":"timeSeries","stacked":false,"title":"A","start":"2016-12-31T15:00:00.000Z","end":"2016-12-31T16:00:00.000Z","region":"us-east-1","metrics":[{"expression":"REMOVE_EMPTY(SEARCH(\'first expression\'))"},{"expression":"REMOVE_EMPTY(SEARCH(\'second expression\'))"}]}` ); @@ -218,7 +218,7 @@ describe('CloudWatchDatasource', () => { response.results['A'].meta.gmdMeta = [{ Period: '300' }]; ctx.ds.query(query).then((result: any) => { expect(result.data[0].name).toBe(response.results.A.series[0].name); - expect(result.data[0].fields[0].config.links[0].title).toBe('View in CloudWatch console'); + expect(result.data[0].fields[1].config.links[0].title).toBe('View in CloudWatch console'); expect(decodeURIComponent(result.data[0].fields[0].config.links[0].url)).toContain( `region=us-east-1#metricsV2:graph={\"view\":\"timeSeries\",\"stacked\":false,\"title\":\"A\",\"start\":\"2016-12-31T15:00:00.000Z\",\"end\":\"2016-12-31T16:00:00.000Z\",\"region\":\"us-east-1\",\"metrics\":[[\"AWS/EC2\",\"CPUUtilization\",\"InstanceId\",\"i-12345678\",{\"stat\":\"Average\",\"period\":\"300\"}]]}` ); @@ -230,7 +230,7 @@ describe('CloudWatchDatasource', () => { query.targets[0].expression = 'a * 2'; response.results['A'].meta.searchExpressions = []; ctx.ds.query(query).then((result: any) => { - expect(result.data[0].fields[0].config.links).toBeUndefined(); + expect(result.data[0].fields[1].config.links).toBeUndefined(); done(); }); }); @@ -456,7 +456,7 @@ describe('CloudWatchDatasource', () => { it('should return series list', done => { ctx.ds.query(query).then((result: any) => { expect(result.data[0].name).toBe(response.results.A.series[0].name); - expect(result.data[0].fields[0].values.buffer[0]).toBe(response.results.A.series[0].points[0][0]); + expect(result.data[0].fields[1].values.buffer[0]).toBe(response.results.A.series[0].points[0][0]); done(); }); }); diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/app_insights/app_insights_datasource.test.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/app_insights/app_insights_datasource.test.ts index f06544042fc..2127f8678a7 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/app_insights/app_insights_datasource.test.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/app_insights/app_insights_datasource.test.ts @@ -177,8 +177,8 @@ describe('AppInsightsDatasource', () => { const data = results.data[0] as DataFrame; expect(data.name).toEqual('PrimaryResult'); expect(data.fields[0].values.length).toEqual(1); - expect(data.fields[1].values.get(0)).toEqual(1558278660000); - expect(data.fields[0].values.get(0)).toEqual(2.2075); + expect(data.fields[0].values.get(0)).toEqual(1558278660000); + expect(data.fields[1].values.get(0)).toEqual(2.2075); }); }); }); @@ -220,8 +220,8 @@ describe('AppInsightsDatasource', () => { const data = results.data[0] as DataFrame; expect(data.name).toEqual('paritionA'); expect(data.fields[0].values.length).toEqual(1); - expect(data.fields[1].values.get(0)).toEqual(1558278660000); - expect(data.fields[0].values.get(0)).toEqual(2.2075); + expect(data.fields[0].values.get(0)).toEqual(1558278660000); + expect(data.fields[1].values.get(0)).toEqual(2.2075); }); }); }); @@ -280,8 +280,8 @@ describe('AppInsightsDatasource', () => { expect(results.data.length).toBe(1); const data = results.data[0] as DataFrame; expect(data.name).toEqual('exceptions/server'); - expect(data.fields[1].values.get(0)).toEqual(1558278660000); - expect(data.fields[0].values.get(0)).toEqual(2.2075); + expect(data.fields[0].values.get(0)).toEqual(1558278660000); + expect(data.fields[1].values.get(0)).toEqual(2.2075); }); }); }); @@ -324,10 +324,10 @@ describe('AppInsightsDatasource', () => { const data = results.data[0] as DataFrame; expect(data.name).toEqual('exceptions/server'); expect(data.fields[0].values.length).toEqual(2); - expect(data.fields[1].values.get(0)).toEqual(1504108800000); - expect(data.fields[0].values.get(0)).toEqual(3); - expect(data.fields[1].values.get(1)).toEqual(1504112400000); - expect(data.fields[0].values.get(1)).toEqual(6); + expect(data.fields[0].values.get(0)).toEqual(1504108800000); + expect(data.fields[1].values.get(0)).toEqual(3); + expect(data.fields[0].values.get(1)).toEqual(1504112400000); + expect(data.fields[1].values.get(1)).toEqual(6); }); }); }); @@ -377,18 +377,18 @@ describe('AppInsightsDatasource', () => { expect(results.data.length).toBe(2); let data = results.data[0] as DataFrame; expect(data.name).toEqual('exceptions/server{client/city="Miami"}'); - expect(data.fields[0].values.length).toEqual(2); - expect(data.fields[1].values.get(0)).toEqual(1504108800000); - expect(data.fields[0].values.get(0)).toEqual(10); - expect(data.fields[1].values.get(1)).toEqual(1504112400000); - expect(data.fields[0].values.get(1)).toEqual(20); + expect(data.fields[1].values.length).toEqual(2); + expect(data.fields[0].values.get(0)).toEqual(1504108800000); + expect(data.fields[1].values.get(0)).toEqual(10); + expect(data.fields[0].values.get(1)).toEqual(1504112400000); + expect(data.fields[1].values.get(1)).toEqual(20); data = results.data[1] as DataFrame; expect(data.name).toEqual('exceptions/server{client/city="San Antonio"}'); - expect(data.fields[0].values.length).toEqual(2); - expect(data.fields[1].values.get(0)).toEqual(1504108800000); - expect(data.fields[0].values.get(0)).toEqual(1); - expect(data.fields[1].values.get(1)).toEqual(1504112400000); - expect(data.fields[0].values.get(1)).toEqual(2); + expect(data.fields[1].values.length).toEqual(2); + expect(data.fields[0].values.get(0)).toEqual(1504108800000); + expect(data.fields[1].values.get(0)).toEqual(1); + expect(data.fields[0].values.get(1)).toEqual(1504112400000); + expect(data.fields[1].values.get(1)).toEqual(2); }); }); }); diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/azure_monitor_datasource.test.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/azure_monitor_datasource.test.ts index bdd7a9fa606..5c9cdb03b21 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/azure_monitor_datasource.test.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/azure_monitor_datasource.test.ts @@ -138,10 +138,10 @@ describe('AzureMonitorDatasource', () => { expect(results.data.length).toBe(1); const data = results.data[0] as DataFrame; expect(data.name).toEqual('Percentage CPU'); - expect(data.fields[1].values.get(0)).toEqual(1558278660000); - expect(data.fields[0].values.get(0)).toEqual(2.2075); - expect(data.fields[1].values.get(1)).toEqual(1558278720000); - expect(data.fields[0].values.get(1)).toEqual(2.29); + expect(data.fields[0].values.get(0)).toEqual(1558278660000); + expect(data.fields[1].values.get(0)).toEqual(2.2075); + expect(data.fields[0].values.get(1)).toEqual(1558278720000); + expect(data.fields[1].values.get(1)).toEqual(2.29); }); }); }); diff --git a/public/app/plugins/datasource/graphite/specs/datasource.test.ts b/public/app/plugins/datasource/graphite/specs/datasource.test.ts index c9b56a7bb49..cd0245a1d57 100644 --- a/public/app/plugins/datasource/graphite/specs/datasource.test.ts +++ b/public/app/plugins/datasource/graphite/specs/datasource.test.ts @@ -165,7 +165,7 @@ describe('graphiteDatasource', () => { }); it('should convert to millisecond resolution', () => { - expect(results.data[0].fields[0].values.get(0)).toBe(10); + expect(results.data[0].fields[1].values.get(0)).toBe(10); }); }); diff --git a/public/app/plugins/panel/graph/specs/__snapshots__/data_processor.test.ts.snap b/public/app/plugins/panel/graph/specs/__snapshots__/data_processor.test.ts.snap index 0c2265b9a8f..7b1c0190035 100644 --- a/public/app/plugins/panel/graph/specs/__snapshots__/data_processor.test.ts.snap +++ b/public/app/plugins/panel/graph/specs/__snapshots__/data_processor.test.ts.snap @@ -24,7 +24,7 @@ Array [ 1003, ], ], - "fieldIndex": 0, + "fieldIndex": 1, "hasMsResolution": false, "id": "Value", "label": "Value", @@ -232,7 +232,7 @@ Array [ 1003, ], ], - "fieldIndex": 0, + "fieldIndex": 1, "hasMsResolution": false, "id": "Value", "label": "Value",