Commit 1e4846d4 by Ryan McKinley Committed by GitHub

Annotation: use DataFrame[] rather than a single DataFrame (#27587)

parent e04e3e7d
......@@ -78,7 +78,7 @@ export interface AnnotationSupport<TQuery extends DataQuery = DataQuery, TAnno =
/**
* When the standard frame > event processing is insufficient, this allows explicit control of the mappings
*/
processEvents?(anno: TAnno, data: DataFrame): AnnotationEvent[] | undefined;
processEvents?(anno: TAnno, data: DataFrame[]): AnnotationEvent[] | undefined;
/**
* Specify a custom QueryEditor for the annotation page. If not specified, the standard one will be used
......
......@@ -24,7 +24,7 @@ import { getTimeSrv } from '../dashboard/services/TimeSrv';
import { Observable, of } from 'rxjs';
import { map } from 'rxjs/operators';
import { AnnotationQueryResponse, AnnotationQueryOptions } from './types';
import { standardAnnotationSupport, singleFrameFromPanelData } from './standardAnnotationSupport';
import { standardAnnotationSupport } from './standardAnnotationSupport';
import { runRequest } from '../dashboard/state/runRequest';
let counter = 100;
......@@ -263,9 +263,8 @@ export function executeAnnotationQuery(
return runRequest(datasource, queryRequest).pipe(
map(panelData => {
const frame = singleFrameFromPanelData(panelData);
const events = frame ? processor.processEvents!(annotation, frame) : [];
return { panelData, frame, events };
const events = panelData.series ? processor.processEvents!(annotation, panelData.series) : [];
return { panelData, events };
})
);
}
......
......@@ -42,7 +42,7 @@ export class AnnotationFieldMapper extends PureComponent<Props, State> {
}
updateFields = () => {
const frame = this.props.response?.frame;
const frame = this.props.response?.panelData?.series[0];
if (frame && frame.fields) {
const fieldNames = frame.fields.map(f => {
const name = getFieldDisplayName(f, frame);
......
......@@ -97,7 +97,7 @@ export default class StandardAnnotationQueryEditor extends PureComponent<Props,
if (running || response?.panelData?.state === LoadingState.Loading || !response) {
text = 'loading...';
} else {
const { events, panelData, frame } = response;
const { events, panelData } = response;
if (panelData?.error) {
rowStyle = 'alert-error';
......@@ -108,6 +108,8 @@ export default class StandardAnnotationQueryEditor extends PureComponent<Props,
icon = 'exclamation-triangle';
text = 'No events found';
} else {
const frame = panelData?.series[0];
text = `${events.length} events (from ${frame?.fields.length} fields)`;
}
}
......
import { toDataFrame, FieldType } from '@grafana/data';
import { getAnnotationsFromFrame } from './standardAnnotationSupport';
import { getAnnotationsFromData } from './standardAnnotationSupport';
describe('DataFrame to annotations', () => {
test('simple conversion', () => {
......@@ -11,7 +11,7 @@ describe('DataFrame to annotations', () => {
],
});
const events = getAnnotationsFromFrame(frame);
const events = getAnnotationsFromData([frame]);
expect(events).toMatchInlineSnapshot(`
Array [
Object {
......@@ -51,7 +51,7 @@ describe('DataFrame to annotations', () => {
],
});
const events = getAnnotationsFromFrame(frame, {
const events = getAnnotationsFromData([frame], {
text: { value: 'bbbbb' },
time: { value: 'time2' },
timeEnd: { value: 'time1' },
......
......@@ -2,7 +2,6 @@ import {
DataFrame,
AnnotationQuery,
AnnotationSupport,
PanelData,
transformDataFrame,
FieldType,
Field,
......@@ -43,20 +42,20 @@ export const standardAnnotationSupport: AnnotationSupport = {
/**
* When the standard frame > event processing is insufficient, this allows explicit control of the mappings
*/
processEvents: (anno: AnnotationQuery, data: DataFrame) => {
return getAnnotationsFromFrame(data, anno.mappings);
processEvents: (anno: AnnotationQuery, data: DataFrame[]) => {
return getAnnotationsFromData(data, anno.mappings);
},
};
/**
* Flatten all panel data into a single frame
*/
export function singleFrameFromPanelData(rsp: PanelData): DataFrame | undefined {
if (!rsp?.series?.length) {
export function singleFrameFromPanelData(data: DataFrame[]): DataFrame | undefined {
if (!data?.length) {
return undefined;
}
if (rsp.series.length === 1) {
return rsp.series[0];
if (data.length === 1) {
return data[0];
}
return transformDataFrame(
......@@ -66,7 +65,7 @@ export function singleFrameFromPanelData(rsp: PanelData): DataFrame | undefined
options: { byField: 'Time' },
},
],
rsp.series
data
)[0];
}
......@@ -108,7 +107,8 @@ export const annotationEventNames: AnnotationFieldInfo[] = [
// { key: 'email' },
];
export function getAnnotationsFromFrame(frame: DataFrame, options?: AnnotationEventMappings): AnnotationEvent[] {
export function getAnnotationsFromData(data: DataFrame[], options?: AnnotationEventMappings): AnnotationEvent[] {
const frame = singleFrameFromPanelData(data);
if (!frame?.length) {
return [];
}
......
import { PanelData, DataFrame, AnnotationEvent, TimeRange } from '@grafana/data';
import { PanelData, AnnotationEvent, TimeRange } from '@grafana/data';
import { DashboardModel, PanelModel } from '../dashboard/state';
export interface AnnotationQueryOptions {
......@@ -9,11 +9,6 @@ export interface AnnotationQueryOptions {
export interface AnnotationQueryResponse {
/**
* All the data flattened to a single frame
*/
frame?: DataFrame;
/**
* The processed annotation events
*/
events?: AnnotationEvent[];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment