mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
FieldValues: Use simple array in transformations and grafana/data (#66702)
Co-authored-by: Leon Sorokin <leeoniya@gmail.com>
This commit is contained in:
@@ -32,7 +32,7 @@ export class DataFrameView<T = any> extends FunctionalVector<T> {
|
||||
}
|
||||
|
||||
fields[field.name] = field;
|
||||
const getter = () => field.values.get(this.index);
|
||||
const getter = () => field.values.get(this.index); // .get() to support all Vector types
|
||||
|
||||
if (!(obj as any).hasOwnProperty(field.name)) {
|
||||
Object.defineProperty(obj, field.name, {
|
||||
|
||||
@@ -92,7 +92,7 @@ describe('FieldCache', () => {
|
||||
it('should get the first field with a duplicate name', () => {
|
||||
const field = fieldCache.getFieldByName('value');
|
||||
expect(field!.name).toEqual('value');
|
||||
expect(field!.values.toArray()).toEqual([1, 2, 3]);
|
||||
expect(field!.values).toEqual([1, 2, 3]);
|
||||
});
|
||||
|
||||
it('should return index of the field', () => {
|
||||
|
||||
@@ -29,11 +29,11 @@ export const getColumnFromDimension = (dimension: Dimension, column: number) =>
|
||||
};
|
||||
|
||||
export const getValueFromDimension = (dimension: Dimension, column: number, row: number) => {
|
||||
return dimension.columns[column].values.get(row);
|
||||
return dimension.columns[column].values[row];
|
||||
};
|
||||
|
||||
export const getAllValuesFromDimension = (dimension: Dimension, column: number, row: number) => {
|
||||
return dimension.columns.map((c) => c.values.get(row));
|
||||
return dimension.columns.map((c) => c.values[row]);
|
||||
};
|
||||
|
||||
export const getDimensionByName = (dimensions: Dimensions, name: string) => dimensions[name];
|
||||
|
||||
@@ -198,7 +198,7 @@ describe('toDataFrame', () => {
|
||||
},
|
||||
};
|
||||
const dataFrame = toDataFrame(msg);
|
||||
expect(dataFrame.fields.map((f) => ({ [f.name]: f.values.toArray() }))).toMatchInlineSnapshot(`
|
||||
expect(dataFrame.fields.map((f) => ({ [f.name]: f.values }))).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"First": [
|
||||
@@ -366,14 +366,14 @@ describe('sorted DataFrame', () => {
|
||||
it('Should sort numbers', () => {
|
||||
const sorted = sortDataFrame(frame, 0, true);
|
||||
expect(sorted.length).toEqual(3);
|
||||
expect(sorted.fields[0].values.toArray()).toEqual([3, 2, 1]);
|
||||
expect(sorted.fields[1].values.toArray()).toEqual(['c', 'b', 'a']);
|
||||
expect(sorted.fields[0].values).toEqual([3, 2, 1]);
|
||||
expect(sorted.fields[1].values).toEqual(['c', 'b', 'a']);
|
||||
});
|
||||
|
||||
it('Should sort strings', () => {
|
||||
const sorted = sortDataFrame(frame, 1, true);
|
||||
expect(sorted.length).toEqual(3);
|
||||
expect(sorted.fields[0].values.toArray()).toEqual([3, 2, 1]);
|
||||
expect(sorted.fields[1].values.toArray()).toEqual(['c', 'b', 'a']);
|
||||
expect(sorted.fields[0].values).toEqual([3, 2, 1]);
|
||||
expect(sorted.fields[1].values).toEqual(['c', 'b', 'a']);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -261,7 +261,7 @@ export function guessFieldTypeForField(field: Field): FieldType | undefined {
|
||||
|
||||
// 2. Check the first non-null value
|
||||
for (let i = 0; i < field.values.length; i++) {
|
||||
const v = field.values.get(i);
|
||||
const v = field.values[i];
|
||||
if (v != null) {
|
||||
return guessFieldTypeFromValue(v);
|
||||
}
|
||||
@@ -362,8 +362,8 @@ export const toLegacyResponseData = (frame: DataFrame): TimeSeries | TableData =
|
||||
// Make sure it is [value,time]
|
||||
for (let i = 0; i < rowCount; i++) {
|
||||
rows.push([
|
||||
valueField.values.get(i), // value
|
||||
timeField.values.get(i), // time
|
||||
valueField.values[i], // value
|
||||
timeField.values[i], // time
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -381,7 +381,7 @@ export const toLegacyResponseData = (frame: DataFrame): TimeSeries | TableData =
|
||||
for (let i = 0; i < rowCount; i++) {
|
||||
const row: any[] = [];
|
||||
for (let j = 0; j < fields.length; j++) {
|
||||
row.push(fields[j].values.get(i));
|
||||
row.push(fields[j].values[i]);
|
||||
}
|
||||
rows.push(row);
|
||||
}
|
||||
@@ -463,7 +463,7 @@ export function reverseDataFrame(data: DataFrame): DataFrame {
|
||||
export function getDataFrameRow(data: DataFrame, row: number): any[] {
|
||||
const values: any[] = [];
|
||||
for (const field of data.fields) {
|
||||
values.push(field.values.get(row));
|
||||
values.push(field.values[row]);
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
@@ -53,8 +53,8 @@ export function getDisplayProcessor(options?: DisplayProcessorOptions): DisplayP
|
||||
unit = `dateTimeAsSystem`;
|
||||
hasDateUnit = true;
|
||||
if (field.values && field.values.length > 1) {
|
||||
let start = field.values.get(0);
|
||||
let end = field.values.get(field.values.length - 1);
|
||||
let start = field.values[0];
|
||||
let end = field.values[field.values.length - 1];
|
||||
if (typeof start === 'string') {
|
||||
start = dateTimeParse(start).unix();
|
||||
end = dateTimeParse(end).unix();
|
||||
|
||||
@@ -18,7 +18,7 @@ export const fieldIndexComparer = (field: Field, reverse = false): IndexComparer
|
||||
case FieldType.boolean:
|
||||
return booleanIndexComparer(values, reverse);
|
||||
case FieldType.time:
|
||||
if (typeof field.values.get(0) === 'number') {
|
||||
if (typeof field.values[0] === 'number') {
|
||||
return timestampIndexComparer(values, reverse);
|
||||
}
|
||||
return timeIndexComparer(values, reverse);
|
||||
@@ -80,39 +80,38 @@ const falsyComparer = (a: unknown, b: unknown): number => {
|
||||
};
|
||||
|
||||
const timestampIndexComparer = (values: Vector<number>, reverse: boolean): IndexComparer => {
|
||||
let vals = values.toArray();
|
||||
let mult = reverse ? -1 : 1;
|
||||
return (a: number, b: number): number => mult * (vals[a] - vals[b]);
|
||||
return (a: number, b: number): number => mult * (values[a] - values[b]);
|
||||
};
|
||||
|
||||
const timeIndexComparer = (values: Vector<unknown>, reverse: boolean): IndexComparer => {
|
||||
return (a: number, b: number): number => {
|
||||
const vA = values.get(a);
|
||||
const vB = values.get(b);
|
||||
const vA = values[a];
|
||||
const vB = values[b];
|
||||
return reverse ? timeComparer(vB, vA) : timeComparer(vA, vB);
|
||||
};
|
||||
};
|
||||
|
||||
const booleanIndexComparer = (values: Vector<boolean>, reverse: boolean): IndexComparer => {
|
||||
return (a: number, b: number): number => {
|
||||
const vA = values.get(a);
|
||||
const vB = values.get(b);
|
||||
const vA = values[a];
|
||||
const vB = values[b];
|
||||
return reverse ? booleanComparer(vB, vA) : booleanComparer(vA, vB);
|
||||
};
|
||||
};
|
||||
|
||||
const numericIndexComparer = (values: Vector<number>, reverse: boolean): IndexComparer => {
|
||||
return (a: number, b: number): number => {
|
||||
const vA = values.get(a);
|
||||
const vB = values.get(b);
|
||||
const vA = values[a];
|
||||
const vB = values[b];
|
||||
return reverse ? numericComparer(vB, vA) : numericComparer(vA, vB);
|
||||
};
|
||||
};
|
||||
|
||||
const stringIndexComparer = (values: Vector<string>, reverse: boolean): IndexComparer => {
|
||||
return (a: number, b: number): number => {
|
||||
const vA = values.get(a);
|
||||
const vB = values.get(b);
|
||||
const vA = values[a];
|
||||
const vB = values[b];
|
||||
return reverse ? stringComparer(vB, vA) : stringComparer(vA, vB);
|
||||
};
|
||||
};
|
||||
|
||||
@@ -140,7 +140,7 @@ export const getFieldDisplayValues = (options: GetFieldDisplayValuesOptions): Fi
|
||||
field.state = setIndexForPaletteColor(field, values.length);
|
||||
|
||||
const scopedVars = getFieldScopedVarsWithDataContexAndRowIndex(field, j);
|
||||
const displayValue = display(field.values.get(j));
|
||||
const displayValue = display(field.values[j]);
|
||||
const rowName = getSmartDisplayNameForRow(dataFrame, field, j, replaceVariables, scopedVars);
|
||||
const overrideColor = lookupRowColorFromOverride(rowName, options.fieldConfig, theme);
|
||||
|
||||
@@ -254,7 +254,7 @@ function getSmartDisplayNameForRow(
|
||||
}
|
||||
|
||||
if (otherField.type === FieldType.string) {
|
||||
const value = otherField.values.get(rowIndex) ?? '';
|
||||
const value = otherField.values[rowIndex] ?? '';
|
||||
const mappedValue = otherField.display ? otherField.display(value).text : value;
|
||||
if (mappedValue.length > 0) {
|
||||
parts.push(mappedValue);
|
||||
|
||||
@@ -935,7 +935,7 @@ describe('applyRawFieldOverrides', () => {
|
||||
|
||||
const getDisplayValue = (frames: DataFrame[], frameIndex: number, fieldIndex: number) => {
|
||||
const field = frames[frameIndex].fields[fieldIndex];
|
||||
const value = field.values.get(0);
|
||||
const value = field.values[0];
|
||||
return field.display!(value);
|
||||
};
|
||||
|
||||
|
||||
@@ -252,7 +252,7 @@ export const fieldReducers = new Registry<FieldReducerInfo>(() => [
|
||||
name: 'All values',
|
||||
description: 'Returns an array with all values',
|
||||
standard: false,
|
||||
reduce: (field: Field) => ({ allValues: field.values.toArray() }),
|
||||
reduce: (field: Field) => ({ allValues: field.values }),
|
||||
},
|
||||
{
|
||||
id: ReducerID.uniqueValues,
|
||||
@@ -260,7 +260,7 @@ export const fieldReducers = new Registry<FieldReducerInfo>(() => [
|
||||
description: 'Returns an array with all unique values',
|
||||
standard: false,
|
||||
reduce: (field: Field) => ({
|
||||
uniqueValues: [...new Set(field.values.toArray())],
|
||||
uniqueValues: [...new Set(field.values)],
|
||||
}),
|
||||
},
|
||||
]);
|
||||
@@ -290,13 +290,13 @@ export function doStandardCalcs(field: Field, ignoreNulls: boolean, nullAsZero:
|
||||
previousDeltaUp: true,
|
||||
};
|
||||
|
||||
const data = field.values;
|
||||
calcs.count = ignoreNulls ? data.length : data.toArray().filter((val) => val != null).length;
|
||||
const data = field.values.toArray(); // toArray() ensures we handle all vector types
|
||||
calcs.count = ignoreNulls ? data.length : data.filter((val) => val != null).length;
|
||||
|
||||
const isNumberField = field.type === FieldType.number || FieldType.time;
|
||||
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
let currentValue = data.get(i);
|
||||
let currentValue = data[i];
|
||||
|
||||
if (i === 0) {
|
||||
calcs.first = currentValue;
|
||||
@@ -404,13 +404,13 @@ export function doStandardCalcs(field: Field, ignoreNulls: boolean, nullAsZero:
|
||||
}
|
||||
|
||||
function calculateFirst(field: Field, ignoreNulls: boolean, nullAsZero: boolean): FieldCalcs {
|
||||
return { first: field.values.get(0) };
|
||||
return { first: field.values[0] };
|
||||
}
|
||||
|
||||
function calculateFirstNotNull(field: Field, ignoreNulls: boolean, nullAsZero: boolean): FieldCalcs {
|
||||
const data = field.values;
|
||||
for (let idx = 0; idx < data.length; idx++) {
|
||||
const v = data.get(idx);
|
||||
const v = data[idx];
|
||||
if (v != null && v !== undefined) {
|
||||
return { firstNotNull: v };
|
||||
}
|
||||
@@ -420,14 +420,14 @@ function calculateFirstNotNull(field: Field, ignoreNulls: boolean, nullAsZero: b
|
||||
|
||||
function calculateLast(field: Field, ignoreNulls: boolean, nullAsZero: boolean): FieldCalcs {
|
||||
const data = field.values;
|
||||
return { last: data.get(data.length - 1) };
|
||||
return { last: data[data.length - 1] };
|
||||
}
|
||||
|
||||
function calculateLastNotNull(field: Field, ignoreNulls: boolean, nullAsZero: boolean): FieldCalcs {
|
||||
const data = field.values;
|
||||
let idx = data.length - 1;
|
||||
while (idx >= 0) {
|
||||
const v = data.get(idx--);
|
||||
const v = data[idx--];
|
||||
if (v != null && v !== undefined) {
|
||||
return { lastNotNull: v };
|
||||
}
|
||||
@@ -447,7 +447,7 @@ function calculateStdDev(field: Field, ignoreNulls: boolean, nullAsZero: boolean
|
||||
let runningNonNullCount = 0;
|
||||
const data = field.values;
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
const currentValue = data.get(i);
|
||||
const currentValue = data[i];
|
||||
if (currentValue != null) {
|
||||
runningNonNullCount++;
|
||||
let _oldMean = runningMean;
|
||||
@@ -468,7 +468,7 @@ function calculateChangeCount(field: Field, ignoreNulls: boolean, nullAsZero: bo
|
||||
let first = true;
|
||||
let last = null;
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
let currentValue = data.get(i);
|
||||
let currentValue = data[i];
|
||||
if (currentValue === null) {
|
||||
if (ignoreNulls) {
|
||||
continue;
|
||||
@@ -491,7 +491,7 @@ function calculateDistinctCount(field: Field, ignoreNulls: boolean, nullAsZero:
|
||||
const data = field.values;
|
||||
const distinct = new Set();
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
let currentValue = data.get(i);
|
||||
let currentValue = data[i];
|
||||
if (currentValue === null) {
|
||||
if (ignoreNulls) {
|
||||
continue;
|
||||
|
||||
@@ -85,7 +85,7 @@ describe('transformDataFrame', () => {
|
||||
const processed = received[0];
|
||||
expect(processed[0].length).toEqual(1);
|
||||
expect(processed[0].fields.length).toEqual(1);
|
||||
expect(processed[0].fields[0].values.get(0)).toEqual(3);
|
||||
expect(processed[0].fields[0].values[0]).toEqual(3);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -112,7 +112,7 @@ describe('transformDataFrame', () => {
|
||||
const processed = received[0];
|
||||
expect(processed[0].length).toEqual(1);
|
||||
expect(processed[0].fields.length).toEqual(2);
|
||||
expect(processed[0].fields[0].values.get(0)).toEqual('temperature');
|
||||
expect(processed[0].fields[0].values[0]).toEqual('temperature');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -142,7 +142,7 @@ describe('transformDataFrame', () => {
|
||||
|
||||
// Only apply A
|
||||
await expect(transformDataFrame(cfg, [frameA, frameB])).toEmitValuesWith((received) => {
|
||||
const processed = received[0].map((v) => v.fields[0].values.toArray());
|
||||
const processed = received[0].map((v) => v.fields[0].values);
|
||||
expect(processed).toBeTruthy();
|
||||
expect(processed).toMatchObject([[5], [7, 8]]);
|
||||
});
|
||||
@@ -150,7 +150,7 @@ describe('transformDataFrame', () => {
|
||||
// Only apply to B
|
||||
cfg[0].filter.options = 'B';
|
||||
await expect(transformDataFrame(cfg, [frameA, frameB])).toEmitValuesWith((received) => {
|
||||
const processed = received[0].map((v) => v.fields[0].values.toArray());
|
||||
const processed = received[0].map((v) => v.fields[0].values);
|
||||
expect(processed).toBeTruthy();
|
||||
expect(processed).toMatchObject([[5, 6], [7]]);
|
||||
});
|
||||
@@ -181,7 +181,7 @@ describe('transformDataFrame', () => {
|
||||
const processed = received[0];
|
||||
expect(processed[0].length).toEqual(1);
|
||||
expect(processed[0].fields.length).toEqual(1);
|
||||
expect(processed[0].fields[0].values.get(0)).toEqual(0.03);
|
||||
expect(processed[0].fields[0].values[0]).toEqual(0.03);
|
||||
});
|
||||
});
|
||||
it('supports trailing custom transformation', async () => {
|
||||
@@ -208,7 +208,7 @@ describe('transformDataFrame', () => {
|
||||
const processed = received[0];
|
||||
expect(processed[0].length).toEqual(1);
|
||||
expect(processed[0].fields.length).toEqual(1);
|
||||
expect(processed[0].fields[0].values.get(0)).toEqual(0.03);
|
||||
expect(processed[0].fields[0].values[0]).toEqual(0.03);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -237,7 +237,7 @@ describe('transformDataFrame', () => {
|
||||
const processed = received[0];
|
||||
expect(processed[0].length).toEqual(1);
|
||||
expect(processed[0].fields.length).toEqual(1);
|
||||
expect(processed[0].fields[0].values.get(0)).toEqual(0.06);
|
||||
expect(processed[0].fields[0].values[0]).toEqual(0.06);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -234,7 +234,7 @@ describe('calculateField transformer w/ timeseries', () => {
|
||||
await expect(transformDataFrame([cfg], [seriesBC])).toEmitValuesWith((received) => {
|
||||
const data = received[0][0];
|
||||
expect(data.fields.length).toEqual(1);
|
||||
expect(data.fields[0].values.toArray()).toEqual([0, 1]);
|
||||
expect(data.fields[0].values).toEqual([0, 1]);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import { getTimeField } from '../../dataframe/processDataFrame';
|
||||
import { getFieldDisplayName } from '../../field';
|
||||
import { DataFrame, DataTransformerInfo, Field, FieldType, NullValueMode, Vector } from '../../types';
|
||||
import { BinaryOperationID, binaryOperators } from '../../utils/binaryOperators';
|
||||
import { BinaryOperationVector, ConstantVector, IndexVector } from '../../vector';
|
||||
import { BinaryOperationVector, ConstantVector } from '../../vector';
|
||||
import { AsNumberVector } from '../../vector/AsNumberVector';
|
||||
import { RowVector } from '../../vector/RowVector';
|
||||
import { doStandardCalcs, fieldReducers, ReducerID } from '../fieldReducer';
|
||||
@@ -104,11 +104,8 @@ export const calculateFieldTransformer: DataTransformerInfo<CalculateFieldTransf
|
||||
const f = {
|
||||
name: options.alias ?? 'Row',
|
||||
type: FieldType.number,
|
||||
values: new IndexVector(frame.length),
|
||||
config: {
|
||||
min: 0,
|
||||
max: frame.length - 1,
|
||||
},
|
||||
values: [...Array(frame.length).keys()],
|
||||
config: {},
|
||||
};
|
||||
return {
|
||||
...frame,
|
||||
|
||||
@@ -89,7 +89,7 @@ export function concatenateFields(data: DataFrame[], opts: ConcatenateTransforme
|
||||
if (f.values.length === maxLength) {
|
||||
return f;
|
||||
}
|
||||
const values = f.values.toArray();
|
||||
const values = f.values;
|
||||
values.length = maxLength;
|
||||
return {
|
||||
...f,
|
||||
|
||||
@@ -174,7 +174,7 @@ describe('field convert types transformer', () => {
|
||||
expect(
|
||||
numbers[0].fields.map((f) => ({
|
||||
type: f.type,
|
||||
values: f.values.toArray(),
|
||||
values: f.values,
|
||||
}))
|
||||
).toEqual([
|
||||
{ type: FieldType.number, values: [1, 2, 3, 4, 5] },
|
||||
@@ -212,7 +212,7 @@ describe('field convert types transformer', () => {
|
||||
expect(
|
||||
booleans[0].fields.map((f) => ({
|
||||
type: f.type,
|
||||
values: f.values.toArray(),
|
||||
values: f.values,
|
||||
}))
|
||||
).toEqual([
|
||||
{
|
||||
@@ -276,7 +276,7 @@ describe('field convert types transformer', () => {
|
||||
expect(
|
||||
complex[0].fields.map((f) => ({
|
||||
type: f.type,
|
||||
values: f.values.toArray(),
|
||||
values: f.values,
|
||||
}))
|
||||
).toEqual([
|
||||
{
|
||||
@@ -324,7 +324,7 @@ describe('field convert types transformer', () => {
|
||||
expect(
|
||||
stringified[0].fields.map((f) => ({
|
||||
type: f.type,
|
||||
values: f.values.toArray(),
|
||||
values: f.values,
|
||||
}))
|
||||
).toEqual([
|
||||
{
|
||||
@@ -354,7 +354,7 @@ describe('field convert types transformer', () => {
|
||||
],
|
||||
}),
|
||||
])[0].fields[0];
|
||||
expect(stringified.values.toArray()).toEqual([
|
||||
expect(stringified.values).toEqual([
|
||||
'2021-07',
|
||||
'2021-07',
|
||||
'2021-07', // can group by month
|
||||
|
||||
@@ -117,7 +117,7 @@ const iso8601Regex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3,})?(?:Z|[-+]
|
||||
export function fieldToTimeField(field: Field, dateFormat?: string): Field {
|
||||
let opts = dateFormat ? { format: dateFormat } : undefined;
|
||||
|
||||
const timeValues = field.values.toArray().slice();
|
||||
const timeValues = field.values.slice();
|
||||
|
||||
let firstDefined = timeValues.find((v) => v != null);
|
||||
|
||||
@@ -140,7 +140,7 @@ export function fieldToTimeField(field: Field, dateFormat?: string): Field {
|
||||
}
|
||||
|
||||
function fieldToNumberField(field: Field): Field {
|
||||
const numValues = field.values.toArray().slice();
|
||||
const numValues = field.values.slice();
|
||||
|
||||
const valuesAsStrings = numValues.some((v) => typeof v === 'string');
|
||||
|
||||
@@ -166,7 +166,7 @@ function fieldToNumberField(field: Field): Field {
|
||||
}
|
||||
|
||||
function fieldToBooleanField(field: Field): Field {
|
||||
const booleanValues = field.values.toArray().slice();
|
||||
const booleanValues = field.values.slice();
|
||||
|
||||
for (let b = 0; b < booleanValues.length; b++) {
|
||||
booleanValues[b] = Boolean(!!booleanValues[b]);
|
||||
@@ -180,7 +180,7 @@ function fieldToBooleanField(field: Field): Field {
|
||||
}
|
||||
|
||||
function fieldToStringField(field: Field, dateFormat?: string): Field {
|
||||
let values = field.values.toArray();
|
||||
let values = field.values;
|
||||
|
||||
switch (field.type) {
|
||||
case FieldType.time:
|
||||
@@ -203,7 +203,7 @@ function fieldToStringField(field: Field, dateFormat?: string): Field {
|
||||
}
|
||||
|
||||
function fieldToComplexField(field: Field): Field {
|
||||
const complexValues = field.values.toArray().slice();
|
||||
const complexValues = field.values.slice();
|
||||
|
||||
for (let s = 0; s < complexValues.length; s++) {
|
||||
try {
|
||||
@@ -229,7 +229,7 @@ function fieldToComplexField(field: Field): Field {
|
||||
* @public
|
||||
*/
|
||||
export function ensureTimeField(field: Field, dateFormat?: string): Field {
|
||||
const firstValueTypeIsNumber = typeof field.values.get(0) === 'number';
|
||||
const firstValueTypeIsNumber = typeof field.values[0] === 'number';
|
||||
if (field.type === FieldType.time && firstValueTypeIsNumber) {
|
||||
return field; //already time
|
||||
}
|
||||
@@ -244,7 +244,7 @@ export function ensureTimeField(field: Field, dateFormat?: string): Field {
|
||||
|
||||
function fieldToEnumField(field: Field, cfg?: EnumFieldConfig): Field {
|
||||
const enumConfig = { ...cfg };
|
||||
const enumValues = field.values.toArray().slice();
|
||||
const enumValues = field.values.slice();
|
||||
const lookup = new Map<unknown, number>();
|
||||
if (enumConfig.text) {
|
||||
for (let i = 0; i < enumConfig.text.length; i++) {
|
||||
|
||||
@@ -100,12 +100,12 @@ export const filterByValueTransformer: DataTransformerInfo<FilterByValueTransfor
|
||||
|
||||
for (let index = 0; index < frame.length; index++) {
|
||||
if (include && rows.has(index)) {
|
||||
buffer.push(field.values.get(index));
|
||||
buffer.push(field.values[index]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!include && !rows.has(index)) {
|
||||
buffer.push(field.values.get(index));
|
||||
buffer.push(field.values[index]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ export const groupByTransformer: DataTransformerInfo<GroupByTransformerOptions>
|
||||
// group for a given field.
|
||||
const valuesByGroupKey = new Map<string, Record<string, MutableField>>();
|
||||
for (let rowIndex = 0; rowIndex < frame.length; rowIndex++) {
|
||||
const groupKey = String(groupByFields.map((field) => field.values.get(rowIndex)));
|
||||
const groupKey = String(groupByFields.map((field) => field.values[rowIndex]));
|
||||
const valuesByField = valuesByGroupKey.get(groupKey) ?? {};
|
||||
|
||||
if (!valuesByGroupKey.has(groupKey)) {
|
||||
@@ -84,7 +84,7 @@ export const groupByTransformer: DataTransformerInfo<GroupByTransformerOptions>
|
||||
};
|
||||
}
|
||||
|
||||
valuesByField[fieldName].values.add(field.values.get(rowIndex));
|
||||
valuesByField[fieldName].values.push(field.values[rowIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ export const groupByTransformer: DataTransformerInfo<GroupByTransformerOptions>
|
||||
const fieldName = getFieldDisplayName(field);
|
||||
|
||||
valuesByGroupKey.forEach((value) => {
|
||||
values.add(value[fieldName].values.get(0));
|
||||
values.push(value[fieldName].values[0]);
|
||||
});
|
||||
|
||||
fields.push({
|
||||
|
||||
@@ -64,9 +64,9 @@ export const groupingToMatrixTransformer: DataTransformerInfo<GroupingToMatrixTr
|
||||
const matrixValues: { [key: string]: { [key: string]: any } } = {};
|
||||
|
||||
for (let index = 0; index < valueField.values.length; index++) {
|
||||
const columnName = keyColumnField.values.get(index);
|
||||
const rowName = keyRowField.values.get(index);
|
||||
const value = valueField.values.get(index);
|
||||
const columnName = keyColumnField.values[index];
|
||||
const rowName = keyRowField.values[index];
|
||||
const value = valueField.values[index];
|
||||
|
||||
if (!matrixValues[columnName]) {
|
||||
matrixValues[columnName] = {};
|
||||
@@ -115,7 +115,7 @@ function uniqueValues(values: Vector): any[] {
|
||||
const unique = new Set();
|
||||
|
||||
for (let index = 0; index < values.length; index++) {
|
||||
unique.add(values.get(index));
|
||||
unique.add(values[index]);
|
||||
}
|
||||
|
||||
return Array.from(unique);
|
||||
|
||||
@@ -26,7 +26,7 @@ describe('histogram frames frames', () => {
|
||||
expect(
|
||||
out.fields.map((f) => ({
|
||||
name: f.name,
|
||||
values: f.values.toArray(),
|
||||
values: f.values,
|
||||
config: f.config,
|
||||
}))
|
||||
).toMatchInlineSnapshot(`
|
||||
@@ -140,7 +140,7 @@ describe('histogram frames frames', () => {
|
||||
expect(
|
||||
out2.fields.map((f) => ({
|
||||
name: f.name,
|
||||
values: f.values.toArray(),
|
||||
values: f.values,
|
||||
}))
|
||||
).toMatchInlineSnapshot(`
|
||||
[
|
||||
|
||||
@@ -151,7 +151,7 @@ export function getHistogramFields(frame: DataFrame): HistogramFields | undefine
|
||||
|
||||
// guess bucket size from single explicit bucket field
|
||||
if (!xMax && xMin && xMin.values.length > 1) {
|
||||
let vals = xMin.values.toArray();
|
||||
let vals = xMin.values;
|
||||
let bucketSize = roundDecimals(vals[1] - vals[0], 6);
|
||||
|
||||
xMax = {
|
||||
@@ -162,7 +162,7 @@ export function getHistogramFields(frame: DataFrame): HistogramFields | undefine
|
||||
}
|
||||
|
||||
if (!xMin && xMax && xMax?.values.length > 1) {
|
||||
let vals = xMax.values.toArray();
|
||||
let vals = xMax.values;
|
||||
let bucketSize = roundDecimals(vals[1] - vals[0], 6);
|
||||
|
||||
xMin = {
|
||||
@@ -199,7 +199,7 @@ export function buildHistogram(frames: DataFrame[], options?: HistogramTransform
|
||||
for (const frame of frames) {
|
||||
for (const field of frame.fields) {
|
||||
if (field.type === FieldType.number) {
|
||||
allValues = allValues.concat(field.values.toArray());
|
||||
allValues = allValues.concat(field.values);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -253,7 +253,7 @@ export function buildHistogram(frames: DataFrame[], options?: HistogramTransform
|
||||
for (const frame of frames) {
|
||||
for (const field of frame.fields) {
|
||||
if (field.type === FieldType.number) {
|
||||
let fieldHist = histogram(field.values.toArray(), getBucket, histFilter, histSort) as AlignedData;
|
||||
let fieldHist = histogram(field.values, getBucket, histFilter, histSort) as AlignedData;
|
||||
histograms.push(fieldHist);
|
||||
counts.push({
|
||||
...field,
|
||||
|
||||
@@ -32,7 +32,7 @@ describe('align frames', () => {
|
||||
expect(
|
||||
out.fields.map((f) => ({
|
||||
name: f.name,
|
||||
values: f.values.toArray(),
|
||||
values: f.values,
|
||||
}))
|
||||
).toMatchInlineSnapshot(`
|
||||
[
|
||||
@@ -85,7 +85,7 @@ describe('align frames', () => {
|
||||
expect(
|
||||
out.fields.map((f) => ({
|
||||
name: f.name,
|
||||
values: f.values.toArray(),
|
||||
values: f.values,
|
||||
}))
|
||||
).toMatchInlineSnapshot(`
|
||||
[
|
||||
@@ -149,7 +149,7 @@ describe('align frames', () => {
|
||||
expect(
|
||||
out.fields.map((f) => ({
|
||||
name: f.name,
|
||||
values: f.values.toArray(),
|
||||
values: f.values,
|
||||
state: f.state,
|
||||
}))
|
||||
).toMatchInlineSnapshot(`
|
||||
@@ -242,7 +242,7 @@ describe('align frames', () => {
|
||||
expect(
|
||||
out.fields.map((f) => ({
|
||||
name: f.name,
|
||||
values: f.values.toArray(),
|
||||
values: f.values,
|
||||
}))
|
||||
).toMatchInlineSnapshot(`
|
||||
[
|
||||
@@ -289,7 +289,7 @@ describe('align frames', () => {
|
||||
expect(
|
||||
out.fields.map((f) => ({
|
||||
name: f.name,
|
||||
values: f.values.toArray(),
|
||||
values: f.values,
|
||||
}))
|
||||
).toMatchInlineSnapshot(`
|
||||
[
|
||||
|
||||
@@ -207,10 +207,10 @@ export function joinDataFrames(options: JoinOptions): DataFrame | undefined {
|
||||
}
|
||||
|
||||
nullModes.push(nullModesFrame);
|
||||
const a: AlignedData = [join.values.toArray()]; //
|
||||
const a: AlignedData = [join.values]; //
|
||||
|
||||
for (const field of fields) {
|
||||
a.push(field.values.toArray());
|
||||
a.push(field.values);
|
||||
originalFields.push(field);
|
||||
// clear field displayName state
|
||||
delete field.state?.displayName;
|
||||
|
||||
@@ -259,7 +259,7 @@ describe('Labels as Columns', () => {
|
||||
});
|
||||
|
||||
await expect(transformDataFrame([cfg], [source])).toEmitValuesWith((received) => {
|
||||
expect(received[0][0].fields.map((f) => ({ [f.name]: f.values.toArray() }))).toMatchInlineSnapshot(`
|
||||
expect(received[0][0].fields.map((f) => ({ [f.name]: f.values }))).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"time": [
|
||||
@@ -346,9 +346,8 @@ describe('Labels as Columns', () => {
|
||||
});
|
||||
|
||||
await expect(transformDataFrame([cfg], [source])).toEmitValuesWith((received) => {
|
||||
expect(
|
||||
received[0].map((f) => ({ name: f.name, fields: f.fields.map((v) => ({ [v.name]: v.values.toArray() })) }))
|
||||
).toMatchInlineSnapshot(`
|
||||
expect(received[0].map((f) => ({ name: f.name, fields: f.fields.map((v) => ({ [v.name]: v.values })) })))
|
||||
.toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"fields": [
|
||||
@@ -410,9 +409,8 @@ describe('Labels as Columns', () => {
|
||||
});
|
||||
|
||||
await expect(transformDataFrame([cfg], [source])).toEmitValuesWith((received) => {
|
||||
expect(
|
||||
received[0].map((f) => ({ name: f.name, fields: f.fields.map((v) => ({ [v.name]: v.values.toArray() })) }))
|
||||
).toMatchInlineSnapshot(`
|
||||
expect(received[0].map((f) => ({ name: f.name, fields: f.fields.map((v) => ({ [v.name]: v.values })) })))
|
||||
.toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"fields": [
|
||||
@@ -457,7 +455,7 @@ describe('Labels as Columns', () => {
|
||||
function toSimpleObject(frame: DataFrame) {
|
||||
const obj: Record<string, unknown> = {};
|
||||
for (const field of frame.fields) {
|
||||
obj[field.name] = field.values.toArray();
|
||||
obj[field.name] = field.values;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
@@ -595,7 +595,5 @@ const createField = (
|
||||
};
|
||||
|
||||
const unwrap = (fields: Field[]): Field[] => {
|
||||
return fields.map((field) =>
|
||||
createField(field.name, field.type, field.values.toArray(), field.config, field.display)
|
||||
);
|
||||
return fields.map((field) => createField(field.name, field.type, field.values, field.config, field.display));
|
||||
};
|
||||
|
||||
@@ -95,5 +95,5 @@ describe('SortBy transformer', () => {
|
||||
});
|
||||
|
||||
function getFieldSnapshot(f: Field): Object {
|
||||
return { name: f.name, values: f.values.toArray() };
|
||||
return { name: f.name, values: f.values };
|
||||
}
|
||||
|
||||
@@ -308,7 +308,7 @@ export function toCSV(data: DataFrame[], config?: CSVConfig): string {
|
||||
csv = csv + config.delimiter;
|
||||
}
|
||||
|
||||
const v = fields[j].values.get(i);
|
||||
const v = fields[j].values[i];
|
||||
if (v !== null) {
|
||||
csv = csv + writers[j](v);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { DataLink, FieldType, TimeRange } from '../types';
|
||||
import { ArrayVector } from '../vector';
|
||||
|
||||
import { mapInternalLinkToExplore } from './dataLinks';
|
||||
|
||||
@@ -24,7 +23,7 @@ describe('mapInternalLinkToExplore', () => {
|
||||
name: 'test',
|
||||
type: FieldType.number,
|
||||
config: {},
|
||||
values: new ArrayVector([2]),
|
||||
values: [2],
|
||||
},
|
||||
replaceVariables: (val) => val,
|
||||
});
|
||||
@@ -65,7 +64,7 @@ describe('mapInternalLinkToExplore', () => {
|
||||
name: 'test',
|
||||
type: FieldType.number,
|
||||
config: {},
|
||||
values: new ArrayVector([2]),
|
||||
values: [2],
|
||||
},
|
||||
replaceVariables: (val) => val,
|
||||
});
|
||||
@@ -112,7 +111,7 @@ describe('mapInternalLinkToExplore', () => {
|
||||
name: 'test',
|
||||
type: FieldType.number,
|
||||
config: {},
|
||||
values: new ArrayVector([2]),
|
||||
values: [2],
|
||||
},
|
||||
replaceVariables: (val, scopedVars) => val.replace(/\$var/g, scopedVars!['var1']!.value),
|
||||
});
|
||||
|
||||
@@ -1,25 +1,24 @@
|
||||
import { Field, FieldType } from '../types';
|
||||
import { ArrayVector } from '../vector';
|
||||
|
||||
import { getSeriesTimeStep, hasMsResolution } from './series';
|
||||
|
||||
const uniformTimeField: Field = {
|
||||
name: 'time',
|
||||
type: FieldType.time,
|
||||
values: new ArrayVector([0, 100, 200, 300]),
|
||||
values: [0, 100, 200, 300],
|
||||
config: {},
|
||||
};
|
||||
const nonUniformTimeField: Field = {
|
||||
name: 'time',
|
||||
type: FieldType.time,
|
||||
values: new ArrayVector([0, 100, 300, 350]),
|
||||
values: [0, 100, 300, 350],
|
||||
config: {},
|
||||
};
|
||||
|
||||
const msResolutionTimeField: Field = {
|
||||
name: 'time',
|
||||
type: FieldType.time,
|
||||
values: new ArrayVector([0, 1572951685007, 300, 350]),
|
||||
values: [0, 1572951685007, 300, 350],
|
||||
config: {},
|
||||
};
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ export const getSeriesTimeStep = (timeField: Field): number => {
|
||||
let returnTimeStep = Number.MAX_VALUE;
|
||||
|
||||
for (let i = 0; i < timeField.values.length; i++) {
|
||||
const currentTime = timeField.values.get(i);
|
||||
const currentTime = timeField.values[i];
|
||||
|
||||
if (previousTime !== undefined) {
|
||||
const timeStep = currentTime - previousTime;
|
||||
@@ -34,7 +34,7 @@ export const getSeriesTimeStep = (timeField: Field): number => {
|
||||
*/
|
||||
export const hasMsResolution = (timeField: Field) => {
|
||||
for (let i = 0; i < timeField.values.length; i++) {
|
||||
const value = timeField.values.get(i);
|
||||
const value = timeField.values[i];
|
||||
if (value !== null && value !== undefined) {
|
||||
const timestamp = value.toString();
|
||||
if (timestamp.length === 13 && timestamp % 1000 !== 0) {
|
||||
|
||||
@@ -13,6 +13,8 @@ interface AppendedVectorInfo<T> {
|
||||
* This may be more trouble than it is worth. This trades some computation time for
|
||||
* RAM -- rather than allocate a new array the size of all previous arrays, this just
|
||||
* points the correct index to their original array values
|
||||
*
|
||||
* @deprecated use a simple Arrays
|
||||
*/
|
||||
export class AppendedVectors<T = any> extends FunctionalVector<T> {
|
||||
length = 0;
|
||||
@@ -60,7 +62,7 @@ export class AppendedVectors<T = any> extends FunctionalVector<T> {
|
||||
for (let i = 0; i < this.source.length; i++) {
|
||||
const src = this.source[i];
|
||||
if (index >= src.start && index < src.end) {
|
||||
return src.values.get(index - src.start);
|
||||
return src.values[index - src.start];
|
||||
}
|
||||
}
|
||||
return undefined as unknown as T;
|
||||
|
||||
@@ -6,6 +6,7 @@ import { FunctionalVector } from './FunctionalVector';
|
||||
* This will force all values to be numbers
|
||||
*
|
||||
* @public
|
||||
* @deprecated use a simple Arrays
|
||||
*/
|
||||
export class AsNumberVector extends FunctionalVector<number> {
|
||||
constructor(private field: Vector) {
|
||||
|
||||
@@ -6,6 +6,7 @@ import { vectorToArray } from './vectorToArray';
|
||||
|
||||
/**
|
||||
* @public
|
||||
* @deprecated use a simple Arrays
|
||||
*/
|
||||
export class BinaryOperationVector extends FunctionalVector<number> {
|
||||
constructor(private left: Vector<number>, private right: Vector<number>, private operation: BinaryOperation) {
|
||||
|
||||
@@ -14,6 +14,7 @@ interface CircularOptions<T> {
|
||||
* to match a configured capacity.
|
||||
*
|
||||
* @public
|
||||
* @deprecated use a simple Arrays
|
||||
*/
|
||||
export class CircularVector<T = any> extends FunctionalVector<T> {
|
||||
private buffer: T[];
|
||||
|
||||
@@ -2,6 +2,7 @@ import { FunctionalVector } from './FunctionalVector';
|
||||
|
||||
/**
|
||||
* @public
|
||||
* @deprecated use a simple Arrays
|
||||
*/
|
||||
export class ConstantVector<T = any> extends FunctionalVector<T> {
|
||||
constructor(private value: T, private len: number) {
|
||||
|
||||
@@ -6,6 +6,7 @@ import { FunctionalVector } from './FunctionalVector';
|
||||
|
||||
/**
|
||||
* @public
|
||||
* @deprecated use a simple Arrays
|
||||
*/
|
||||
export class FormattedVector<T = any> extends FunctionalVector<string> {
|
||||
constructor(private source: Vector<T>, private formatter: DisplayProcessor) {
|
||||
|
||||
@@ -2,7 +2,10 @@ import { Vector } from '../types';
|
||||
|
||||
import { vectorToArray } from './vectorToArray';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* @public
|
||||
* @deprecated use a simple Arrays
|
||||
*/
|
||||
export abstract class FunctionalVector<T = any> implements Vector<T> {
|
||||
abstract get length(): number;
|
||||
|
||||
@@ -187,6 +190,8 @@ const emptyarray: any[] = [];
|
||||
|
||||
/**
|
||||
* Use functional programming with your vector
|
||||
*
|
||||
* @deprecated use a simple Arrays
|
||||
*/
|
||||
export function vectorator<T>(vector: Vector<T>) {
|
||||
return {
|
||||
|
||||
@@ -6,6 +6,7 @@ import { vectorToArray } from './vectorToArray';
|
||||
/**
|
||||
* RowVector makes the row values look like a vector
|
||||
* @internal
|
||||
* @deprecated use a simple Arrays
|
||||
*/
|
||||
export class RowVector extends FunctionalVector<number> {
|
||||
constructor(private columns: Vector[]) {
|
||||
|
||||
Reference in New Issue
Block a user