|
@@ -1,5 +1,13 @@
|
|
|
-import { getDatasourceSrv } from 'app/features/plugins/datasource_srv';
|
|
|
|
|
|
|
+// Libraries
|
|
|
|
|
+import cloneDeep from 'lodash/cloneDeep';
|
|
|
import { Subject, Unsubscribable, PartialObserver } from 'rxjs';
|
|
import { Subject, Unsubscribable, PartialObserver } from 'rxjs';
|
|
|
|
|
+
|
|
|
|
|
+// Services & Utils
|
|
|
|
|
+import { getDatasourceSrv } from 'app/features/plugins/datasource_srv';
|
|
|
|
|
+import kbn from 'app/core/utils/kbn';
|
|
|
|
|
+import templateSrv from 'app/features/templating/template_srv';
|
|
|
|
|
+
|
|
|
|
|
+// Components & Types
|
|
|
import {
|
|
import {
|
|
|
guessFieldTypes,
|
|
guessFieldTypes,
|
|
|
toSeriesData,
|
|
toSeriesData,
|
|
@@ -16,10 +24,6 @@ import {
|
|
|
DataSourceApi,
|
|
DataSourceApi,
|
|
|
} from '@grafana/ui';
|
|
} from '@grafana/ui';
|
|
|
|
|
|
|
|
-import cloneDeep from 'lodash/cloneDeep';
|
|
|
|
|
-
|
|
|
|
|
-import kbn from 'app/core/utils/kbn';
|
|
|
|
|
-
|
|
|
|
|
export interface QueryRunnerOptions<TQuery extends DataQuery = DataQuery> {
|
|
export interface QueryRunnerOptions<TQuery extends DataQuery = DataQuery> {
|
|
|
ds?: DataSourceApi<TQuery>; // if they already have the datasource, don't look it up
|
|
ds?: DataSourceApi<TQuery>; // if they already have the datasource, don't look it up
|
|
|
datasource: string | null;
|
|
datasource: string | null;
|
|
@@ -27,11 +31,11 @@ export interface QueryRunnerOptions<TQuery extends DataQuery = DataQuery> {
|
|
|
panelId: number;
|
|
panelId: number;
|
|
|
dashboardId?: number;
|
|
dashboardId?: number;
|
|
|
timezone?: string;
|
|
timezone?: string;
|
|
|
- timeRange?: TimeRange;
|
|
|
|
|
|
|
+ timeRange: TimeRange;
|
|
|
timeInfo?: string; // String description of time range for display
|
|
timeInfo?: string; // String description of time range for display
|
|
|
widthPixels: number;
|
|
widthPixels: number;
|
|
|
- minInterval?: string;
|
|
|
|
|
- maxDataPoints?: number;
|
|
|
|
|
|
|
+ maxDataPoints: number | undefined | null;
|
|
|
|
|
+ minInterval: string | undefined | null;
|
|
|
scopedVars?: ScopedVars;
|
|
scopedVars?: ScopedVars;
|
|
|
cacheTimeout?: string;
|
|
cacheTimeout?: string;
|
|
|
delayStateNotification?: number; // default 100ms.
|
|
delayStateNotification?: number; // default 100ms.
|
|
@@ -98,6 +102,7 @@ export class PanelQueryRunner {
|
|
|
widthPixels,
|
|
widthPixels,
|
|
|
maxDataPoints,
|
|
maxDataPoints,
|
|
|
scopedVars,
|
|
scopedVars,
|
|
|
|
|
+ minInterval,
|
|
|
delayStateNotification,
|
|
delayStateNotification,
|
|
|
} = options;
|
|
} = options;
|
|
|
|
|
|
|
@@ -118,14 +123,12 @@ export class PanelQueryRunner {
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
if (!queries) {
|
|
if (!queries) {
|
|
|
- this.data = {
|
|
|
|
|
|
|
+ return this.publishUpdate({
|
|
|
state: LoadingState.Done,
|
|
state: LoadingState.Done,
|
|
|
series: [], // Clear the data
|
|
series: [], // Clear the data
|
|
|
legacy: [],
|
|
legacy: [],
|
|
|
request,
|
|
request,
|
|
|
- };
|
|
|
|
|
- this.subject.next(this.data);
|
|
|
|
|
- return this.data;
|
|
|
|
|
|
|
+ });
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
let loadingStateTimeoutId = 0;
|
|
let loadingStateTimeoutId = 0;
|
|
@@ -133,8 +136,8 @@ export class PanelQueryRunner {
|
|
|
try {
|
|
try {
|
|
|
const ds = options.ds ? options.ds : await getDatasourceSrv().get(datasource, request.scopedVars);
|
|
const ds = options.ds ? options.ds : await getDatasourceSrv().get(datasource, request.scopedVars);
|
|
|
|
|
|
|
|
- const minInterval = options.minInterval || ds.interval;
|
|
|
|
|
- const norm = kbn.calculateInterval(timeRange, widthPixels, minInterval);
|
|
|
|
|
|
|
+ const lowerIntervalLimit = minInterval ? templateSrv.replace(minInterval, request.scopedVars) : ds.interval;
|
|
|
|
|
+ const norm = kbn.calculateInterval(timeRange, widthPixels, lowerIntervalLimit);
|
|
|
|
|
|
|
|
// make shallow copy of scoped vars,
|
|
// make shallow copy of scoped vars,
|
|
|
// and add built in variables interval and interval_ms
|
|
// and add built in variables interval and interval_ms
|
|
@@ -142,6 +145,7 @@ export class PanelQueryRunner {
|
|
|
__interval: { text: norm.interval, value: norm.interval },
|
|
__interval: { text: norm.interval, value: norm.interval },
|
|
|
__interval_ms: { text: norm.intervalMs, value: norm.intervalMs },
|
|
__interval_ms: { text: norm.intervalMs, value: norm.intervalMs },
|
|
|
});
|
|
});
|
|
|
|
|
+
|
|
|
request.interval = norm.interval;
|
|
request.interval = norm.interval;
|
|
|
request.intervalMs = norm.intervalMs;
|
|
request.intervalMs = norm.intervalMs;
|
|
|
|
|
|
|
@@ -151,7 +155,6 @@ export class PanelQueryRunner {
|
|
|
}, delayStateNotification || 500);
|
|
}, delayStateNotification || 500);
|
|
|
|
|
|
|
|
const resp = await ds.query(request);
|
|
const resp = await ds.query(request);
|
|
|
-
|
|
|
|
|
request.endTime = Date.now();
|
|
request.endTime = Date.now();
|
|
|
|
|
|
|
|
// Make sure the response is in a supported format
|
|
// Make sure the response is in a supported format
|
|
@@ -229,5 +232,6 @@ export function getProcessedSeriesData(results?: any[]): SeriesData[] {
|
|
|
series.push(guessFieldTypes(toSeriesData(r)));
|
|
series.push(guessFieldTypes(toSeriesData(r)));
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
return series;
|
|
return series;
|
|
|
}
|
|
}
|