mirror of
https://github.com/grafana/grafana.git
synced 2024-12-02 05:29:42 -06:00
Heatmap (new): exemplars tooltip stub (#48795)
This commit is contained in:
parent
2d6ab03e4f
commit
42098a7a27
@ -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 (
|
||||
<ul>
|
||||
{ids.map((id) => (
|
||||
<li key={id}>
|
||||
<pre>{JSON.stringify(view.get(id), null, 2)}</pre>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
|
||||
// should not show anything... but for debugging
|
||||
return <div>EXEMPLARS: {JSON.stringify(exemplarIndex)}</div>;
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div>
|
||||
@ -175,6 +199,7 @@ export const HeatmapHoverView = ({ data, hover, showHistogram }: Props) => {
|
||||
{getFieldDisplayName(countField!, data.heatmap)}: {count}
|
||||
</div>
|
||||
</div>
|
||||
{renderExemplars()}
|
||||
{links.length > 0 && (
|
||||
<VerticalGroup>
|
||||
{links.map((link, i) => (
|
||||
|
@ -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: {
|
||||
|
@ -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<number | string | null>;
|
||||
|
||||
@ -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<Field | undefined> => {
|
||||
@ -100,7 +100,7 @@ const getHeatmapFields = (dataFrame: DataFrame): Array<Field | undefined> => {
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user