PanelData: include structure revision info and only apply overrides once (#33098)

* calculate schemaRevision in panel query runner

* schema > structureRev

* calculate revision after apply field overrides

* this.state

* don't apply field overrides if the shape is already the same

* check schema revision

* update snapshots
This commit is contained in:
Ryan McKinley
2021-04-20 02:05:50 -07:00
committed by GitHub
parent b3ce655b67
commit dff78561bc
9 changed files with 99 additions and 43 deletions

View File

@@ -12,8 +12,11 @@ import { isSharedDashboardQuery, runSharedRequest } from '../../../plugins/datas
// Types
import {
applyFieldOverrides,
compareArrayValues,
compareDataFrameStructures,
CoreApp,
DataConfigSource,
DataFrame,
DataQuery,
DataQueryRequest,
DataSourceApi,
@@ -72,30 +75,74 @@ export class PanelQueryRunner {
*/
getData(options: GetDataOptions): Observable<PanelData> {
const { withFieldConfig, withTransforms } = options;
let structureRev = 1;
let lastData: DataFrame[] = [];
let processedCount = 0;
let lastConfigRev = -1;
const fastCompare = (a: DataFrame, b: DataFrame) => {
return compareDataFrameStructures(a, b, true);
};
return this.subject.pipe(
this.getTransformationsStream(withTransforms),
map((data: PanelData) => {
let processedData = data;
let sameStructure = false;
if (withFieldConfig) {
if (withFieldConfig && data.series?.length) {
// Apply field defaults and overrides
const fieldConfig = this.dataConfigSource.getFieldOverrideOptions();
const timeZone = data.request?.timezone ?? 'browser';
let fieldConfig = this.dataConfigSource.getFieldOverrideOptions();
let processFields = fieldConfig != null;
if (fieldConfig) {
// If the shape is the same, we can skip field overrides
if (
processFields &&
processedCount > 0 &&
lastData.length &&
lastConfigRev === this.dataConfigSource.configRev
) {
const sameTypes = compareArrayValues(lastData, processedData.series, fastCompare);
if (sameTypes) {
// Keep the previous field config settings
processedData = {
...processedData,
series: lastData.map((frame, frameIndex) => ({
...frame,
fields: frame.fields.map((field, fieldIndex) => ({
...field,
values: data.series[frameIndex].fields[fieldIndex].values,
})),
})),
};
processFields = false;
sameStructure = true;
}
}
if (processFields) {
lastConfigRev = this.dataConfigSource.configRev!;
processedCount++; // results with data
processedData = {
...processedData,
series: applyFieldOverrides({
timeZone: timeZone,
timeZone: data.request?.timezone ?? 'browser',
data: processedData.series,
...fieldConfig,
...fieldConfig!,
}),
};
}
}
return processedData;
if (!sameStructure) {
sameStructure = compareArrayValues(lastData, processedData.series, compareDataFrameStructures);
}
if (!sameStructure) {
structureRev++;
}
lastData = processedData.series;
return { ...processedData, structureRev };
})
);
}

View File

@@ -8,6 +8,8 @@ import {
QueryRunnerOptions,
QueryRunner as QueryRunnerSrv,
LoadingState,
compareArrayValues,
compareDataFrameStructures,
} from '@grafana/data';
import { getTemplateSrv } from '@grafana/runtime';
import { getDatasourceSrv } from 'app/features/plugins/datasource_srv';
@@ -99,7 +101,24 @@ export class QueryRunner implements QueryRunnerSrv {
this.subscription = runRequest(ds, request).subscribe({
next: (data) => {
this.lastResult = preProcessPanelData(data, this.lastResult);
const results = preProcessPanelData(data, this.lastResult);
// Indicate if the structure has changed since the last query
let structureRev = 1;
if (this.lastResult?.structureRev && this.lastResult.series) {
structureRev = this.lastResult.structureRev;
const sameStructure = compareArrayValues(
results.series,
this.lastResult.series,
compareDataFrameStructures
);
if (!sameStructure) {
structureRev++;
}
}
results.structureRev = structureRev;
this.lastResult = results;
// Store preprocessed query results for applying overrides later on in the pipeline
this.subject.next(this.lastResult);
},