Skip to content

Commit 86302bc

Browse files
authored
DataFrame: Deprecate MutableDataFrame (grafana#67569)
1 parent d31d157 commit 86302bc

35 files changed

+266
-219
lines changed

.betterer.results

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,9 @@ exports[`better eslint`] = {
8686
[0, 0, 0, "Do not use any type assertions.", "18"],
8787
[0, 0, 0, "Do not use any type assertions.", "19"],
8888
[0, 0, 0, "Do not use any type assertions.", "20"],
89-
[0, 0, 0, "Do not use any type assertions.", "21"]
89+
[0, 0, 0, "Do not use any type assertions.", "21"],
90+
[0, 0, 0, "Do not use any type assertions.", "22"],
91+
[0, 0, 0, "Do not use any type assertions.", "23"]
9092
],
9193
"packages/grafana-data/src/datetime/datemath.ts:5381": [
9294
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],

packages/grafana-data/src/dataframe/MutableDataFrame.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,16 @@ import { guessFieldTypeFromValue, guessFieldTypeForField, toDataFrameDTO } from
1010
/** @deprecated */
1111
export type MutableField<T = any> = Field<T>;
1212

13+
/** @deprecated */
1314
type MutableVectorCreator = (buffer?: any[]) => any[];
1415

1516
export const MISSING_VALUE = undefined; // Treated as connected in new graph panel
1617

18+
/**
19+
* MutableDataFrame is a complex wrapper around the DataFrame interface
20+
*
21+
* @deprecated use standard DataFrame, or create one with PartialDataFrame
22+
*/
1723
export class MutableDataFrame<T = any> extends FunctionalVector<T> implements DataFrame {
1824
name?: string;
1925
refId?: string;

packages/grafana-data/src/dataframe/processDataFrame.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import { dateTime } from '../datetime/moment_wrapper';
22
import { DataFrameDTO, FieldType, TableData, TimeSeries } from '../types/index';
33

44
import { ArrayDataFrame } from './ArrayDataFrame';
5-
import { MutableDataFrame } from './MutableDataFrame';
65
import {
6+
createDataFrame,
77
guessFieldTypeFromValue,
88
guessFieldTypes,
99
isDataFrame,
@@ -130,7 +130,7 @@ describe('toDataFrame', () => {
130130
});
131131

132132
it('Guess Column Types from series', () => {
133-
const series = new MutableDataFrame({
133+
const series = createDataFrame({
134134
fields: [
135135
{ name: 'A (number)', values: [123, null] },
136136
{ name: 'B (strings)', values: [null, 'Hello'] },

packages/grafana-data/src/dataframe/processDataFrame.ts

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import {
2727

2828
import { arrayToDataFrame } from './ArrayDataFrame';
2929
import { dataFrameFromJSON } from './DataFrameJSON';
30-
import { MutableDataFrame } from './MutableDataFrame';
3130

3231
function convertTableToDataFrame(table: TableData): DataFrame {
3332
const fields = table.columns.map((c) => {
@@ -315,7 +314,7 @@ export function toDataFrame(data: any): DataFrame {
315314
}
316315

317316
// This will convert the array values into Vectors
318-
return new MutableDataFrame(data as DataFrameDTO);
317+
return createDataFrame(data as DataFrameDTO);
319318
}
320319

321320
// Handle legacy docs/json type
@@ -567,3 +566,35 @@ export function preProcessPanelData(data: PanelData, lastResult?: PanelData): Pa
567566
timings: { dataProcessingTime: STOPTIME - STARTTIME },
568567
};
569568
}
569+
570+
export interface PartialDataFrame extends Omit<DataFrame, 'fields' | 'length'> {
571+
fields: Array<Partial<Field>>;
572+
}
573+
574+
export function createDataFrame(input: PartialDataFrame): DataFrame {
575+
let length = 0;
576+
const fields = input.fields.map((p, idx) => {
577+
const { state, ...field } = p;
578+
if (!field.name) {
579+
field.name = `Field ${idx + 1}`;
580+
}
581+
if (!field.config) {
582+
field.config = {};
583+
}
584+
if (!field.values) {
585+
field.values = new Array(length);
586+
} else if (field.values.length > length) {
587+
length = field.values.length;
588+
}
589+
if (!field.type) {
590+
field.type = guessFieldTypeForField(field as Field) ?? FieldType.other;
591+
}
592+
return field as Field;
593+
});
594+
595+
return {
596+
...input,
597+
fields,
598+
length,
599+
};
600+
}

packages/grafana-data/src/field/fieldDisplay.test.ts

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -508,8 +508,25 @@ function createEmptyDisplayOptions(extend = {}): GetFieldDisplayValuesOptions {
508508
}
509509

510510
function createDisplayOptions(extend: Partial<GetFieldDisplayValuesOptions> = {}): GetFieldDisplayValuesOptions {
511-
const options: GetFieldDisplayValuesOptions = {
512-
data: [
511+
const options = merge(
512+
{
513+
replaceVariables: (value: string) => {
514+
return value;
515+
},
516+
reduceOptions: {
517+
calcs: [],
518+
},
519+
fieldConfig: {
520+
overrides: [],
521+
defaults: {},
522+
},
523+
theme: createTheme(),
524+
},
525+
extend
526+
);
527+
528+
if (!options.data?.length) {
529+
options.data = [
513530
toDataFrame({
514531
name: 'Series Name',
515532
fields: [
@@ -518,21 +535,9 @@ function createDisplayOptions(extend: Partial<GetFieldDisplayValuesOptions> = {}
518535
{ name: 'Field 3', values: [2, 4, 6] },
519536
],
520537
}),
521-
],
522-
replaceVariables: (value: string) => {
523-
return value;
524-
},
525-
reduceOptions: {
526-
calcs: [],
527-
},
528-
fieldConfig: {
529-
overrides: [],
530-
defaults: {},
531-
},
532-
theme: createTheme(),
533-
};
534-
535-
return merge(options, extend);
538+
];
539+
}
540+
return options;
536541
}
537542

538543
describe('fixCellTemplateExpressions', () => {

packages/grafana-data/src/field/fieldOverrides.test.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ArrayDataFrame, MutableDataFrame, toDataFrame } from '../dataframe';
1+
import { ArrayDataFrame, createDataFrame, toDataFrame } from '../dataframe';
22
import { rangeUtil } from '../datetime';
33
import { createTheme } from '../themes';
44
import { FieldMatcherID } from '../transformations';
@@ -177,11 +177,11 @@ describe('applyFieldOverrides', () => {
177177
};
178178

179179
describe('given multiple data frames', () => {
180-
const f0 = new MutableDataFrame({
180+
const f0 = createDataFrame({
181181
name: 'A',
182182
fields: [{ name: 'message', type: FieldType.string, values: [10, 20] }],
183183
});
184-
const f1 = new MutableDataFrame({
184+
const f1 = createDataFrame({
185185
name: 'B',
186186
fields: [{ name: 'info', type: FieldType.string, values: [10, 20] }],
187187
});
@@ -676,7 +676,7 @@ describe('getLinksSupplier', () => {
676676
getTimeRangeForUrl: () => ({ from: 'now-7d', to: 'now' }),
677677
});
678678

679-
const f0 = new MutableDataFrame({
679+
const f0 = createDataFrame({
680680
name: 'A',
681681
fields: [
682682
{
@@ -712,7 +712,7 @@ describe('getLinksSupplier', () => {
712712
});
713713

714714
const datasourceUid = '1234';
715-
const f0 = new MutableDataFrame({
715+
const f0 = createDataFrame({
716716
name: 'A',
717717
fields: [
718718
{
@@ -766,7 +766,7 @@ describe('getLinksSupplier', () => {
766766

767767
const datasourceUid = '1234';
768768
const range = rangeUtil.relativeToTimeRange({ from: 600, to: 0 });
769-
const f0 = new MutableDataFrame({
769+
const f0 = createDataFrame({
770770
name: 'A',
771771
fields: [
772772
{
@@ -827,7 +827,7 @@ describe('getLinksSupplier', () => {
827827
it('handles link click handlers', () => {
828828
const onClickSpy = jest.fn();
829829
const replaceSpy = jest.fn();
830-
const f0 = new MutableDataFrame({
830+
const f0 = createDataFrame({
831831
name: 'A',
832832
fields: [
833833
{
@@ -867,7 +867,7 @@ describe('getLinksSupplier', () => {
867867
const replaceSpy = jest.fn().mockReturnValue('url interpolated 10');
868868
const onBuildUrlSpy = jest.fn();
869869

870-
const f0 = new MutableDataFrame({
870+
const f0 = createDataFrame({
871871
name: 'A',
872872
fields: [
873873
{

packages/grafana-data/src/field/getFieldDisplayValuesProxy.test.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { MutableDataFrame, toDataFrame } from '../dataframe';
1+
import { createDataFrame, toDataFrame } from '../dataframe';
22
import { createTheme } from '../themes';
33

44
import { applyFieldOverrides } from './fieldOverrides';
@@ -85,7 +85,7 @@ describe('getFieldDisplayValuesProxy', () => {
8585

8686
it('should use default display processor if display is not defined', () => {
8787
const p = getFieldDisplayValuesProxy({
88-
frame: new MutableDataFrame({ fields: [{ name: 'test', values: [1, 2] }] }),
88+
frame: createDataFrame({ fields: [{ name: 'test', values: [1, 2] }] }),
8989
rowIndex: 0,
9090
});
9191
expect(p.test.text).toBe('1');

packages/grafana-data/src/transformations/fieldReducer.test.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { difference } from 'lodash';
22

3-
import { MutableDataFrame } from '../dataframe/MutableDataFrame';
4-
import { guessFieldTypeFromValue } from '../dataframe/processDataFrame';
3+
import { createDataFrame, guessFieldTypeFromValue } from '../dataframe/processDataFrame';
54
import { Field, FieldType } from '../types/index';
65

76
import { fieldReducers, ReducerID, reduceField } from './fieldReducer';
@@ -24,7 +23,7 @@ function createField<T>(name: string, values?: T[], type?: FieldType): Field<T>
2423
}
2524

2625
describe('Stats Calculators', () => {
27-
const basicTable = new MutableDataFrame({
26+
const basicTable = createDataFrame({
2827
fields: [
2928
{ name: 'a', values: [10, 20] },
3029
{ name: 'b', values: [20, 30] },

packages/grafana-data/src/transformations/transformers/groupingToMatrix.ts

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { map } from 'rxjs/operators';
22

3-
import { MutableDataFrame } from '../../dataframe';
43
import { getFieldDisplayName } from '../../field/fieldState';
54
import { DataFrame, DataTransformerInfo, Field, FieldType, SpecialValue } from '../../types';
65
import { fieldMatchers } from '../matchers';
@@ -75,13 +74,14 @@ export const groupingToMatrixTransformer: DataTransformerInfo<GroupingToMatrixTr
7574
matrixValues[columnName][rowName] = value;
7675
}
7776

78-
const resultFrame = new MutableDataFrame();
79-
80-
resultFrame.addField({
81-
name: rowColumnField,
82-
values: rowValues,
83-
type: FieldType.string,
84-
});
77+
const fields: Field[] = [
78+
{
79+
name: rowColumnField,
80+
values: rowValues,
81+
type: FieldType.string,
82+
config: {},
83+
},
84+
];
8585

8686
for (const columnName of columnValues) {
8787
let values = [];
@@ -98,15 +98,20 @@ export const groupingToMatrixTransformer: DataTransformerInfo<GroupingToMatrixTr
9898
valueField.config = { ...valueField.config, displayNameFromDS: undefined };
9999
}
100100

101-
resultFrame.addField({
101+
fields.push({
102102
name: columnName.toString(),
103103
values: values,
104104
config: valueField.config,
105105
type: valueField.type,
106106
});
107107
}
108108

109-
return [resultFrame];
109+
return [
110+
{
111+
fields,
112+
length: rowValues.length,
113+
},
114+
];
110115
})
111116
),
112117
};

packages/grafana-data/src/utils/flotPairs.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import { MutableDataFrame } from '../dataframe/MutableDataFrame';
1+
import { createDataFrame } from '../dataframe';
22
import { dateTime } from '../datetime/moment_wrapper';
33
import { TimeRange } from '../types/time';
44

55
import { getFlotPairs, getFlotPairsConstant } from './flotPairs';
66

77
describe('getFlotPairs', () => {
8-
const series = new MutableDataFrame({
8+
const series = createDataFrame({
99
fields: [
1010
{ name: 'a', values: [1, 2, 3] },
1111
{ name: 'b', values: [100, 200, 300] },

packages/grafana-runtime/src/utils/DataSourceWithBackend.test.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
DataSourceInstanceSettings,
99
DataSourceJsonData,
1010
DataSourceRef,
11-
MutableDataFrame,
11+
createDataFrame,
1212
} from '@grafana/data';
1313

1414
import {
@@ -240,10 +240,12 @@ describe('DataSourceWithBackend', () => {
240240
let obs = toStreamingDataResponse(rsp, request, standardStreamOptionsProvider);
241241
expect(obs).toBeDefined();
242242

243-
let frame = new MutableDataFrame();
244-
frame.meta = {
245-
channel: 'a/b/c',
246-
};
243+
let frame = createDataFrame({
244+
meta: {
245+
channel: 'a/b/c',
246+
},
247+
fields: [],
248+
});
247249
rsp.data = [frame];
248250
obs = toStreamingDataResponse(rsp, request, standardStreamOptionsProvider);
249251
expect(obs).toBeDefined();

0 commit comments

Comments
 (0)