diff --git a/packages/grafana-data/src/dataframe/index.ts b/packages/grafana-data/src/dataframe/index.ts index 5c505a16670..752b04e580d 100644 --- a/packages/grafana-data/src/dataframe/index.ts +++ b/packages/grafana-data/src/dataframe/index.ts @@ -13,5 +13,6 @@ export { isTimeSeriesFrame, isTimeSeriesFrames, isTimeSeriesField, + getRowUniqueId, } from './utils'; export { StreamingDataFrame, StreamingFrameAction, type StreamingFrameOptions, closestIdx } from './StreamingDataFrame'; diff --git a/packages/grafana-data/src/dataframe/utils.ts b/packages/grafana-data/src/dataframe/utils.ts index ea9dbd34327..4dbdddbf47e 100644 --- a/packages/grafana-data/src/dataframe/utils.ts +++ b/packages/grafana-data/src/dataframe/utils.ts @@ -86,3 +86,15 @@ export function anySeriesWithTimeField(data: DataFrame[]) { export function hasTimeField(data: DataFrame): boolean { return data.fields.some((field) => field.type === FieldType.time); } + +/** + * Get row id based on the meta.uniqueRowIdFields attribute. + * @param dataFrame + * @param rowIndex + */ +export function getRowUniqueId(dataFrame: DataFrame, rowIndex: number) { + if (dataFrame.meta?.uniqueRowIdFields === undefined) { + return undefined; + } + return dataFrame.meta.uniqueRowIdFields.map((fieldIndex) => dataFrame.fields[fieldIndex].values[rowIndex]).join('-'); +} diff --git a/packages/grafana-data/src/types/data.ts b/packages/grafana-data/src/types/data.ts index b8130318bcf..8c88d3c99eb 100644 --- a/packages/grafana-data/src/types/data.ts +++ b/packages/grafana-data/src/types/data.ts @@ -33,6 +33,7 @@ export const preferredVisualizationTypes = [ export type PreferredVisualisationType = (typeof preferredVisualizationTypes)[number]; /** + * Should be kept in sync with https://github.com/grafana/grafana-plugin-sdk-go/blob/main/data/frame_meta.go * @public */ export interface QueryResultMeta { @@ -107,6 +108,14 @@ export interface QueryResultMeta { limit?: number; // used by log models and loki json?: boolean; // used to keep track of old json doc values instant?: boolean; + + /** + * Array of field indices which values create a unique id for each row. Ideally this should be globally unique ID + * but that isn't guarantied. Should help with keeping track and deduplicating rows in visualizations, especially + * with streaming data with frequent updates. + * Example: TraceID in Tempo, table name + primary key in SQL + */ + uniqueRowIdFields?: number[]; } export interface QueryResultMetaStat extends FieldConfig {