Heatmap: hover legend regardless of tooltip state (#47600)

This commit is contained in:
Ryan McKinley
2022-04-13 20:45:30 -07:00
committed by GitHub
parent c266a4ac81
commit 17e44c306c
4 changed files with 24 additions and 10 deletions

View File

@@ -220,7 +220,9 @@ export function calculateHeatmapFromData(frames: DataFrame[], options: HeatmapCa
name: 'count',
type: FieldType.number,
values: new ArrayVector(heat2d.count),
config: {},
config: {
unit: 'short', // always integer
},
},
],
};

View File

@@ -1,5 +1,5 @@
import React, { useEffect, useRef } from 'react';
import { Field, FieldType, formattedValueToString, LinkModel } from '@grafana/data';
import { Field, FieldType, formattedValueToString, getFieldDisplayName, LinkModel } from '@grafana/data';
import { HeatmapHoverEvent } from './utils';
import { BucketLayout, HeatmapData } from './fields';
@@ -26,7 +26,7 @@ export const HeatmapHoverView = ({ data, hover, showHistogram }: Props) => {
const dashboard = getDashboardSrv().getCurrent();
return dashboard?.formatDate(v, tooltipTimeFormat);
}
return `${v}XX`;
return `${v}`;
};
const xVals = xField?.values.toArray();
@@ -45,7 +45,7 @@ export const HeatmapHoverView = ({ data, hover, showHistogram }: Props) => {
if (yField?.display) {
return formattedValueToString(yField.display(v));
}
return `${v}YYY`;
return `${v}`;
};
}
@@ -170,7 +170,9 @@ export const HeatmapHoverView = ({ data, hover, showHistogram }: Props) => {
<div>
Bucket: {yDisp(yBucketMin)} - {yDisp(yBucketMax)}
</div>
<div>Count: {count}</div>
<div>
{getFieldDisplayName(countField!, data.heatmap)}: {count}
</div>
</div>
{links.length > 0 && (
<VerticalGroup>

View File

@@ -1,6 +1,6 @@
import React, { useCallback, useMemo, useRef, useState } from 'react';
import { css } from '@emotion/css';
import { formattedValueToString, GrafanaTheme2, PanelProps, reduceField, ReducerID, TimeRange } from '@grafana/data';
import { GrafanaTheme2, PanelProps, reduceField, ReducerID, TimeRange } from '@grafana/data';
import {
Portal,
UPlotChart,
@@ -82,7 +82,7 @@ export const HeatmapPanel: React.FC<HeatmapPanelProps> = ({
return prepConfig({
dataRef,
theme,
onhover: options.tooltip.show ? onhover : null,
onhover: onhover,
onclick: options.tooltip.show ? onclick : null,
onzoom: (evt) => {
onChangeTimeRange({ from: evt.xMin, to: evt.xMax });
@@ -104,7 +104,6 @@ export const HeatmapPanel: React.FC<HeatmapPanelProps> = ({
const field = info.heatmap.fields[2];
const { min, max } = reduceField({ field, reducers: [ReducerID.min, ReducerID.max] });
const display = field.display ? (v: number) => formattedValueToString(field.display!(v)) : (v: number) => `${v}`;
let hoverValue: number | undefined = undefined;
if (hover && info.heatmap.fields) {
@@ -114,7 +113,7 @@ export const HeatmapPanel: React.FC<HeatmapPanelProps> = ({
return (
<VizLayout.Legend placement="bottom" maxHeight="20%">
<ColorScale hoverValue={hoverValue} colorPalette={palette} min={min} max={max} display={display} />
<ColorScale hoverValue={hoverValue} colorPalette={palette} min={min} max={max} display={info.display} />
</VizLayout.Legend>
);
};
@@ -133,7 +132,7 @@ export const HeatmapPanel: React.FC<HeatmapPanelProps> = ({
)}
</VizLayout>
<Portal>
{hover && (
{hover && options.tooltip.show && (
<VizTooltipContainer
position={{ x: hover.pageX, y: hover.pageY }}
offset={{ x: 10, y: 10 }}

View File

@@ -2,8 +2,10 @@ import {
DataFrame,
DataFrameType,
FieldType,
formattedValueToString,
getDisplayProcessor,
getFieldDisplayName,
getValueFormat,
GrafanaTheme2,
} from '@grafana/data';
import { calculateHeatmapFromData, bucketsToScanlines } from 'app/features/transformers/calculateHeatmap/heatmap';
@@ -29,6 +31,9 @@ export interface HeatmapData {
xLayout?: BucketLayout;
yLayout?: BucketLayout;
// Print a heatmap cell value
display?: (v: number) => string;
// Errors
warning?: string;
}
@@ -84,6 +89,7 @@ const getHeatmapData = (frame: DataFrame, theme: GrafanaTheme2): HeatmapData =>
return { heatmap: frame };
}
// Y field values (display is used in the axis)
if (!frame.fields[1].display) {
frame.fields[1].display = getDisplayProcessor({ field: frame.fields[1], theme });
}
@@ -105,14 +111,19 @@ const getHeatmapData = (frame: DataFrame, theme: GrafanaTheme2): HeatmapData =>
let yBinIncr = ys[1] - ys[0];
let xBinIncr = xs[yBinQty] - xs[0];
// The "count" field
const disp = frame.fields[2].display ?? getValueFormat('short');
return {
heatmap: frame,
xBucketSize: xBinIncr,
yBucketSize: yBinIncr,
xBucketCount: xBinQty,
yBucketCount: yBinQty,
// TODO: improve heuristic
xLayout: frame.fields[0].name === 'xMax' ? BucketLayout.le : BucketLayout.ge,
yLayout: frame.fields[1].name === 'yMax' ? BucketLayout.le : BucketLayout.ge,
display: (v) => formattedValueToString(disp(v)),
};
};