Heatmap: Use displayName to test if numeric bucket fields (#71407)
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
import {
|
import {
|
||||||
|
cacheFieldDisplayNames,
|
||||||
createDataFrame,
|
createDataFrame,
|
||||||
DataFrame,
|
DataFrame,
|
||||||
DataQueryRequest,
|
DataQueryRequest,
|
||||||
@@ -7,7 +8,7 @@ import {
|
|||||||
PreferredVisualisationType,
|
PreferredVisualisationType,
|
||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
|
|
||||||
import { parseSampleValue, transform, transformDFToTable, transformV2 } from './result_transformer';
|
import { parseSampleValue, sortSeriesByLabel, transform, transformDFToTable, transformV2 } from './result_transformer';
|
||||||
import { PromQuery } from './types';
|
import { PromQuery } from './types';
|
||||||
|
|
||||||
jest.mock('@grafana/runtime', () => ({
|
jest.mock('@grafana/runtime', () => ({
|
||||||
@@ -83,6 +84,54 @@ describe('Prometheus Result Transformer', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('sortSeriesByLabel() should use frame.fields[1].state?.displayName when available', () => {
|
||||||
|
let frames = [
|
||||||
|
createDataFrame({
|
||||||
|
refId: 'A',
|
||||||
|
fields: [
|
||||||
|
{ name: 'Time', type: FieldType.time, values: [1, 2, 3] },
|
||||||
|
{
|
||||||
|
name: 'Value',
|
||||||
|
type: FieldType.number,
|
||||||
|
values: [4, 5, 6],
|
||||||
|
config: {
|
||||||
|
displayNameFromDS: '2',
|
||||||
|
},
|
||||||
|
labels: {
|
||||||
|
offset_days: '2',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
createDataFrame({
|
||||||
|
refId: 'A',
|
||||||
|
fields: [
|
||||||
|
{ name: 'Time', type: FieldType.time, values: [1, 2, 3] },
|
||||||
|
{
|
||||||
|
name: 'Value',
|
||||||
|
type: FieldType.number,
|
||||||
|
values: [7, 8, 9],
|
||||||
|
config: {
|
||||||
|
displayNameFromDS: '1',
|
||||||
|
},
|
||||||
|
labels: {
|
||||||
|
offset_days: '1',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
];
|
||||||
|
|
||||||
|
it('sorts by displayNameFromDS', () => {
|
||||||
|
cacheFieldDisplayNames(frames);
|
||||||
|
|
||||||
|
let sorted = frames.slice().sort(sortSeriesByLabel);
|
||||||
|
|
||||||
|
expect(sorted[0]).toEqual(frames[1]);
|
||||||
|
expect(sorted[1]).toEqual(frames[0]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('transformV2', () => {
|
describe('transformV2', () => {
|
||||||
it('results with time_series format should be enriched with preferredVisualisationType', () => {
|
it('results with time_series format should be enriched with preferredVisualisationType', () => {
|
||||||
const request = {
|
const request = {
|
||||||
|
|||||||
@@ -673,10 +673,13 @@ export function sortSeriesByLabel(s1: DataFrame, s2: DataFrame): number {
|
|||||||
let le1, le2;
|
let le1, le2;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// fail if not integer. might happen with bad queries
|
// the state.displayName conditions are here because we also use this sorting util fn
|
||||||
le1 = parseSampleValue(s1.name ?? s1.fields[1].name);
|
// in panels where isHeatmapResult was false but we still want to sort numerically-named
|
||||||
le2 = parseSampleValue(s2.name ?? s2.fields[1].name);
|
// fields after the full unique displayName is cached in field state
|
||||||
|
le1 = parseSampleValue(s1.fields[1].state?.displayName ?? s1.name ?? s1.fields[1].name);
|
||||||
|
le2 = parseSampleValue(s2.fields[1].state?.displayName ?? s2.name ?? s2.fields[1].name);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
// fail if not integer. might happen with bad queries
|
||||||
console.error(err);
|
console.error(err);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import {
|
import {
|
||||||
|
cacheFieldDisplayNames,
|
||||||
DataFrame,
|
DataFrame,
|
||||||
DataFrameType,
|
DataFrameType,
|
||||||
Field,
|
Field,
|
||||||
@@ -73,6 +74,8 @@ export function prepareHeatmapData(
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cacheFieldDisplayNames(frames);
|
||||||
|
|
||||||
const exemplars = annotations?.find((f) => f.name === 'exemplar');
|
const exemplars = annotations?.find((f) => f.name === 'exemplar');
|
||||||
|
|
||||||
if (getFieldLinks) {
|
if (getFieldLinks) {
|
||||||
@@ -109,7 +112,7 @@ export function prepareHeatmapData(
|
|||||||
if (!rowsHeatmap) {
|
if (!rowsHeatmap) {
|
||||||
if (frames.length > 1) {
|
if (frames.length > 1) {
|
||||||
let allNamesNumeric = frames.every(
|
let allNamesNumeric = frames.every(
|
||||||
(frame) => !Number.isNaN(parseSampleValue(frame.name ?? frame.fields[1].name))
|
(frame) => !Number.isNaN(parseSampleValue(frame.fields[1].state?.displayName!))
|
||||||
);
|
);
|
||||||
|
|
||||||
if (allNamesNumeric) {
|
if (allNamesNumeric) {
|
||||||
@@ -124,10 +127,10 @@ export function prepareHeatmapData(
|
|||||||
} else {
|
} else {
|
||||||
let frame = frames[0];
|
let frame = frames[0];
|
||||||
let numberFields = frame.fields.filter((field) => field.type === FieldType.number);
|
let numberFields = frame.fields.filter((field) => field.type === FieldType.number);
|
||||||
let allNamesNumeric = numberFields.every((field) => !Number.isNaN(parseSampleValue(field.name)));
|
let allNamesNumeric = numberFields.every((field) => !Number.isNaN(parseSampleValue(field.state?.displayName!)));
|
||||||
|
|
||||||
if (allNamesNumeric) {
|
if (allNamesNumeric) {
|
||||||
numberFields.sort((a, b) => parseSampleValue(a.name) - parseSampleValue(b.name));
|
numberFields.sort((a, b) => parseSampleValue(a.state?.displayName!) - parseSampleValue(b.state?.displayName!));
|
||||||
|
|
||||||
rowsHeatmap = {
|
rowsHeatmap = {
|
||||||
...frame,
|
...frame,
|
||||||
|
|||||||
Reference in New Issue
Block a user