FieldValues: Use simple array in panel visualizations (#66706)

Co-authored-by: Leon Sorokin <leeoniya@gmail.com>
This commit is contained in:
Ryan McKinley 2023-04-17 14:46:29 -07:00 committed by GitHub
parent 50cb4f8998
commit 09f03e92bf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
60 changed files with 265 additions and 320 deletions

View File

@ -2859,9 +2859,6 @@ exports[`better eslint`] = {
"public/app/features/geo/format/geojson.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"public/app/features/geo/format/utils.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"public/app/features/geo/gazetteer/gazetteer.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"],

View File

@ -1,7 +1,7 @@
import { Story, Meta } from '@storybook/react';
import React from 'react';
import { ArrayVector, FieldSparkline, FieldType } from '@grafana/data';
import { FieldSparkline, FieldType } from '@grafana/data';
import { useTheme2 } from '../../themes';
import { withCenteredStory } from '../../utils/storybook/withCenteredStory';
@ -74,7 +74,7 @@ export const Basic: Story<StoryProps> = ({
const sparkline: FieldSparkline = {
y: {
name: '',
values: new ArrayVector([1, 2, 3, 4, 3]),
values: [1, 2, 3, 4, 3],
type: FieldType.number,
state: { range: { min: 1, max: 4, delta: 3 } },
config: {},

View File

@ -1,4 +1,4 @@
import { ArrayVector, createTheme, FieldType } from '@grafana/data';
import { createTheme, FieldType } from '@grafana/data';
import { Props, BigValueColorMode, BigValueGraphMode, BigValueTextMode } from './BigValue';
import { buildLayout, StackedWithChartLayout, StackedWithNoChartLayout, WideWithChartLayout } from './BigValueLayout';
@ -16,7 +16,7 @@ function getProps(propOverrides?: Partial<Props>): Props {
sparkline: {
y: {
name: '',
values: new ArrayVector([1, 2, 3, 4, 3]),
values: [1, 2, 3, 4, 3],
type: FieldType.number,
config: {},
},
@ -68,7 +68,7 @@ describe('BigValueLayout', () => {
sparkline: {
y: {
name: '',
values: new ArrayVector([1]),
values: [1],
type: FieldType.number,
config: {},
},

View File

@ -2,7 +2,7 @@ import { act, render, screen } from '@testing-library/react';
import $ from 'jquery';
import React from 'react';
import { GraphSeriesXY, FieldType, ArrayVector, dateTime, FieldColorModeId, DisplayProcessor } from '@grafana/data';
import { GraphSeriesXY, FieldType, dateTime, FieldColorModeId, DisplayProcessor } from '@grafana/data';
import { TooltipDisplayMode } from '@grafana/schema';
import { VizTooltip } from '../VizTooltip';
@ -25,13 +25,13 @@ const series: GraphSeriesXY[] = [
timeField: {
type: FieldType.time,
name: 'time',
values: new ArrayVector([1546372800000, 1546376400000, 1546380000000]),
values: [1546372800000, 1546376400000, 1546380000000],
config: {},
},
valueField: {
type: FieldType.number,
name: 'a-series',
values: new ArrayVector([10, 20, 10]),
values: [10, 20, 10],
config: { color: { mode: FieldColorModeId.Fixed, fixedColor: 'red' } },
display,
},
@ -53,13 +53,13 @@ const series: GraphSeriesXY[] = [
timeField: {
type: FieldType.time,
name: 'time',
values: new ArrayVector([1546372800000, 1546376400000, 1546380000000]),
values: [1546372800000, 1546376400000, 1546380000000],
config: {},
},
valueField: {
type: FieldType.number,
name: 'b-series',
values: new ArrayVector([20, 30, 40]),
values: [20, 30, 40],
config: { color: { mode: FieldColorModeId.Fixed, fixedColor: 'blue' } },
display,
},

View File

@ -1,7 +1,7 @@
import { render, screen } from '@testing-library/react';
import React from 'react';
import { createDimension, createTheme, ArrayVector, FieldType, DisplayProcessor } from '@grafana/data';
import { createDimension, createTheme, FieldType, DisplayProcessor } from '@grafana/data';
import { ActiveDimensions } from '../../VizTooltip';
@ -20,14 +20,14 @@ describe('MultiModeGraphTooltip', () => {
xAxis: createDimension('xAxis', [
{
config: {},
values: new ArrayVector([0, 100, 200]),
values: [0, 100, 200],
name: 'A-series time',
type: FieldType.time,
display,
},
{
config: {},
values: new ArrayVector([0, 100, 200]),
values: [0, 100, 200],
name: 'B-series time',
type: FieldType.time,
display,
@ -36,14 +36,14 @@ describe('MultiModeGraphTooltip', () => {
yAxis: createDimension('yAxis', [
{
config: {},
values: new ArrayVector([10, 20, 10]),
values: [10, 20, 10],
name: 'A-series values',
type: FieldType.number,
display,
},
{
config: {},
values: new ArrayVector([20, 30, 40]),
values: [20, 30, 40],
name: 'B-series values',
type: FieldType.number,
display,

View File

@ -1,7 +1,7 @@
import { Story } from '@storybook/react';
import React from 'react';
import { GraphSeriesXY, FieldType, ArrayVector, dateTime, FieldColorModeId } from '@grafana/data';
import { GraphSeriesXY, FieldType, dateTime, FieldColorModeId } from '@grafana/data';
import { LegendDisplayMode } from '@grafana/schema';
import { withCenteredStory } from '../../utils/storybook/withCenteredStory';
@ -42,13 +42,13 @@ const series: GraphSeriesXY[] = [
timeField: {
type: FieldType.time,
name: 'time',
values: new ArrayVector([1546372800000, 1546376400000, 1546380000000]),
values: [1546372800000, 1546376400000, 1546380000000],
config: {},
},
valueField: {
type: FieldType.number,
name: 'a-series',
values: new ArrayVector([10, 20, 10]),
values: [10, 20, 10],
config: {
color: {
mode: FieldColorModeId.Fixed,
@ -74,13 +74,13 @@ const series: GraphSeriesXY[] = [
timeField: {
type: FieldType.time,
name: 'time',
values: new ArrayVector([1546372800000, 1546376400000, 1546380000000]),
values: [1546372800000, 1546376400000, 1546380000000],
config: {},
},
valueField: {
type: FieldType.number,
name: 'b-series',
values: new ArrayVector([20, 30, 40]),
values: [20, 30, 40],
config: {
color: {
mode: FieldColorModeId.Fixed,

View File

@ -24,7 +24,7 @@ export const findHoverIndexFromData = (xAxisDimension: Field, xPos: number) => {
return Math.max(upper, 0);
}
middle = Math.floor((lower + upper) / 2);
const xPosition = xAxisDimension.values.get(middle);
const xPosition = xAxisDimension.values[middle];
if (xPosition === xPos) {
return middle;
@ -72,8 +72,8 @@ export const getMultiSeriesGraphHoverInfo = (
field = yAxisDimensions[i];
const time = xAxisDimensions[i];
hoverIndex = findHoverIndexFromData(time, xAxisPosition);
hoverDistance = xAxisPosition - time.values.get(hoverIndex);
pointTime = time.values.get(hoverIndex);
hoverDistance = xAxisPosition - time.values[hoverIndex];
pointTime = time.values[hoverIndex];
// Take the closest point before the cursor, or if it does not exist, the closest after
if (
minDistance === undefined ||
@ -84,7 +84,7 @@ export const getMultiSeriesGraphHoverInfo = (
minTime = time.display ? formattedValueToString(time.display(pointTime)) : pointTime;
}
const disp = field.display!(field.values.get(hoverIndex));
const disp = field.display!(field.values[hoverIndex]);
results.push({
value: formattedValueToString(disp),

View File

@ -1,4 +1,4 @@
import { ArrayVector, FieldType, MutableDataFrame } from '@grafana/data';
import { FieldType, MutableDataFrame } from '@grafana/data';
import { applyNullInsertThreshold } from './nullInsertThreshold';
@ -40,7 +40,7 @@ function genFrame() {
config: {
interval: i === 0 ? step : null,
},
values: new ArrayVector(values),
values: values,
};
}),
};

View File

@ -1,4 +1,4 @@
import { ArrayVector, DataFrame, FieldType, incrRoundDn } from '@grafana/data';
import { DataFrame, FieldType, incrRoundDn } from '@grafana/data';
type InsertMode = (prev: number, next: number, threshold: number) => number;
@ -60,9 +60,9 @@ export function applyNullInsertThreshold(opts: NullInsertOptions): DataFrame {
return frame;
}
const refValues = refField.values.toArray();
const refValues = refField.values;
const frameValues = frame.fields.map((field) => field.values.toArray());
const frameValues = frame.fields.map((field) => field.values);
const filledFieldValues = nullInsertThreshold(
refValues,
@ -83,7 +83,7 @@ export function applyNullInsertThreshold(opts: NullInsertOptions): DataFrame {
length: filledFieldValues[0].length,
fields: frame.fields.map((field, i) => ({
...field,
values: new ArrayVector(filledFieldValues[i]),
values: filledFieldValues[i],
})),
};
}

View File

@ -1,4 +1,4 @@
import { ArrayVector, DataFrame } from '@grafana/data';
import { DataFrame } from '@grafana/data';
export function nullToValue(frame: DataFrame) {
return {
@ -7,7 +7,7 @@ export function nullToValue(frame: DataFrame) {
const noValue = +field.config?.noValue!;
if (!Number.isNaN(noValue)) {
const transformedVals = field.values.toArray().slice();
const transformedVals = field.values.slice();
for (let i = 0; i < transformedVals.length; i++) {
if (transformedVals[i] === null) {
@ -17,7 +17,7 @@ export function nullToValue(frame: DataFrame) {
return {
...field,
values: new ArrayVector(transformedVals),
values: transformedVals,
};
} else {
return field;

View File

@ -1,5 +1,4 @@
import {
ArrayVector,
createTheme,
DashboardCursorSync,
DataFrame,
@ -232,7 +231,7 @@ describe('GraphNG utils', () => {
name: 'time',
type: FieldType.time,
config: {},
values: new ArrayVector([1, 2, 4, 6, 100]), // should find smallest delta === 1 from here
values: [1, 2, 4, 6, 100], // should find smallest delta === 1 from here
},
{
name: 'value',
@ -242,7 +241,7 @@ describe('GraphNG utils', () => {
drawStyle: GraphDrawStyle.Bars,
},
},
values: new ArrayVector([1, 1, 1, 1, 1]),
values: [1, 1, 1, 1, 1],
},
],
};
@ -255,7 +254,7 @@ describe('GraphNG utils', () => {
name: 'time',
type: FieldType.time,
config: {},
values: new ArrayVector([30, 40, 50, 90, 100]), // should be appended with two smallest-delta increments
values: [30, 40, 50, 90, 100], // should be appended with two smallest-delta increments
},
{
name: 'value',
@ -265,7 +264,7 @@ describe('GraphNG utils', () => {
drawStyle: GraphDrawStyle.Bars,
},
},
values: new ArrayVector([2, 2, 2, 2, 2]), // bar series should be appended with nulls
values: [2, 2, 2, 2, 2], // bar series should be appended with nulls
},
{
name: 'value',
@ -275,7 +274,7 @@ describe('GraphNG utils', () => {
drawStyle: GraphDrawStyle.Line,
},
},
values: new ArrayVector([3, 3, 3, 3, 3]), // line series should be appended with undefineds
values: [3, 3, 3, 3, 3], // line series should be appended with undefineds
},
],
};
@ -288,7 +287,7 @@ describe('GraphNG utils', () => {
name: 'time',
type: FieldType.time,
config: {},
values: new ArrayVector([1, 1.1]), // should not trip up on smaller deltas of non-bars
values: [1, 1.1], // should not trip up on smaller deltas of non-bars
},
{
name: 'value',
@ -298,7 +297,7 @@ describe('GraphNG utils', () => {
drawStyle: GraphDrawStyle.Line,
},
},
values: new ArrayVector([4, 4]),
values: [4, 4],
},
{
name: 'value',
@ -311,7 +310,7 @@ describe('GraphNG utils', () => {
},
},
},
values: new ArrayVector([4, 4]),
values: [4, 4],
},
],
};

View File

@ -1,4 +1,4 @@
import { ArrayVector, DataFrame, Field, FieldConfig, FieldType, outerJoinDataFrames, TimeRange } from '@grafana/data';
import { DataFrame, Field, FieldConfig, FieldType, outerJoinDataFrames, TimeRange } from '@grafana/data';
import {
AxisPlacement,
GraphDrawStyle,
@ -21,7 +21,7 @@ function isVisibleBarField(f: Field) {
// will mutate the DataFrame's fields' values
function applySpanNullsThresholds(frame: DataFrame) {
let refField = frame.fields.find((field) => field.type === FieldType.time); // this doesnt need to be time, just any numeric/asc join field
let refValues = refField?.values.toArray() as any[];
let refValues = refField?.values as any[];
for (let i = 0; i < frame.fields.length; i++) {
let field = frame.fields[i];
@ -34,7 +34,7 @@ function applySpanNullsThresholds(frame: DataFrame) {
if (typeof spanNulls === 'number') {
if (spanNulls !== -1) {
field.values = new ArrayVector(nullToUndefThreshold(refValues, field.values.toArray(), spanNulls));
field.values = nullToUndefThreshold(refValues, field.values, spanNulls);
}
}
}
@ -84,7 +84,7 @@ export function preparePlotFrame(frames: DataFrame[], dimFields: XYFieldMatchers
return;
}
const xVals = frame.fields[0].values.toArray();
const xVals = frame.fields[0].values;
for (let i = 0; i < xVals.length; i++) {
if (i > 0) {
@ -107,7 +107,7 @@ export function preparePlotFrame(frames: DataFrame[], dimFields: XYFieldMatchers
// append 2 null vals at minXDelta to bar series
if (minXDelta !== Infinity) {
alignedFrame.fields.forEach((f, fi) => {
let vals = f.values.toArray();
let vals = f.values;
if (fi === 0) {
let lastVal = vals[vals.length - 1];

View File

@ -1,4 +1,4 @@
import { DataFrame, FieldConfig, FieldSparkline, IndexVector } from '@grafana/data';
import { DataFrame, FieldConfig, FieldSparkline, FieldType } from '@grafana/data';
import { GraphFieldConfig } from '@grafana/schema';
import { applyNullInsertThreshold } from '../GraphNG/nullInsertThreshold';
@ -17,7 +17,12 @@ export function preparePlotFrame(sparkline: FieldSparkline, config?: FieldConfig
frame: {
refId: 'sparkline',
fields: [
sparkline.x ?? IndexVector.newField(length),
sparkline.x ?? {
name: '',
values: [...Array(length).keys()],
type: FieldType.number,
config: {},
},
{
...sparkline.y,
config: yFieldConfig,

View File

@ -124,7 +124,7 @@ function getAlignmentFactor(field: Field, displayValue: DisplayValue, rowIndex:
const maxIndex = Math.min(field.values.length, rowIndex + 1000);
for (let i = rowIndex + 1; i < maxIndex; i++) {
const nextDisplayValue = field.display!(field.values.get(i));
const nextDisplayValue = field.display!(field.values[i]);
if (nextDisplayValue.text.length > alignmentFactor.text.length) {
alignmentFactor.text = displayValue.text;
}

View File

@ -1,15 +1,6 @@
import { isArray } from 'lodash';
import React from 'react';
import {
ArrayVector,
FieldType,
FieldConfig,
getMinMaxAndDelta,
FieldSparkline,
isDataFrame,
Field,
} from '@grafana/data';
import { FieldType, FieldConfig, getMinMaxAndDelta, FieldSparkline, isDataFrame, Field } from '@grafana/data';
import {
BarAlignment,
GraphDrawStyle,
@ -79,12 +70,12 @@ export const SparklineCell = (props: TableCellProps) => {
};
function getSparkline(value: unknown): FieldSparkline | undefined {
if (isArray(value)) {
if (Array.isArray(value)) {
return {
y: {
name: 'test',
type: FieldType.number,
values: new ArrayVector(value),
values: value,
config: {},
},
};

View File

@ -155,7 +155,7 @@ function buildSubTablesData(theme: GrafanaTheme2, config: Record<string, FieldCo
}
function buildFooterData(data: DataFrame): FooterItem[] {
const values = data.fields[3].values.toArray();
const values = data.fields[3].values;
const valueSum = values.reduce((prev, curr) => {
return prev + curr;
}, 0);

View File

@ -1,6 +1,6 @@
import { Row } from 'react-table';
import { ArrayVector, Field, FieldType, MutableDataFrame, SelectableValue } from '@grafana/data';
import { Field, FieldType, MutableDataFrame, SelectableValue } from '@grafana/data';
import {
calculateUniqueFieldValues,
@ -92,7 +92,7 @@ describe('Table utils', () => {
describe('filterByValue', () => {
describe('happy path', () => {
const field = { values: new ArrayVector(['a', 'aa', 'ab', 'b', 'ba', 'bb', 'c']) } as unknown as Field;
const field = { values: ['a', 'aa', 'ab', 'b', 'ba', 'bb', 'c'] } as unknown as Field;
const rows = [
{ index: 0, values: { 0: 'a' } },
{ index: 1, values: { 0: 'aa' } },
@ -116,7 +116,7 @@ describe('Table utils', () => {
describe('fast exit cases', () => {
describe('no rows', () => {
it('should return empty array', () => {
const field = { values: new ArrayVector(['a']) } as unknown as Field;
const field = { values: ['a'] } as unknown as Field;
const rows: Row[] = [];
const filterValues = [{ value: 'a' }];
@ -128,7 +128,7 @@ describe('Table utils', () => {
describe('no filterValues', () => {
it('should return rows', () => {
const field = { values: new ArrayVector(['a']) } as unknown as Field;
const field = { values: ['a'] } as unknown as Field;
const rows = [{}] as Row[];
const filterValues = undefined;
@ -152,7 +152,7 @@ describe('Table utils', () => {
describe('missing id in values', () => {
it('should return rows', () => {
const field = { values: new ArrayVector(['a', 'b', 'c']) } as unknown as Field;
const field = { values: ['a', 'b', 'c'] } as unknown as Field;
const rows = [
{ index: 0, values: { 0: 'a' } },
{ index: 1, values: { 0: 'b' } },
@ -185,7 +185,7 @@ describe('Table utils', () => {
const field: Field = {
config: {},
labels: {},
values: new ArrayVector([1]),
values: [1],
name: 'value',
type: FieldType.number,
getLinks: () => [],
@ -210,7 +210,7 @@ describe('Table utils', () => {
it('then it should return an array with unique values', () => {
const field: Field = {
config: {},
values: new ArrayVector([1, 2, 2, 1, 3, 5, 6]),
values: [1, 2, 2, 1, 3, 5, 6],
name: 'value',
type: FieldType.number,
display: jest.fn().mockImplementation((value) => ({
@ -238,7 +238,7 @@ describe('Table utils', () => {
it('then it should return an array with unique values', () => {
const field: Field = {
config: {},
values: new ArrayVector([1, 2, 2, 1, 3, 5, 6]),
values: [1, 2, 2, 1, 3, 5, 6],
name: 'value',
type: FieldType.number,
};
@ -257,7 +257,7 @@ describe('Table utils', () => {
it('then it should return an array with unique values and (Blanks)', () => {
const field: Field = {
config: {},
values: new ArrayVector([1, null, null, 1, 3, 5, 6]),
values: [1, null, null, 1, 3, 5, 6],
name: 'value',
type: FieldType.number,
};
@ -282,7 +282,7 @@ describe('Table utils', () => {
name: 'value',
type: FieldType.string,
config: {},
values: new ArrayVector(['a', 'b', 'c']),
values: ['a', 'b', 'c'],
};
const row = { index: 1 };
@ -294,7 +294,7 @@ describe('Table utils', () => {
describe('field with display processor', () => {
const field: Field = {
config: {},
values: new ArrayVector([1, 2, 2, 1, 3, 5, 6]),
values: [1, 2, 2, 1, 3, 5, 6],
name: 'value',
type: FieldType.number,
display: jest.fn().mockImplementation((value) => ({
@ -327,7 +327,7 @@ describe('Table utils', () => {
name: 'value',
type: FieldType.string,
config: {},
values: new ArrayVector(['a', 'b', 'c']),
values: ['a', 'b', 'c'],
};
const row = undefined;

View File

@ -14,7 +14,6 @@ import {
getDisplayProcessor,
reduceField,
GrafanaTheme2,
ArrayVector,
isDataFrame,
isTimeSeriesFrame,
} from '@grafana/data';
@ -133,7 +132,7 @@ export function getColumns(
field: field,
Header: getFieldDisplayName(field, data),
accessor: (_row: any, i: number) => {
return field.values.get(i);
return field.values[i];
},
sortType: selectSortType(field.type),
width: fieldTableOptions.width,
@ -188,7 +187,7 @@ export function getCellComponent(displayMode: TableCellDisplayMode, field: Field
}
if (field.type === FieldType.frame) {
const firstValue = field.values.get(0);
const firstValue = field.values[0];
if (isDataFrame(firstValue) && isTimeSeriesFrame(firstValue)) {
return SparklineCell;
}
@ -248,7 +247,7 @@ export function rowToFieldValue(row: any, field?: Field): string {
return '';
}
const fieldValue = field.values.get(row.index);
const fieldValue = field.values[row.index];
const displayValue = field.display ? field.display(fieldValue) : fieldValue;
const value = field.display ? formattedValueToString(displayValue) : displayValue;
@ -359,7 +358,7 @@ export function getFooterItems(
}
let newField = clone(data.field);
newField.values = new ArrayVector(values[data.id]);
newField.values = values[data.id];
newField.state = undefined;
data.field = newField;

View File

@ -1,4 +1,4 @@
import { ArrayVector, EventBus, FieldType } from '@grafana/data';
import { EventBus, FieldType } from '@grafana/data';
import { getTheme } from '@grafana/ui';
import { preparePlotConfigBuilder } from './utils';
@ -26,21 +26,21 @@ describe('when fill below to option is used', () => {
fields: [
{
config: {},
values: new ArrayVector([1667406900000, 1667407170000, 1667407185000]),
values: [1667406900000, 1667407170000, 1667407185000],
name: 'Time',
state: { multipleFrames: true, displayName: 'Time', origin: { fieldIndex: 0, frameIndex: 0 } },
type: FieldType.time,
},
{
config: { displayNameFromDS: 'Test1', custom: { fillBelowTo: 'Test2' }, min: 0, max: 100 },
values: new ArrayVector([1, 2, 3]),
values: [1, 2, 3],
name: 'Value',
state: { multipleFrames: true, displayName: 'Test1', origin: { fieldIndex: 1, frameIndex: 0 } },
type: FieldType.number,
},
{
config: { displayNameFromDS: 'Test2', min: 0, max: 100 },
values: new ArrayVector([4, 5, 6]),
values: [4, 5, 6],
name: 'Value',
state: { multipleFrames: true, displayName: 'Test2', origin: { fieldIndex: 1, frameIndex: 1 } },
type: FieldType.number,
@ -55,14 +55,14 @@ describe('when fill below to option is used', () => {
fields: [
{
config: {},
values: new ArrayVector([1667406900000, 1667407170000, 1667407185000]),
values: [1667406900000, 1667407170000, 1667407185000],
name: 'Time',
state: { multipleFrames: true, displayName: 'Time', origin: { fieldIndex: 0, frameIndex: 0 } },
type: FieldType.time,
},
{
config: { displayNameFromDS: 'Test1', custom: { fillBelowTo: 'Test2' }, min: 0, max: 100 },
values: new ArrayVector([1, 2, 3]),
values: [1, 2, 3],
name: 'Value',
state: { multipleFrames: true, displayName: 'Test1', origin: { fieldIndex: 1, frameIndex: 0 } },
type: FieldType.number,
@ -76,14 +76,14 @@ describe('when fill below to option is used', () => {
fields: [
{
config: {},
values: new ArrayVector([1667406900000, 1667407170000, 1667407185000]),
values: [1667406900000, 1667407170000, 1667407185000],
name: 'Time',
state: { multipleFrames: true, displayName: 'Time', origin: { fieldIndex: 0, frameIndex: 1 } },
type: FieldType.time,
},
{
config: { displayNameFromDS: 'Test2', min: 0, max: 100 },
values: new ArrayVector([1, 2, 3]),
values: [1, 2, 3],
name: 'Value',
state: { multipleFrames: true, displayName: 'Test2', origin: { fieldIndex: 1, frameIndex: 1 } },
type: FieldType.number,
@ -99,35 +99,35 @@ describe('when fill below to option is used', () => {
fields: [
{
config: {},
values: new ArrayVector([1667406900000, 1667407170000, 1667407185000]),
values: [1667406900000, 1667407170000, 1667407185000],
name: 'time',
state: { multipleFrames: true, displayName: 'time', origin: { fieldIndex: 0, frameIndex: 0 } },
type: FieldType.time,
},
{
config: { custom: { fillBelowTo: 'below_value1' } },
values: new ArrayVector([1, 2, 3]),
values: [1, 2, 3],
name: 'value1',
state: { multipleFrames: true, displayName: 'value1', origin: { fieldIndex: 1, frameIndex: 0 } },
type: FieldType.number,
},
{
config: { custom: { fillBelowTo: 'below_value2' } },
values: new ArrayVector([4, 5, 6]),
values: [4, 5, 6],
name: 'value2',
state: { multipleFrames: true, displayName: 'value2', origin: { fieldIndex: 2, frameIndex: 0 } },
type: FieldType.number,
},
{
config: {},
values: new ArrayVector([4, 5, 6]),
values: [4, 5, 6],
name: 'below_value1',
state: { multipleFrames: true, displayName: 'below_value1', origin: { fieldIndex: 1, frameIndex: 1 } },
type: FieldType.number,
},
{
config: {},
values: new ArrayVector([4, 5, 6]),
values: [4, 5, 6],
name: 'below_value2',
state: { multipleFrames: true, displayName: 'below_value2', origin: { fieldIndex: 2, frameIndex: 1 } },
type: FieldType.number,
@ -141,21 +141,21 @@ describe('when fill below to option is used', () => {
fields: [
{
config: {},
values: new ArrayVector([1667406900000, 1667407170000, 1667407185000]),
values: [1667406900000, 1667407170000, 1667407185000],
name: 'time',
state: { multipleFrames: true, displayName: 'time', origin: { fieldIndex: 0, frameIndex: 0 } },
type: FieldType.time,
},
{
config: { custom: { fillBelowTo: 'below_value1' } },
values: new ArrayVector([1, 2, 3]),
values: [1, 2, 3],
name: 'value1',
state: { multipleFrames: true, displayName: 'value1', origin: { fieldIndex: 1, frameIndex: 0 } },
type: FieldType.number,
},
{
config: { custom: { fillBelowTo: 'below_value2' } },
values: new ArrayVector([4, 5, 6]),
values: [4, 5, 6],
name: 'value2',
state: { multipleFrames: true, displayName: 'value2', origin: { fieldIndex: 2, frameIndex: 0 } },
type: FieldType.number,
@ -168,21 +168,21 @@ describe('when fill below to option is used', () => {
fields: [
{
config: {},
values: new ArrayVector([1667406900000, 1667407170000, 1667407185000]),
values: [1667406900000, 1667407170000, 1667407185000],
name: 'time',
state: { multipleFrames: true, displayName: 'time', origin: { fieldIndex: 0, frameIndex: 1 } },
type: FieldType.time,
},
{
config: {},
values: new ArrayVector([4, 5, 6]),
values: [4, 5, 6],
name: 'below_value1',
state: { multipleFrames: true, displayName: 'below_value1', origin: { fieldIndex: 1, frameIndex: 1 } },
type: FieldType.number,
},
{
config: {},
values: new ArrayVector([4, 5, 6]),
values: [4, 5, 6],
name: 'below_value2',
state: { multipleFrames: true, displayName: 'below_value2', origin: { fieldIndex: 2, frameIndex: 1 } },
type: FieldType.number,

View File

@ -3,7 +3,7 @@ import createMockRaf from 'mock-raf';
import React from 'react';
import uPlot from 'uplot';
import { ArrayVector, dateTime, FieldConfig, FieldType, MutableDataFrame } from '@grafana/data';
import { dateTime, FieldConfig, FieldType, MutableDataFrame } from '@grafana/data';
import { GraphFieldConfig, GraphDrawStyle } from '@grafana/schema';
import { UPlotChart } from './Plot';
@ -34,14 +34,14 @@ const mockData = () => {
data.addField({
type: FieldType.time,
name: 'Time',
values: new ArrayVector([1602630000000, 1602633600000, 1602637200000]),
values: [1602630000000, 1602633600000, 1602637200000],
config: {},
});
data.addField({
type: FieldType.number,
name: 'Value',
values: new ArrayVector([10, 20, 5]),
values: [10, 20, 5],
config: {
custom: {
drawStyle: GraphDrawStyle.Line,

View File

@ -114,9 +114,8 @@ export function getStackingGroups(frame: DataFrame) {
}
// will this be stacked up or down after any transforms applied
let vals = values.toArray();
let transform = custom.transform;
let stackDir = getStackDirection(transform, vals);
let stackDir = getStackDirection(transform, values);
let drawStyle = custom.drawStyle as GraphDrawStyle;
let drawStyle2 =
@ -174,7 +173,7 @@ export function preparePlotData2(
return;
}
let vals = field.values.toArray();
let vals = field.values;
for (let i = 0; i < dataLen; i++) {
if (vals[i] != null) {
@ -185,11 +184,11 @@ export function preparePlotData2(
});
frame.fields.forEach((field, i) => {
let vals = field.values.toArray();
let vals = field.values;
if (i === 0) {
if (field.type === FieldType.time) {
data[i] = ensureTimeField(field).values.toArray();
data[i] = ensureTimeField(field).values;
} else {
data[i] = vals;
}

View File

@ -1,13 +1,4 @@
import {
ArrayVector,
createTheme,
FieldType,
ThresholdsMode,
TimeRange,
toDataFrame,
dateTime,
DataFrame,
} from '@grafana/data';
import { createTheme, FieldType, ThresholdsMode, TimeRange, toDataFrame, dateTime, DataFrame } from '@grafana/data';
import { LegendDisplayMode, VizLegendOptions } from '@grafana/schema';
import {
@ -70,7 +61,7 @@ describe('prepare timeline graph', () => {
const out = info.frames![0];
const field = out.fields.find((f) => f.name === 'b');
expect(field?.values.toArray()).toMatchInlineSnapshot(`
expect(field?.values).toMatchInlineSnapshot(`
[
1,
1,
@ -94,7 +85,7 @@ describe('prepare timeline graph', () => {
}),
];
const result = prepareTimelineFields(frames, true, timeRange, theme);
expect(result.frames?.[0].fields[0].values.toArray()).toEqual([1, 2, 3, 4]);
expect(result.frames?.[0].fields[0].values).toEqual([1, 2, 3, 4]);
});
});
@ -103,7 +94,7 @@ describe('findNextStateIndex', () => {
const field = {
name: 'time',
type: FieldType.number,
values: new ArrayVector([1, undefined, undefined, 2, undefined, undefined]),
values: [1, undefined, undefined, 2, undefined, undefined],
config: {},
};
const result = findNextStateIndex(field, 0);
@ -114,7 +105,7 @@ describe('findNextStateIndex', () => {
const field = {
name: 'time',
type: FieldType.number,
values: new ArrayVector([1, undefined, undefined, 2, undefined, 3]),
values: [1, undefined, undefined, 2, undefined, 3],
config: {},
};
const result = findNextStateIndex(field, 5);
@ -125,7 +116,7 @@ describe('findNextStateIndex', () => {
const field = {
name: 'time',
type: FieldType.number,
values: new ArrayVector([1, undefined, undefined, 2, undefined, 3, undefined]),
values: [1, undefined, undefined, 2, undefined, 3, undefined],
config: {},
};
const result = findNextStateIndex(field, 5);
@ -136,19 +127,7 @@ describe('findNextStateIndex', () => {
const field = {
name: 'time',
type: FieldType.number,
values: new ArrayVector([
1,
undefined,
undefined,
3,
undefined,
undefined,
undefined,
undefined,
2,
undefined,
undefined,
]),
values: [1, undefined, undefined, 3, undefined, undefined, undefined, undefined, 2, undefined, undefined],
config: {},
};
const result = findNextStateIndex(field, 3);
@ -159,7 +138,7 @@ describe('findNextStateIndex', () => {
const field = {
name: 'time',
type: FieldType.number,
values: new ArrayVector([1, 3, 2]),
values: [1, 3, 2],
config: {},
};
@ -212,10 +191,10 @@ describe('prepareTimelineLegendItems', () => {
],
},
},
values: new ArrayVector([
values: [
1634092733455, 1634092763455, 1634092793455, 1634092823455, 1634092853455, 1634092883455, 1634092913455,
1634092943455, 1634092973455, 1634093003455,
]),
],
display: (value: string) => ({
text: value,
color: undefined,
@ -238,7 +217,7 @@ describe('prepareTimelineLegendItems', () => {
],
},
},
values: new ArrayVector(['< -∞', null, null, null, null, null, null, null, null, null]),
values: ['< -∞', null, null, null, null, null, null, null, null, null],
display: (value?: string) => ({
text: value || '',
color: 'green',

View File

@ -2,7 +2,6 @@ import React from 'react';
import uPlot from 'uplot';
import {
ArrayVector,
DataFrame,
DashboardCursorSync,
DataHoverPayload,
@ -371,7 +370,7 @@ export function mergeThresholdValues(field: Field, theme: GrafanaTheme2): Field
textToColor.set(items[i].label, items[i].color!);
}
let input = field.values.toArray();
let input = field.values;
const vals = new Array<String | undefined>(field.values.length);
if (thresholds.mode === ThresholdsMode.Percentage) {
const { min, max } = getFieldConfigWithMinMax(field);
@ -403,7 +402,7 @@ export function mergeThresholdValues(field: Field, theme: GrafanaTheme2): Field
},
},
type: FieldType.string,
values: new ArrayVector(vals),
values: vals,
display: (value) => ({
text: String(value),
color: textToColor.get(String(value)),
@ -571,7 +570,7 @@ export function getFieldLegendItem(fields: Field[], theme: GrafanaTheme2): VizLe
let stateColors: Map<string, string | undefined> = new Map();
fields.forEach((field) => {
field.values.toArray().forEach((v) => {
field.values.forEach((v) => {
let state = field.display!(v);
if (state.color) {
stateColors.set(state.text, state.color!);

View File

@ -54,7 +54,7 @@ export function getColorDimensionForField(
return {
field,
get: (index: number): string => getColor(field!.values.get(index)),
get: (index: number): string => getColor(field!.values[index]),
value: () => getColor(getLastNotNullFieldValue(field!)),
};
}

View File

@ -43,7 +43,7 @@ export function getResourceDimension(
const mapper = (v: string) => getPublicOrAbsoluteUrl(`${v}`);
return {
field,
get: (i) => mapper(field.values.get(i)),
get: (i) => mapper(field.values[i]),
value: () => mapper(getLastNotNullFieldValue(field)),
};
}
@ -60,7 +60,7 @@ export function getResourceDimension(
return {
field,
get: (index: number): string => getIcon(field.values.get(index)),
get: (index: number): string => getIcon(field.values[index]),
value: () => getIcon(getLastNotNullFieldValue(field)),
};
}

View File

@ -1,4 +1,4 @@
import { ArrayVector, DataFrame, FieldType } from '@grafana/data';
import { DataFrame, FieldType } from '@grafana/data';
import { getScalarDimension } from './scalar';
@ -14,7 +14,7 @@ describe('scalar dimensions', () => {
{
name: 'test',
type: FieldType.number,
values: new ArrayVector(values),
values: values,
config: {
min: -720,
max: 540,
@ -31,7 +31,7 @@ describe('scalar dimensions', () => {
mode: ScalarDimensionMode.Clamped,
});
const clamped = frame.fields[0].values.toArray().map((k, i) => supplier.get(i));
const clamped = frame.fields[0].values.map((k, i) => supplier.get(i));
expect(clamped).toEqual([0, 0, 0, 0, 0]);
});
it('clamps out of range values', () => {
@ -43,7 +43,7 @@ describe('scalar dimensions', () => {
{
name: 'test',
type: FieldType.number,
values: new ArrayVector(values),
values: values,
config: {
min: -720,
max: 540,
@ -60,7 +60,7 @@ describe('scalar dimensions', () => {
mode: ScalarDimensionMode.Clamped,
});
const clamped = frame.fields[0].values.toArray().map((k, i) => supplier.get(i));
const clamped = frame.fields[0].values.map((k, i) => supplier.get(i));
expect(clamped).toEqual([-360, 10, 360, 90, -210]);
});
@ -73,7 +73,7 @@ describe('scalar dimensions', () => {
{
name: 'test',
type: FieldType.number,
values: new ArrayVector(values),
values: values,
config: {
min: -721,
max: 540,
@ -90,7 +90,7 @@ describe('scalar dimensions', () => {
mode: ScalarDimensionMode.Mod,
});
const remainder = frame.fields[0].values.toArray().map((k, i) => supplier.get(i));
const remainder = frame.fields[0].values.map((k, i) => supplier.get(i));
expect(remainder).toEqual([-1, 10, 180, 30, -210]);
});
});

View File

@ -45,7 +45,7 @@ export function getScalarDimensionForField(
}
const get = (i: number) => {
const v = field.values.get(i);
const v = field.values[i];
if (v === null || typeof v !== 'number') {
return 0;
}

View File

@ -1,4 +1,4 @@
import { ArrayVector, DataFrame, FieldType } from '@grafana/data';
import { DataFrame, FieldType } from '@grafana/data';
import { ScaleDimensionConfig } from '@grafana/schema';
import { getScaledDimension, validateScaleConfig } from './scale';
@ -45,11 +45,11 @@ describe('scale dimensions', () => {
name: 'a',
length: values.length,
fields: [
{ name: 'time', type: FieldType.number, values: new ArrayVector(values), config: {} },
{ name: 'time', type: FieldType.number, values: values, config: {} },
{
name: 'hello',
type: FieldType.number,
values: new ArrayVector(values),
values: values,
config: {
min: -10,
max: 10,
@ -64,7 +64,7 @@ describe('scale dimensions', () => {
field: 'hello',
fixed: 0,
});
const scaled = frame.fields[0].values.toArray().map((k, i) => supplier.get(i));
const scaled = frame.fields[0].values.map((k, i) => supplier.get(i));
expect(scaled).toEqual([-1, -1, -0.5, 0, 0.5, 1, 1]);
});
});

View File

@ -56,7 +56,7 @@ export function getScaledDimensionForField(
}
const get = (i: number) => {
const value = field.values.get(i);
const value = field.values[i];
let percent = 0;
if (value !== -Infinity) {
percent = (value - info.min!) / info.delta;

View File

@ -42,7 +42,7 @@ export function getTextDimensionForField(
}
return {
field,
get: (i) => disp(field.values.get(i)),
get: (i) => disp(field.values[i]),
value: () => disp(getLastNotNullFieldValue(field)),
};
}
@ -59,7 +59,7 @@ export function getTextDimensionForField(
let disp = (v: unknown) => formattedValueToString(field.display!(v));
return {
field,
get: (i) => disp(field.values.get(i)),
get: (i) => disp(field.values[i]),
value: () => disp(getLastNotNullFieldValue(field)),
};
}

View File

@ -82,7 +82,7 @@ describe('Read GeoJSON', () => {
expect(
frame.fields.reduce<Record<string, unknown[]>>((acc, v, idx, arr) => {
if (v.type !== FieldType.geo) {
acc[v.name] = v.values.toArray();
acc[v.name] = v.values;
}
return acc;
}, {})

View File

@ -1,7 +1,7 @@
import GeoJSON from 'ol/format/GeoJSON';
import { Geometry } from 'ol/geom';
import { ArrayVector, DataFrame, Field, FieldType, getFieldTypeFromValue } from '@grafana/data';
import { DataFrame, Field, FieldType, getFieldTypeFromValue } from '@grafana/data';
interface FieldInfo {
values: any[];
@ -75,7 +75,7 @@ export function frameFromGeoJSON(body: Document | Element | Object | string): Da
fields.push({
name: getBestName('id', '_id', '__id'),
type,
values: new ArrayVector(idfield.values),
values: idfield.values,
config: {},
});
}
@ -84,7 +84,7 @@ export function frameFromGeoJSON(body: Document | Element | Object | string): Da
fields.push({
name: getBestName('geo', 'geometry'),
type: FieldType.geo,
values: new ArrayVector(geo),
values: geo,
config: {},
});
@ -97,7 +97,7 @@ export function frameFromGeoJSON(body: Document | Element | Object | string): Da
fields.push({
name,
type,
values: new ArrayVector(info.values),
values: info.values,
config: {},
});
}

View File

@ -1,7 +1,7 @@
import { Geometry, GeometryCollection, LineString, Point } from 'ol/geom';
import { fromLonLat } from 'ol/proj';
import { ArrayVector, Field, FieldConfig, FieldType } from '@grafana/data';
import { Field, FieldConfig, FieldType } from '@grafana/data';
import { getCenterPoint } from 'app/features/transformers/spatial/utils';
import { Gazetteer } from '../gazetteer/gazetteer';
@ -12,15 +12,13 @@ export function pointFieldFromGeohash(geohash: Field<string>): Field<Geometry |
return {
name: geohash.name ?? 'Point',
type: FieldType.geo,
values: new ArrayVector<any>(
geohash.values.toArray().map((v) => {
const coords = decodeGeohash(v);
if (coords) {
return new Point(fromLonLat(coords));
}
return undefined;
})
),
values: geohash.values.map((v) => {
const coords = decodeGeohash(v);
if (coords) {
return new Point(fromLonLat(coords));
}
return undefined;
}),
config: hiddenTooltipField,
};
}
@ -28,8 +26,8 @@ export function pointFieldFromGeohash(geohash: Field<string>): Field<Geometry |
export function pointFieldFromLonLat(lon: Field, lat: Field): Field<Geometry | undefined> {
const buffer = new Array<Point>(lon.values.length);
for (let i = 0; i < lon.values.length; i++) {
const longitude = lon.values.get(i);
const latitude = lat.values.get(i);
const longitude = lon.values[i];
const latitude = lat.values[i];
// TODO: Add unit tests to thoroughly test out edge cases
// If longitude or latitude are null, don't add them to buffer
@ -43,7 +41,7 @@ export function pointFieldFromLonLat(lon: Field, lat: Field): Field<Geometry | u
return {
name: 'Point',
type: FieldType.geo,
values: new ArrayVector(buffer),
values: buffer,
config: hiddenTooltipField,
};
}
@ -52,12 +50,12 @@ export function getGeoFieldFromGazetteer(gaz: Gazetteer, field: Field<string>):
const count = field.values.length;
const geo = new Array<Geometry | undefined>(count);
for (let i = 0; i < count; i++) {
geo[i] = gaz.find(field.values.get(i))?.geometry();
geo[i] = gaz.find(field.values[i])?.geometry();
}
return {
name: 'Geometry',
type: FieldType.geo,
values: new ArrayVector(geo),
values: geo,
config: hiddenTooltipField,
};
}
@ -66,8 +64,8 @@ export function createGeometryCollection(
src: Field<Geometry | undefined>,
dest: Field<Geometry | undefined>
): Field<Geometry | undefined> {
const v0 = src.values.toArray();
const v1 = dest.values.toArray();
const v0 = src.values;
const v1 = dest.values;
if (!v0 || !v1) {
throw 'missing src/dest';
}
@ -91,7 +89,7 @@ export function createGeometryCollection(
return {
name: 'Geometry',
type: FieldType.geo,
values: new ArrayVector(geo),
values: geo,
config: hiddenTooltipField,
};
}
@ -100,8 +98,8 @@ export function createLineBetween(
src: Field<Geometry | undefined>,
dest: Field<Geometry | undefined>
): Field<Geometry | undefined> {
const v0 = src.values.toArray();
const v1 = dest.values.toArray();
const v0 = src.values;
const v1 = dest.values;
if (!v0 || !v1) {
throw 'missing src/dest';
}
@ -121,7 +119,7 @@ export function createLineBetween(
return {
name: 'Geometry',
type: FieldType.geo,
values: new ArrayVector(geo),
values: geo,
config: hiddenTooltipField,
};
}

View File

@ -132,12 +132,12 @@ export function frameAsGazetter(frame: DataFrame, opts: { path: string; keys?: s
isPoint = true;
}
} else {
isPoint = geo.values.get(0)?.getType() === 'Point';
isPoint = geo.values[0]?.getType() === 'Point';
}
const lookup = new Map<string, number>();
keys.forEach((f) => {
f.values.toArray().forEach((k, idx) => {
f.values.forEach((k, idx) => {
const str = `${k}`;
lookup.set(str.toUpperCase(), idx);
lookup.set(str, idx);
@ -149,7 +149,7 @@ export function frameAsGazetter(frame: DataFrame, opts: { path: string; keys?: s
find: (k) => {
const index = lookup.get(k);
if (index != null) {
const g = geo?.values.get(index);
const g = geo?.values[index];
return {
frame,
index,

View File

@ -26,7 +26,7 @@ export class FrameVectorSource<T extends Geometry = Geometry> extends VectorSour
new Feature({
frame,
rowIndex: i,
geometry: info.field.values.get(i) as T,
geometry: info.field.values[i] as T,
})
);
}
@ -45,7 +45,7 @@ export class FrameVectorSource<T extends Geometry = Geometry> extends VectorSour
//eslint-disable-next-line
const field = info.field as unknown as Field<Point>;
const geometry = new LineString(field.values.toArray().map((p) => p.getCoordinates())) as Geometry;
const geometry = new LineString(field.values.map((p) => p.getCoordinates())) as Geometry;
this.addFeatureInternal(
new Feature({
frame,

View File

@ -33,7 +33,7 @@ describe('handle location parsing', () => {
const info = getGeometryField(frame, matchers);
expect(info.field!.type).toBe(FieldType.geo);
expect(info.field!.values.toArray().map((p) => toLonLat((p as Point).getCoordinates()))).toMatchInlineSnapshot(`
expect(info.field!.values.map((p) => toLonLat((p as Point).getCoordinates()))).toMatchInlineSnapshot(`
[
[
-122.01416015625001,
@ -59,7 +59,7 @@ describe('handle location parsing', () => {
const matchers = await getLocationMatchers();
const geo = getGeometryField(frame, matchers).field!;
expect(geo.values.toArray().map((p) => toLonLat((p as Point).getCoordinates()))).toMatchInlineSnapshot(`
expect(geo.values.map((p) => toLonLat((p as Point).getCoordinates()))).toMatchInlineSnapshot(`
[
[
0,
@ -86,7 +86,7 @@ describe('handle location parsing', () => {
mode: FrameGeometrySourceMode.Auto,
});
const geo = getGeometryField(frame, matchers).field!;
expect(geo.values.toArray().map((p) => toLonLat((p as Point).getCoordinates()))).toMatchInlineSnapshot(`
expect(geo.values.map((p) => toLonLat((p as Point).getCoordinates()))).toMatchInlineSnapshot(`
[
[
-122.01416015625001,

View File

@ -202,7 +202,7 @@ describe('BarChart utils', () => {
const displayValues = assertIsDefined('viz' in result ? result : null);
const field = displayValues.viz[0].fields[1];
expect(field.values.toArray()).toMatchInlineSnapshot(`
expect(field.values).toMatchInlineSnapshot(`
[
-10,
null,
@ -215,7 +215,7 @@ describe('BarChart utils', () => {
const displayLegendValuesAsc = assertIsDefined('legend' in result ? result : null).legend;
const legendField = displayLegendValuesAsc.fields[1];
expect(legendField.values.toArray()).toMatchInlineSnapshot(`
expect(legendField.values).toMatchInlineSnapshot(`
[
-10,
null,

View File

@ -2,7 +2,6 @@ import { orderBy } from 'lodash';
import uPlot, { Padding } from 'uplot';
import {
ArrayVector,
DataFrame,
Field,
FieldType,
@ -318,7 +317,7 @@ function getRotationPadding(
const fontSize = UPLOT_AXIS_FONT_SIZE;
const displayProcessor = frame.fields[0].display;
const getProcessedValue = (i: number) => {
return displayProcessor ? displayProcessor(values.get(i)) : values.get(i);
return displayProcessor ? displayProcessor(values[i]) : values[i];
};
let maxLength = 0;
for (let i = 0; i < values.length; i++) {
@ -432,14 +431,12 @@ export function prepareBarChartDisplayValues(
},
},
},
values: new ArrayVector(
field.values.toArray().map((v) => {
if (!(Number.isFinite(v) || v == null)) {
return null;
}
return v;
})
),
values: field.values.map((v) => {
if (!(Number.isFinite(v) || v == null)) {
return null;
}
return v;
}),
};
if (options.stacking === StackingMode.Percent) {

View File

@ -81,7 +81,7 @@ describe('Candlestick data', () => {
expect(info.names.close).toMatchInlineSnapshot(`"Next open"`);
// Close should be offset by one and dupliate last point
expect({ open: info.open!.values.toArray(), close: info.close!.values.toArray() }).toMatchInlineSnapshot(`
expect({ open: info.open!.values, close: info.close!.values }).toMatchInlineSnapshot(`
{
"close": [
5,
@ -117,8 +117,8 @@ describe('Candlestick data', () => {
theme
)!;
expect(info.open!.values.toArray()).toEqual([1, 1, 2, 3, 4]);
expect(info.close!.values.toArray()).toEqual([1, 2, 3, 4, 5]);
expect(info.open!.values).toEqual([1, 1, 2, 3, 4]);
expect(info.close!.values).toEqual([1, 2, 3, 4, 5]);
});
it('will unmap high & low fields in volume-only mode', () => {

View File

@ -1,5 +1,4 @@
import {
ArrayVector,
DataFrame,
Field,
FieldType,
@ -153,11 +152,11 @@ export function prepareCandlestickFields(
// Use next open as 'close' value
if (data.open && !data.close && !fieldMap.close) {
const values = data.open.values.toArray().slice(1);
const values = data.open.values.slice(1);
values.push(values[values.length - 1]); // duplicate last value
data.close = {
...data.open,
values: new ArrayVector(values),
values: values,
name: 'Next open',
state: undefined,
};
@ -168,12 +167,12 @@ export function prepareCandlestickFields(
// Use previous close as 'open' value
if (data.close && !data.open && !fieldMap.open) {
const values = data.close.values.toArray().slice();
const values = data.close.values.slice();
values.unshift(values[0]); // duplicate first value
values.length = frame.length;
data.open = {
...data.close,
values: new ArrayVector(values),
values: values,
name: 'Previous close',
state: undefined,
};

View File

@ -1,4 +1,4 @@
import { ArrayVector, Field, FieldType, MutableDataFrame } from '@grafana/data';
import { Field, FieldType, MutableDataFrame } from '@grafana/data';
import { getTooltipData } from './FlameGraphTooltip';
import { FlameGraphDataContainer } from './dataTransform';
@ -89,6 +89,6 @@ function makeField(name: string, unit: string, values: number[]): Field {
config: {
unit,
},
values: new ArrayVector(values),
values: values,
};
}

View File

@ -75,7 +75,7 @@ export class FlameGraphDataContainer {
text: value + '',
numeric: 0,
});
this.uniqueLabels = [...new Set<string>(this.labelField.values.toArray())];
this.uniqueLabels = [...new Set<string>(this.labelField.values)];
}
this.valueDisplayProcessor = getDisplayProcessor({
@ -85,27 +85,27 @@ export class FlameGraphDataContainer {
}
getLabel(index: number) {
return this.labelDisplayProcessor(this.labelField.values.get(index)).text;
return this.labelDisplayProcessor(this.labelField.values[index]).text;
}
getLevel(index: number) {
return this.levelField.values.get(index);
return this.levelField.values[index];
}
getValue(index: number) {
return this.valueField.values.get(index);
return this.valueField.values[index];
}
getValueDisplay(index: number) {
return this.valueDisplayProcessor(this.valueField.values.get(index));
return this.valueDisplayProcessor(this.valueField.values[index]);
}
getSelf(index: number) {
return this.selfField.values.get(index);
return this.selfField.values[index];
}
getSelfDisplay(index: number) {
return this.valueDisplayProcessor(this.selfField.values.get(index));
return this.valueDisplayProcessor(this.selfField.values[index]);
}
getUniqueLabels() {

View File

@ -2,15 +2,7 @@ import { css } from '@emotion/css';
import React from 'react';
import AutoSizer from 'react-virtualized-auto-sizer';
import {
applyFieldOverrides,
ArrayVector,
CoreApp,
DataFrame,
DataLinkClickEvent,
Field,
FieldType,
} from '@grafana/data';
import { applyFieldOverrides, CoreApp, DataFrame, DataLinkClickEvent, Field, FieldType } from '@grafana/data';
import { config } from '@grafana/runtime';
import { Table, useStyles2 } from '@grafana/ui';
@ -93,10 +85,10 @@ function buildTableDataFrame(
table[label].total = table[label].total ? table[label].total + value : value;
}
const symbolField = {
const symbolField: Field = {
type: FieldType.string,
name: 'Symbol',
values: new ArrayVector(),
values: [],
config: {
custom: { width: width - TOP_TABLE_COLUMN_WIDTH * 2 },
links: [
@ -113,24 +105,24 @@ function buildTableDataFrame(
},
};
const selfField = {
const selfField: Field = {
type: FieldType.number,
name: 'Self',
values: new ArrayVector(),
values: [],
config: { unit: data.selfField.config.unit, custom: { width: TOP_TABLE_COLUMN_WIDTH } },
};
const totalField = {
const totalField: Field = {
type: FieldType.number,
name: 'Total',
values: new ArrayVector(),
values: [],
config: { unit: data.valueField.config.unit, custom: { width: TOP_TABLE_COLUMN_WIDTH } },
};
for (let key in table) {
symbolField.values.add(key);
selfField.values.add(table[key].self);
totalField.values.add(table[key].total);
symbolField.values.push(key);
selfField.values.push(table[key].self);
totalField.values.push(table[key].total);
}
const frame = { fields: [symbolField, selfField, totalField], length: symbolField.values.length };

View File

@ -174,7 +174,7 @@ export const dynamicGeoJSONLayer: MapLayerRegistryItem<DynamicGeoJSONMapperConfi
const field = findField(frame, config.idField);
if (field) {
idToIdx.clear();
field.values.toArray().forEach((v, i) => idToIdx.set(v, i));
field.values.forEach((v, i) => idToIdx.set(v, i));
}
style.dims = getStyleDimension(frame, style, theme, config.dataStyle);

View File

@ -56,7 +56,7 @@ export const lastPointTracker: MapLayerRegistryItem<LastPointConfig> = {
if (!out.field) {
return; // ???
}
point.setGeometry(out.field.values.get(frame.length - 1));
point.setGeometry(out.field.values[frame.length - 1]);
}
},
};

View File

@ -171,13 +171,13 @@ export const photosLayer: MapLayerRegistryItem<PhotoConfig> = {
if (config.src) {
const srcField: Field | undefined = findField(frame, config.src);
if (srcField) {
images = srcField?.values.toArray();
images = srcField?.values;
}
} else {
for (let i = 0; i < frame.fields.length; i++) {
const field = frame.fields[i];
if (field.type === FieldType.string) {
images = field.values.toArray();
images = field.values;
break;
}
}

View File

@ -229,7 +229,7 @@ export const routeLayer: MapLayerRegistryItem<RouteConfig> = {
if (frame && time) {
const timeField = frame.fields.find((f) => f.name === TIME_SERIES_TIME_FIELD_NAME);
if (timeField) {
const timestamps: number[] = timeField.values.toArray();
const timestamps: number[] = timeField.values;
const pointIdx = findNearestTimeIndex(timestamps, time);
if (pointIdx !== null) {
const out = getGeometryField(frame, location);

View File

@ -43,7 +43,7 @@ export class DataProcessor {
const datapoints = [];
for (let r = 0; r < series.length; r++) {
datapoints.push([field.values.get(r), dateTime(timeField.values.get(r)).valueOf()]);
datapoints.push([field.values[r], dateTime(timeField.values[r]).valueOf()]);
}
list.push(this.toTimeSeries(field, name, i, j, datapoints, list.length, range));

View File

@ -371,7 +371,7 @@ class GraphElement {
return dataIndex;
}
const correctIndex = timeField.values.toArray().findIndex((value) => value === ts);
const correctIndex = timeField.values.findIndex((value) => value === ts);
return correctIndex > -1 ? correctIndex : dataIndex;
}

View File

@ -51,9 +51,9 @@ const HeatmapHoverCell = ({ data, hover, showHistogram }: Props) => {
return `${v}`;
};
const xVals = xField?.values.toArray();
const yVals = yField?.values.toArray();
const countVals = countField?.values.toArray();
const xVals = xField?.values;
const yVals = yField?.values;
const countVals = countField?.values;
// labeled buckets
const meta = readHeatmapRowsCustomMeta(data.heatmap);
@ -122,7 +122,7 @@ const HeatmapHoverCell = ({ data, hover, showHistogram }: Props) => {
for (const field of visibleFields ?? []) {
// TODO: Currently always undefined? (getLinks)
if (field.getLinks) {
const v = field.values.get(index);
const v = field.values[index];
const disp = field.display ? field.display(v) : { text: `${v}`, numeric: +v };
field.getLinks({ calculatedValue: disp, valueRowIndex: index }).forEach((link) => {

View File

@ -68,22 +68,20 @@ export const HeatmapPanel = ({
const meta = readHeatmapRowsCustomMeta(info.heatmap);
if (info.exemplars?.length && meta.yMatchWithLabel) {
exemplarsXFacet = info.exemplars?.fields[0].values.toArray();
exemplarsXFacet = info.exemplars?.fields[0].values;
// ordinal/labeled heatmap-buckets?
const hasLabeledY = meta.yOrdinalDisplay != null;
if (hasLabeledY) {
let matchExemplarsBy = info.exemplars?.fields
.find((field) => field.name === meta.yMatchWithLabel)!
.values.toArray();
let matchExemplarsBy = info.exemplars?.fields.find((field) => field.name === meta.yMatchWithLabel)!.values;
exemplarsyFacet = matchExemplarsBy.map((label) => meta.yOrdinalLabel?.indexOf(label)) as number[];
} else {
exemplarsyFacet = info.exemplars?.fields[1].values.toArray() as number[]; // "Value" field
exemplarsyFacet = info.exemplars?.fields[1].values as number[]; // "Value" field
}
}
return [null, info.heatmap?.fields.map((f) => f.values.toArray()), [exemplarsXFacet, exemplarsyFacet]];
return [null, info.heatmap?.fields.map((f) => f.values), [exemplarsXFacet, exemplarsyFacet]];
}, [info.heatmap, info.exemplars]);
const palette = useMemo(() => quantizeScheme(options.color, theme), [options.color, theme]);

View File

@ -146,7 +146,7 @@ const getSparseHeatmapData = (
const disp = updateFieldDisplay(frame.fields[3], options.cellValues, theme);
let [minValue, maxValue] = boundedMinMax(
frame.fields[3].values.toArray(),
frame.fields[3].values,
options.color.min,
options.color.max,
options.filterValues?.le,
@ -233,8 +233,8 @@ const getDenseHeatmapData = (
// y: 3,4,5,6,3,4,5,6
// count: 0,0,0,7,0,3,0,1
const xs = frame.fields[0].values.toArray();
const ys = frame.fields[1].values.toArray();
const xs = frame.fields[0].values;
const ys = frame.fields[1].values;
const dlen = xs.length;
// below is literally copy/paste from the pathBuilder code in utils.ts
@ -245,7 +245,7 @@ const getDenseHeatmapData = (
let xBinIncr = xs[yBinQty] - xs[0];
let [minValue, maxValue] = boundedMinMax(
valueField.values.toArray(),
valueField.values,
options.color.min,
options.color.max,
options.filterValues?.le,

View File

@ -47,7 +47,7 @@ export interface HistogramProps extends Themeable2 {
export function getBucketSize(frame: DataFrame) {
// assumes BucketMin is fields[0] and BucktMax is fields[1]
return frame.fields[1].values.get(0) - frame.fields[0].values.get(0);
return frame.fields[1].values[0] - frame.fields[0].values[0];
}
const prepConfig = (frame: DataFrame, theme: GrafanaTheme2) => {
@ -221,7 +221,7 @@ const preparePlotData = (frame: DataFrame) => {
for (const field of frame.fields) {
if (field.name !== histogramFrameBucketMaxFieldName) {
data.push(field.values.toArray());
data.push(field.values);
}
}

View File

@ -1,7 +1,7 @@
import { render, screen } from '@testing-library/react';
import React from 'react';
import { ArrayVector, FieldType } from '@grafana/data/src';
import { FieldType } from '@grafana/data/src';
import { Node } from './Node';
@ -50,7 +50,7 @@ const nodeDatum = {
subTitle: 'node subtitle',
dataFrameRowIndex: 0,
incoming: 0,
mainStat: { name: 'stat', values: new ArrayVector([1234]), type: FieldType.number, config: {} },
secondaryStat: { name: 'stat2', values: new ArrayVector([9876]), type: FieldType.number, config: {} },
mainStat: { name: 'stat', values: [1234], type: FieldType.number, config: {} },
secondaryStat: { name: 'stat2', values: [9876], type: FieldType.number, config: {} },
arcSections: [],
};

View File

@ -133,13 +133,11 @@ function NodeContents({ node, hovering }: { node: NodeDatum; hovering: HoverStat
) : (
<foreignObject x={node.x - (isHovered ? 100 : 35)} y={node.y - 15} width={isHovered ? '200' : '70'} height="40">
<div className={cx(styles.statsText, isHovered && styles.textHovering)}>
<span>
{node.mainStat && statToString(node.mainStat.config, node.mainStat.values.get(node.dataFrameRowIndex))}
</span>
<span>{node.mainStat && statToString(node.mainStat.config, node.mainStat.values[node.dataFrameRowIndex])}</span>
<br />
<span>
{node.secondaryStat &&
statToString(node.secondaryStat.config, node.secondaryStat.values.get(node.dataFrameRowIndex))}
statToString(node.secondaryStat.config, node.secondaryStat.values[node.dataFrameRowIndex])}
</span>
</div>
</foreignObject>
@ -151,7 +149,7 @@ function NodeContents({ node, hovering }: { node: NodeDatum; hovering: HoverStat
*/
function ColorCircle(props: { node: NodeDatum }) {
const { node } = props;
const fullStat = node.arcSections.find((s) => s.values.get(node.dataFrameRowIndex) >= 1);
const fullStat = node.arcSections.find((s) => s.values[node.dataFrameRowIndex] >= 1);
const theme = useTheme2();
if (fullStat) {
@ -168,7 +166,7 @@ function ColorCircle(props: { node: NodeDatum }) {
);
}
const nonZero = node.arcSections.filter((s) => s.values.get(node.dataFrameRowIndex) !== 0);
const nonZero = node.arcSections.filter((s) => s.values[node.dataFrameRowIndex] !== 0);
if (nonZero.length === 0) {
// Fallback if no arc is defined
return (
@ -189,7 +187,7 @@ function ColorCircle(props: { node: NodeDatum }) {
}>(
(acc, section, index) => {
const color = section.config.color?.fixedColor || '';
const value = section.values.get(node.dataFrameRowIndex);
const value = section.values[node.dataFrameRowIndex];
const el = (
<ArcSection
@ -254,8 +252,8 @@ function ArcSection({
function getColor(field: Field, index: number, theme: GrafanaTheme2): string {
if (!field.config.color) {
return field.values.get(index);
return field.values[index];
}
return getFieldColorModeForField(field).getCalculator(field, theme)(0, field.values.get(index));
return getFieldColorModeForField(field).getCalculator(field, theme)(0, field.values[index]);
}

View File

@ -177,7 +177,7 @@ function FieldRow({ field, index }: { field: Field; index: number }) {
return (
<HeaderRow
label={field.config?.displayName || field.name}
value={statToString(field.config, field.values.get(index) || '')}
value={statToString(field.config, field.values[index] || '')}
/>
);
}
@ -200,7 +200,7 @@ function NodeHeader({ node, nodes }: { node: NodeDatum; nodes?: DataFrame }) {
if (nodes) {
const fields = getNodeFields(nodes);
for (const f of [fields.title, fields.subTitle, fields.mainStat, fields.secondaryStat, ...fields.details]) {
if (f && f.values.get(node.dataFrameRowIndex)) {
if (f && f.values[node.dataFrameRowIndex]) {
rows.push(<FieldRow field={f} index={node.dataFrameRowIndex} />);
}
}
@ -227,8 +227,8 @@ function NodeHeader({ node, nodes }: { node: NodeDatum; nodes?: DataFrame }) {
function EdgeHeader(props: { edge: EdgeDatum; edges: DataFrame }) {
const index = props.edge.dataFrameRowIndex;
const fields = getEdgeFields(props.edges);
const valueSource = fields.source?.values.get(index) || '';
const valueTarget = fields.target?.values.get(index) || '';
const valueSource = fields.source?.values[index] || '';
const valueTarget = fields.target?.values[index] || '';
const rows = [];
if (valueSource && valueTarget) {
@ -236,7 +236,7 @@ function EdgeHeader(props: { edge: EdgeDatum; edges: DataFrame }) {
}
for (const f of [fields.mainStat, fields.secondaryStat, ...fields.details]) {
if (f && f.values.get(index)) {
if (f && f.values[index]) {
rows.push(<FieldRow field={f} index={index} />);
}
}

View File

@ -122,7 +122,7 @@ export function processNodes(
// Create the nodes here
const nodesMap: { [id: string]: NodeDatum } = {};
for (let i = 0; i < nodeFields.id.values.length; i++) {
const id = nodeFields.id.values.get(i);
const id = nodeFields.id.values[i];
nodesMap[id] = makeNodeDatum(id, nodeFields, i);
}
@ -167,12 +167,12 @@ export function processNodes(
// they are numbers. Here we just sum all incoming edges to get the final value for node.
if (computableField(edgeFields.mainStat)) {
nodesMap[target.id].mainStatNumeric =
(nodesMap[target.id].mainStatNumeric ?? 0) + edgeFields.mainStat!.values.get(i);
(nodesMap[target.id].mainStatNumeric ?? 0) + edgeFields.mainStat!.values[i];
}
if (computableField(edgeFields.secondaryStat)) {
nodesMap[target.id].secondaryStatNumeric =
(nodesMap[target.id].secondaryStatNumeric ?? 0) + edgeFields.secondaryStat!.values.get(i);
(nodesMap[target.id].secondaryStatNumeric ?? 0) + edgeFields.secondaryStat!.values[i];
}
// We are adding incoming edges count, so we can later on find out which nodes are the roots
@ -199,20 +199,18 @@ function processEdges(edges: DataFrame, edgeFields: EdgeFields): EdgeDatum[] {
throw new Error('id field is required for edges data frame.');
}
return edgeFields.id.values.toArray().map((id, index) => {
const target = edgeFields.target?.values.get(index);
const source = edgeFields.source?.values.get(index);
return edgeFields.id.values.map((id, index) => {
const target = edgeFields.target?.values[index];
const source = edgeFields.source?.values[index];
return {
id,
dataFrameRowIndex: index,
source,
target,
mainStat: edgeFields.mainStat
? statToString(edgeFields.mainStat.config, edgeFields.mainStat.values.get(index))
: '',
mainStat: edgeFields.mainStat ? statToString(edgeFields.mainStat.config, edgeFields.mainStat.values[index]) : '',
secondaryStat: edgeFields.secondaryStat
? statToString(edgeFields.secondaryStat.config, edgeFields.secondaryStat.values.get(index))
? statToString(edgeFields.secondaryStat.config, edgeFields.secondaryStat.values[index])
: '',
};
});
@ -269,8 +267,8 @@ function normalizeStatsForNodes(nodesMap: { [id: string]: NodeDatumFromEdge }, e
}
function makeNodeDatumsFromEdge(edgeFields: EdgeFields, index: number) {
const targetId = edgeFields.target?.values.get(index);
const sourceId = edgeFields.source?.values.get(index);
const targetId = edgeFields.target?.values[index];
const sourceId = edgeFields.source?.values[index];
return {
target: makeSimpleNodeDatum(targetId, index),
source: makeSimpleNodeDatum(sourceId, index),
@ -291,15 +289,15 @@ function makeSimpleNodeDatum(name: string, index: number): NodeDatumFromEdge {
function makeNodeDatum(id: string, nodeFields: NodeFields, index: number): NodeDatum {
return {
id: id,
title: nodeFields.title?.values.get(index) || '',
subTitle: nodeFields.subTitle?.values.get(index) || '',
title: nodeFields.title?.values[index] || '',
subTitle: nodeFields.subTitle?.values[index] || '',
dataFrameRowIndex: index,
incoming: 0,
mainStat: nodeFields.mainStat,
secondaryStat: nodeFields.secondaryStat,
arcSections: nodeFields.arc,
color: nodeFields.color,
icon: nodeFields.icon?.values.get(index) || '',
icon: nodeFields.icon?.values[index] || '',
};
}

View File

@ -85,7 +85,7 @@ describe('prepare timeseries graph', () => {
const frames = prepareGraphableFields([df], createTheme());
const field = frames![0].fields.find((f) => f.name === 'a');
expect(field!.values.toArray()).toMatchInlineSnapshot(`
expect(field!.values).toMatchInlineSnapshot(`
[
-10,
null,
@ -106,7 +106,7 @@ describe('prepare timeseries graph', () => {
const frames = prepareGraphableFields([df], createTheme());
const field = frames![0].fields.find((f) => f.name === 'a');
expect(field!.values.toArray()).toMatchInlineSnapshot(`
expect(field!.values).toMatchInlineSnapshot(`
[
1,
null,
@ -130,7 +130,7 @@ describe('prepare timeseries graph', () => {
const frames = prepareGraphableFields([df], createTheme());
const field = frames![0].fields.find((f) => f.name === 'a');
expect(field!.values.toArray()).toMatchInlineSnapshot(`
expect(field!.values).toMatchInlineSnapshot(`
[
1,
20,

View File

@ -1,5 +1,4 @@
import {
ArrayVector,
DataFrame,
Field,
FieldType,
@ -47,7 +46,7 @@ export function prepareGraphableFields(
// this mutates (once)
for (let frame of series) {
for (let field of frame.fields) {
if (field.type === FieldType.time && typeof field.values.get(0) !== 'number') {
if (field.type === FieldType.time && typeof field.values[0] !== 'number') {
field.values = convertFieldType(field, { destinationType: FieldType.time }).values;
}
}
@ -85,14 +84,12 @@ export function prepareGraphableFields(
hasValueField = useNumericX ? fieldIdx > 0 : true;
copy = {
...field,
values: new ArrayVector(
field.values.toArray().map((v) => {
if (!(Number.isFinite(v) || v == null)) {
return null;
}
return v;
})
),
values: field.values.map((v) => {
if (!(Number.isFinite(v) || v == null)) {
return null;
}
return v;
}),
};
fields.push(copy);
@ -100,7 +97,7 @@ export function prepareGraphableFields(
case FieldType.string:
copy = {
...field,
values: new ArrayVector(field.values.toArray()),
values: field.values,
};
fields.push(copy);

View File

@ -123,10 +123,10 @@ function getScatterSeries(
const index = dims.pointColorIndex;
pointColor = (frame: DataFrame) => {
// Yes we can improve this later
return frame.fields[index].values.toArray().map((v) => disp(v).color!);
return frame.fields[index].values.map((v) => disp(v).color!);
};
} else {
seriesColor = pointColorMode.getCalculator(f, config.theme2)(f.values.get(0), 1);
seriesColor = pointColorMode.getCalculator(f, config.theme2)(f.values[0], 1);
pointColor = () => seriesColor;
}
}
@ -675,8 +675,8 @@ const prepConfig = (
let { fields } = frames[i];
return f.y.map((yIndex, frameSeriesIndex) => {
let xValues = fields[f.x[frameSeriesIndex]].values.toArray();
let yValues = fields[f.y[frameSeriesIndex]].values.toArray();
let xValues = fields[f.x[frameSeriesIndex]].values;
let yValues = fields[f.y[frameSeriesIndex]].values;
let sizeValues = f.size![frameSeriesIndex](frames[i]);
if (!Array.isArray(sizeValues)) {
@ -719,8 +719,8 @@ export function prepData(info: ScatterPanelInfo, data: DataFrame[], from?: numbe
colorAlphaValues = Array(frame.length).fill(alpha(r as string, 0.5));
}
return [
s.x(frame).values.toArray(), // X
s.y(frame).values.toArray(), // Y
s.x(frame).values, // X
s.y(frame).values, // Y
asArray(frame, s.pointSize),
colorValues,
colorAlphaValues,