TimeSeries: Fix memory leak with boolean fields (#112252)

Co-authored-by: Paul Marbach <paul.marbach@grafana.com>
This commit is contained in:
Leon Sorokin
2025-10-10 09:40:02 -05:00
committed by GitHub
co-authored by Paul Marbach
parent e4b981a6c0
commit 248c20a6b6
2 changed files with 39 additions and 3 deletions
@@ -1,4 +1,5 @@
import { createTheme, FieldType, createDataFrame, toDataFrame } from '@grafana/data';
import { LineInterpolation } from '@grafana/ui';
import { prepareGraphableFields } from './utils';
@@ -142,4 +143,39 @@ describe('prepare timeseries graph', () => {
`);
expect(frames![0].length).toEqual(6);
});
describe('boolean fields', () => {
it('will set line interpolation to an appropriate mode for boolean fields', () => {
const df = createDataFrame({
fields: [
{ name: 'time', type: FieldType.time, values: [1, 2, 3] },
{ name: 'a', type: FieldType.boolean, values: [true, false, true] },
],
});
const frames = prepareGraphableFields([df], createTheme());
const field = frames![0].fields.find((f) => f.name === 'a');
expect(field?.config.custom.lineInterpolation).toEqual(LineInterpolation.StepAfter);
expect(df.fields[1].config?.custom).toBeUndefined();
});
// #112194 - mutating this value directly can cause a memory leak
it('does not mutate the underlying lineInterpolation value', () => {
const df = createDataFrame({
fields: [
{ name: 'time', type: FieldType.time, values: [1, 2, 3] },
{
name: 'a',
type: FieldType.boolean,
values: [true, false, true],
config: { custom: { lineInterpolation: LineInterpolation.Smooth } },
},
],
});
const frames = prepareGraphableFields([df], createTheme());
expect(df.fields[1].config.custom.lineInterpolation).toEqual(LineInterpolation.Smooth);
expect(frames![0].fields[1].config.custom.lineInterpolation).toEqual(LineInterpolation.StepAfter);
});
});
});
+3 -3
View File
@@ -176,12 +176,12 @@ export function prepareGraphableFields(
...field.config,
max: 1,
min: 0,
custom,
custom: { ...custom },
};
// smooth and linear do not make sense
if (custom.lineInterpolation !== LineInterpolation.StepBefore) {
custom.lineInterpolation = LineInterpolation.StepAfter;
if (config.custom.lineInterpolation !== LineInterpolation.StepBefore) {
config.custom.lineInterpolation = LineInterpolation.StepAfter;
}
copy = {