diff --git a/public/app/plugins/panel/heatmap-new/HeatmapHoverView.tsx b/public/app/plugins/panel/heatmap-new/HeatmapHoverView.tsx index 97b5d3419bf..842f1b2febc 100644 --- a/public/app/plugins/panel/heatmap-new/HeatmapHoverView.tsx +++ b/public/app/plugins/panel/heatmap-new/HeatmapHoverView.tsx @@ -1,6 +1,6 @@ import React, { useEffect, useRef } from 'react'; -import { Field, FieldType, formattedValueToString, getFieldDisplayName, LinkModel } from '@grafana/data'; +import { DataFrameView, Field, FieldType, formattedValueToString, getFieldDisplayName, LinkModel } from '@grafana/data'; import { LinkButton, VerticalGroup } from '@grafana/ui'; import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv'; @@ -153,6 +153,30 @@ export const HeatmapHoverView = ({ data, hover, showHistogram }: Props) => { [hover.index] ); + const renderExemplars = () => { + const exemplarIndex = data.exemplarsMappings?.lookup; //?.[hover.index]; + if (!exemplarIndex || !data.exemplars) { + return null; + } + + const ids = exemplarIndex[hover.index]; + if (ids) { + const view = new DataFrameView(data.exemplars); + return ( + + ); + } + + // should not show anything... but for debugging + return
EXEMPLARS: {JSON.stringify(exemplarIndex)}
; + }; + return ( <>
@@ -175,6 +199,7 @@ export const HeatmapHoverView = ({ data, hover, showHistogram }: Props) => { {getFieldDisplayName(countField!, data.heatmap)}: {count}
+ {renderExemplars()} {links.length > 0 && ( {links.map((link, i) => ( diff --git a/public/app/plugins/panel/heatmap-new/fields.test.ts b/public/app/plugins/panel/heatmap-new/fields.test.ts index ce8be363bfa..96dd7889592 100644 --- a/public/app/plugins/panel/heatmap-new/fields.test.ts +++ b/public/app/plugins/panel/heatmap-new/fields.test.ts @@ -1,6 +1,6 @@ import { createTheme, ArrayVector, DataFrameType, FieldType } from '@grafana/data'; -import { BucketLayout, getAnnotationMapping, HEATMAP_NOT_SCANLINES_ERROR } from './fields'; +import { BucketLayout, getExemplarsMapping, HEATMAP_NOT_SCANLINES_ERROR } from './fields'; import { PanelOptions } from './models.gen'; const theme = createTheme(); @@ -16,7 +16,7 @@ describe('Heatmap data', () => { describe('creating a heatmap data mapping', () => { describe('generates a simple data mapping with orderly data', () => { - const mapping = getAnnotationMapping( + const mapping = getExemplarsMapping( { heatmap: { name: 'test', @@ -139,7 +139,7 @@ describe('creating a heatmap data mapping', () => { // In this case, we are just finding proper values, but don't care if a values // exists in the bucket in the original data or not. Therefore, we should see // a value mapped into the second mapping bucket containing the value '8'. - const mapping = getAnnotationMapping(heatmap, rawData); + const mapping = getExemplarsMapping(heatmap, rawData); expect(mapping.lookup.length).toEqual(3); expect(mapping.lookup[0]).toEqual([1, 4]); expect(mapping.lookup[1]).toEqual([8]); @@ -148,7 +148,7 @@ describe('creating a heatmap data mapping', () => { }); describe('Handles a larger data set that will not fill all buckets', () => { - const mapping = getAnnotationMapping( + const mapping = getExemplarsMapping( { heatmap: { name: 'test', @@ -276,7 +276,7 @@ describe('creating a heatmap data mapping', () => { it('Will not process heatmap buckets', () => { expect(() => - getAnnotationMapping( + getExemplarsMapping( { ...heatmap, heatmap: { @@ -291,7 +291,7 @@ describe('creating a heatmap data mapping', () => { ).toThrow(HEATMAP_NOT_SCANLINES_ERROR); expect(() => - getAnnotationMapping( + getExemplarsMapping( { ...heatmap, heatmap: { @@ -306,7 +306,7 @@ describe('creating a heatmap data mapping', () => { ).toThrow(HEATMAP_NOT_SCANLINES_ERROR); expect(() => - getAnnotationMapping( + getExemplarsMapping( { ...heatmap, heatmap: { diff --git a/public/app/plugins/panel/heatmap-new/fields.ts b/public/app/plugins/panel/heatmap-new/fields.ts index 145ad8443fe..433954fdff6 100644 --- a/public/app/plugins/panel/heatmap-new/fields.ts +++ b/public/app/plugins/panel/heatmap-new/fields.ts @@ -32,8 +32,8 @@ export const HEATMAP_NOT_SCANLINES_ERROR = 'A calculated heatmap was expected, b export interface HeatmapData { // List of heatmap frames heatmap?: DataFrame; - annotations?: DataFrame; - annotationMappings?: HeatmapDataMapping; + exemplars?: DataFrame; + exemplarsMappings?: HeatmapDataMapping; yAxisValues?: Array; @@ -61,17 +61,17 @@ export function prepareHeatmapData(data: PanelData, options: PanelOptions, theme const { source } = options; - const annotations = data.annotations?.[0]; // TODO: Maybe join on time with frames + const exemplars = data.annotations?.find((f) => f.name === 'exemplar'); if (source === HeatmapSourceMode.Calculate) { // TODO, check for error etc - return getHeatmapData(calculateHeatmapFromData(frames, options.heatmap ?? {}), annotations, theme); + return getHeatmapData(calculateHeatmapFromData(frames, options.heatmap ?? {}), exemplars, theme); } // Find a well defined heatmap let scanlinesHeatmap = frames.find((f) => f.meta?.type === DataFrameType.HeatmapScanlines); if (scanlinesHeatmap) { - return getHeatmapData(scanlinesHeatmap, annotations, theme); + return getHeatmapData(scanlinesHeatmap, exemplars, theme); } let bucketsHeatmap = frames.find((f) => f.meta?.type === DataFrameType.HeatmapBuckets); @@ -80,16 +80,16 @@ export function prepareHeatmapData(data: PanelData, options: PanelOptions, theme yAxisValues: frames[0].fields.flatMap((field) => field.type === FieldType.number ? getFieldDisplayName(field) : [] ), - ...getHeatmapData(bucketsToScanlines(bucketsHeatmap), annotations, theme), + ...getHeatmapData(bucketsToScanlines(bucketsHeatmap), exemplars, theme), }; } if (source === HeatmapSourceMode.Data) { - return getHeatmapData(bucketsToScanlines(frames[0]), annotations, theme); + return getHeatmapData(bucketsToScanlines(frames[0]), exemplars, theme); } // TODO, check for error etc - return getHeatmapData(calculateHeatmapFromData(frames, options.heatmap ?? {}), annotations, theme); + return getHeatmapData(calculateHeatmapFromData(frames, options.heatmap ?? {}), exemplars, theme); } const getHeatmapFields = (dataFrame: DataFrame): Array => { @@ -100,7 +100,7 @@ const getHeatmapFields = (dataFrame: DataFrame): Array => { return [xField, yField, countField]; }; -export const getAnnotationMapping = (heatmapData: HeatmapData, rawData: DataFrame): HeatmapDataMapping => { +export const getExemplarsMapping = (heatmapData: HeatmapData, rawData: DataFrame): HeatmapDataMapping => { if (heatmapData.heatmap?.meta?.type !== DataFrameType.HeatmapScanlines) { throw HEATMAP_NOT_SCANLINES_ERROR; } @@ -152,7 +152,7 @@ export const getAnnotationMapping = (heatmapData: HeatmapData, rawData: DataFram return mapping; }; -const getHeatmapData = (frame: DataFrame, annotations: DataFrame | undefined, theme: GrafanaTheme2): HeatmapData => { +const getHeatmapData = (frame: DataFrame, exemplars: DataFrame | undefined, theme: GrafanaTheme2): HeatmapData => { if (frame.meta?.type !== DataFrameType.HeatmapScanlines) { return { warning: 'Expected heatmap scanlines format', @@ -190,7 +190,7 @@ const getHeatmapData = (frame: DataFrame, annotations: DataFrame | undefined, th const disp = frame.fields[2].display ?? getValueFormat('short'); const data: HeatmapData = { heatmap: frame, - annotations, + exemplars, xBucketSize: xBinIncr, yBucketSize: yBinIncr, xBucketCount: xBinQty, @@ -203,8 +203,9 @@ const getHeatmapData = (frame: DataFrame, annotations: DataFrame | undefined, th display: (v) => formattedValueToString(disp(v)), }; - if (annotations) { - data.annotationMappings = getAnnotationMapping(data, annotations); + if (exemplars) { + data.exemplarsMappings = getExemplarsMapping(data, exemplars); + console.log('EXEMPLARS', data.exemplarsMappings, data.exemplars); } return data;