FieldValues: Use plain arrays instead of Vector (part 3 of 2) (#66612)

Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
This commit is contained in:
Leon Sorokin 2023-04-20 09:59:18 -05:00 committed by GitHub
parent 24696d593b
commit b24ba7b7ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
109 changed files with 594 additions and 648 deletions

View File

@ -4627,9 +4627,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "5"], [0, 0, 0, "Unexpected any. Specify a different type.", "5"],
[0, 0, 0, "Unexpected any. Specify a different type.", "6"] [0, 0, 0, "Unexpected any. Specify a different type.", "6"]
], ],
"public/app/plugins/datasource/loki/getDerivedFields.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"public/app/plugins/datasource/loki/queryUtils.ts:5381": [ "public/app/plugins/datasource/loki/queryUtils.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"] [0, 0, 0, "Do not use any type assertions.", "0"]
], ],
@ -5089,7 +5086,8 @@ exports[`better eslint`] = {
], ],
"public/app/plugins/datasource/testdata/nodeGraphUtils.ts:5381": [ "public/app/plugins/datasource/testdata/nodeGraphUtils.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"], [0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"] [0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[0, 0, 0, "Unexpected any. Specify a different type.", "2"]
], ],
"public/app/plugins/datasource/testdata/runStreams.ts:5381": [ "public/app/plugins/datasource/testdata/runStreams.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"] [0, 0, 0, "Unexpected any. Specify a different type.", "0"]

View File

@ -72,7 +72,7 @@ const y = frame.fields.find((field) => field.name === yField);
const size = frame.fields.find((field) => field.name === sizeField); const size = frame.fields.find((field) => field.name === sizeField);
for (let i = 0; i < frame.length; i++) { for (let i = 0; i < frame.length; i++) {
const row = [x?.values.get(i), y?.values.get(i), size?.values.get(i)]; const row = [x?.values[i], y?.values[i], size?.values[i]];
// ... // ...
} }
@ -100,7 +100,7 @@ const valueField = frame.fields.find((field) => field.type === FieldType.number)
return ( return (
<div> <div>
{valueField {valueField
? valueField.values.toArray().map((value) => { ? valueField.values.map((value) => {
const displayValue = valueField.display!(value); const displayValue = valueField.display!(value);
return ( return (
<p style={{ color: displayValue.color }}> <p style={{ color: displayValue.color }}>

View File

@ -24,6 +24,7 @@ describe('Array DataFrame', () => {
// Check map // Check map
expect(frame.map((row) => row.name)).toEqual(expectedNames); expect(frame.map((row) => row.name)).toEqual(expectedNames);
expect(frame[0].name).toEqual(input[0].name);
let names: string[] = []; let names: string[] = [];
for (const row of frame) { for (const row of frame) {

View File

@ -1,4 +1,4 @@
import { QueryResultMeta } from '../types'; import { makeArrayIndexableVector, QueryResultMeta } from '../types';
import { Field, FieldType, DataFrame } from '../types/dataFrame'; import { Field, FieldType, DataFrame } from '../types/dataFrame';
import { FunctionalVector } from '../vector/FunctionalVector'; import { FunctionalVector } from '../vector/FunctionalVector';
import { vectorToArray } from '../vector/vectorToArray'; import { vectorToArray } from '../vector/vectorToArray';
@ -15,6 +15,7 @@ class ArrayPropertyVector<T = any> extends FunctionalVector<T> {
constructor(private source: any[], private prop: string) { constructor(private source: any[], private prop: string) {
super(); super();
return makeArrayIndexableVector(this);
} }
get length(): number { get length(): number {
@ -64,6 +65,7 @@ export class ArrayDataFrame<T = any> extends FunctionalVector<T> implements Data
} else { } else {
this.setFieldsFromObject(first); this.setFieldsFromObject(first);
} }
return makeArrayIndexableVector(this);
} }
/** /**

View File

@ -49,7 +49,7 @@ export function getFieldDisplayValuesProxy(options: {
// TODO: we could supply the field here for the getDisplayProcessor fallback but we would also need theme which // TODO: we could supply the field here for the getDisplayProcessor fallback but we would also need theme which
// we do not have access to here // we do not have access to here
const displayProcessor = field.display ?? getDisplayProcessor(); const displayProcessor = field.display ?? getDisplayProcessor();
const raw = field.values.get(options.rowIndex); const raw = field.values[options.rowIndex];
const disp = displayProcessor(raw); const disp = displayProcessor(raw);
disp.toString = () => formattedValueToString(disp); disp.toString = () => formattedValueToString(disp);
return disp; return disp;

View File

@ -10,7 +10,7 @@ const isEqualValueMatcher: ValueMatcherInfo<BasicValueMatcherOptions> = {
description: 'Match where value for given field is equal to options value.', description: 'Match where value for given field is equal to options value.',
get: (options) => { get: (options) => {
return (valueIndex: number, field: Field) => { return (valueIndex: number, field: Field) => {
const value = field.values.get(valueIndex); const value = field.values[valueIndex];
// eslint-disable-next-line eqeqeq // eslint-disable-next-line eqeqeq
return value == options.value; return value == options.value;
}; };
@ -28,7 +28,7 @@ const isNotEqualValueMatcher: ValueMatcherInfo<BasicValueMatcherOptions> = {
description: 'Match where value for given field is not equal to options value.', description: 'Match where value for given field is not equal to options value.',
get: (options) => { get: (options) => {
return (valueIndex: number, field: Field) => { return (valueIndex: number, field: Field) => {
const value = field.values.get(valueIndex); const value = field.values[valueIndex];
// eslint-disable-next-line eqeqeq // eslint-disable-next-line eqeqeq
return value != options.value; return value != options.value;
}; };

View File

@ -10,7 +10,7 @@ const isNullValueMatcher: ValueMatcherInfo<ValueMatcherOptions> = {
description: 'Match where value for given field is null.', description: 'Match where value for given field is null.',
get: () => { get: () => {
return (valueIndex: number, field: Field) => { return (valueIndex: number, field: Field) => {
const value = field.values.get(valueIndex); const value = field.values[valueIndex];
return value == null; return value == null;
}; };
}, },
@ -27,7 +27,7 @@ const isNotNullValueMatcher: ValueMatcherInfo<ValueMatcherOptions> = {
description: 'Match where value for given field is not null.', description: 'Match where value for given field is not null.',
get: () => { get: () => {
return (valueIndex: number, field: Field) => { return (valueIndex: number, field: Field) => {
const value = field.values.get(valueIndex); const value = field.values[valueIndex];
return value != null; return value != null;
}; };
}, },

View File

@ -10,7 +10,7 @@ const isGreaterValueMatcher: ValueMatcherInfo<BasicValueMatcherOptions<number>>
description: 'Match when field value is greater than option.', description: 'Match when field value is greater than option.',
get: (options) => { get: (options) => {
return (valueIndex: number, field: Field) => { return (valueIndex: number, field: Field) => {
const value = field.values.get(valueIndex); const value = field.values[valueIndex];
if (isNaN(value)) { if (isNaN(value)) {
return false; return false;
} }
@ -30,7 +30,7 @@ const isGreaterOrEqualValueMatcher: ValueMatcherInfo<BasicValueMatcherOptions<nu
description: 'Match when field value is greater than or equal to option.', description: 'Match when field value is greater than or equal to option.',
get: (options) => { get: (options) => {
return (valueIndex: number, field: Field) => { return (valueIndex: number, field: Field) => {
const value = field.values.get(valueIndex); const value = field.values[valueIndex];
if (isNaN(value)) { if (isNaN(value)) {
return false; return false;
} }
@ -50,7 +50,7 @@ const isLowerValueMatcher: ValueMatcherInfo<BasicValueMatcherOptions<number>> =
description: 'Match when field value is lower than option.', description: 'Match when field value is lower than option.',
get: (options) => { get: (options) => {
return (valueIndex: number, field: Field) => { return (valueIndex: number, field: Field) => {
const value = field.values.get(valueIndex); const value = field.values[valueIndex];
if (isNaN(value)) { if (isNaN(value)) {
return false; return false;
} }
@ -70,7 +70,7 @@ const isLowerOrEqualValueMatcher: ValueMatcherInfo<BasicValueMatcherOptions<numb
description: 'Match when field value is lower or equal than option.', description: 'Match when field value is lower or equal than option.',
get: (options) => { get: (options) => {
return (valueIndex: number, field: Field) => { return (valueIndex: number, field: Field) => {
const value = field.values.get(valueIndex); const value = field.values[valueIndex];
if (isNaN(value)) { if (isNaN(value)) {
return false; return false;
} }

View File

@ -10,7 +10,7 @@ const isBetweenValueMatcher: ValueMatcherInfo<RangeValueMatcherOptions<number>>
description: 'Match when field value is between given option values.', description: 'Match when field value is between given option values.',
get: (options) => { get: (options) => {
return (valueIndex: number, field: Field) => { return (valueIndex: number, field: Field) => {
const value = field.values.get(valueIndex); const value = field.values[valueIndex];
if (isNaN(value)) { if (isNaN(value)) {
return false; return false;
} }

View File

@ -12,7 +12,7 @@ const regexValueMatcher: ValueMatcherInfo<BasicValueMatcherOptions<string>> = {
const regex = new RegExp(options.value); const regex = new RegExp(options.value);
return (valueIndex: number, field: Field) => { return (valueIndex: number, field: Field) => {
const value = field.values.get(valueIndex); const value = field.values[valueIndex];
return regex.test(value); return regex.test(value);
}; };
}, },

View File

@ -138,7 +138,7 @@ const createKeyFactory = (
return (frameIndex: number, valueIndex: number): string => { return (frameIndex: number, valueIndex: number): string => {
return factoryIndex[frameIndex].reduce((key: string, fieldIndex: number) => { return factoryIndex[frameIndex].reduce((key: string, fieldIndex: number) => {
return key + data[frameIndex].fields[fieldIndex].values.get(valueIndex); return key + data[frameIndex].fields[fieldIndex].values[valueIndex];
}, ''); }, '');
}; };
}; };
@ -173,7 +173,7 @@ const createValueMapper = (
continue; continue;
} }
value[fieldName] = field.values.get(valueIndex); value[fieldName] = field.values[valueIndex];
} }
return value; return value;

View File

@ -75,9 +75,9 @@ export const seriesToRowsTransformer: DataTransformerInfo<SeriesToRowsTransforme
const valueFieldIndex = timeFieldIndex === 0 ? 1 : 0; const valueFieldIndex = timeFieldIndex === 0 ? 1 : 0;
dataFrame.add({ dataFrame.add({
[TIME_SERIES_TIME_FIELD_NAME]: frame.fields[timeFieldIndex].values.get(valueIndex), [TIME_SERIES_TIME_FIELD_NAME]: frame.fields[timeFieldIndex].values[valueIndex],
[TIME_SERIES_METRIC_FIELD_NAME]: getFrameDisplayName(frame), [TIME_SERIES_METRIC_FIELD_NAME]: getFrameDisplayName(frame),
[TIME_SERIES_VALUE_FIELD_NAME]: frame.fields[valueFieldIndex].values.get(valueIndex), [TIME_SERIES_VALUE_FIELD_NAME]: frame.fields[valueFieldIndex].values[valueIndex],
}); });
} }
} }

View File

@ -1,12 +1,12 @@
declare global { declare global {
interface Array<T> { interface Array<T> {
/** @deprecated this only exists to help migrate Vector to Array */ /** @deprecated Use [idx]. This only exists to help migrate Vector to Array */
get(idx: number): T; get(idx: number): T;
/** @deprecated this only exists to help migrate Vector to Array */ /** @deprecated Use [idx]. This only exists to help migrate Vector to Array */
set(idx: number, value: T): void; set(idx: number, value: T): void;
/** @deprecated this only exists to help migrate Vector to Array */ /** @deprecated Use .push(value). This only exists to help migrate Vector to Array */
add(value: T): void; add(value: T): void;
/** @deprecated this only exists to help migrate Vector to Array */ /** @deprecated this is not necessary. This only exists to help migrate Vector to Array */
toArray(): T[]; toArray(): T[];
} }
} }
@ -108,17 +108,21 @@ export interface MutableVector<T = any> extends ReadWriteVector<T> {}
export function makeArrayIndexableVector<T extends Vector>(v: T): T { export function makeArrayIndexableVector<T extends Vector>(v: T): T {
return new Proxy(v, { return new Proxy(v, {
get(target: Vector, property: string, receiver: Vector) { get(target: Vector, property: string, receiver: Vector) {
const idx = +property; if (typeof property !== 'symbol') {
if (String(idx) === property) { const idx = +property;
return target.get(idx); if (String(idx) === property) {
return target.get(idx);
}
} }
return Reflect.get(target, property, receiver); return Reflect.get(target, property, receiver);
}, },
set(target: Vector, property: string, value: any, receiver: Vector) { set(target: Vector, property: string, value: any, receiver: Vector) {
const idx = +property; if (typeof property !== 'symbol') {
if (String(idx) === property) { const idx = +property;
target.set(idx, value); if (String(idx) === property) {
return true; target.set(idx, value);
return true;
}
} }
return Reflect.set(target, property, value, receiver); return Reflect.set(target, property, value, receiver);
}, },

View File

@ -234,7 +234,7 @@ export function frameToMetricFindValue(frame: DataFrame): MetricFindValue[] {
} }
if (field) { if (field) {
for (let i = 0; i < field.values.length; i++) { for (let i = 0; i < field.values.length; i++) {
values.push({ text: '' + field.values.get(i) }); values.push({ text: '' + field.values[i] });
} }
} }
return values; return values;

View File

@ -220,7 +220,7 @@ export class UPlotConfigBuilder {
// interpolate for gradients/thresholds // interpolate for gradients/thresholds
if (typeof s !== 'string') { if (typeof s !== 'string') {
let field = this.frames![0].fields[seriesIdx]; let field = this.frames![0].fields[seriesIdx];
s = field.display!(field.values.get(u.cursor.idxs![seriesIdx]!)).color!; s = field.display!(field.values[u.cursor.idxs![seriesIdx]!]).color!;
} }
return s + alphaHex; return s + alphaHex;

View File

@ -183,7 +183,7 @@ export const TooltipPlugin = ({
const xFieldFmt = xField.display || getDisplayProcessor({ field: xField, timeZone, theme }); const xFieldFmt = xField.display || getDisplayProcessor({ field: xField, timeZone, theme });
let tooltip: React.ReactNode = null; let tooltip: React.ReactNode = null;
let xVal = xFieldFmt(xField!.values.get(focusedPointIdx)).text; let xVal = xFieldFmt(xField!.values[focusedPointIdx]).text;
if (!renderTooltip) { if (!renderTooltip) {
// when interacting with a point in single mode // when interacting with a point in single mode
@ -195,9 +195,9 @@ export const TooltipPlugin = ({
} }
const dataIdx = focusedPointIdxs?.[focusedSeriesIdx] ?? focusedPointIdx; const dataIdx = focusedPointIdxs?.[focusedSeriesIdx] ?? focusedPointIdx;
xVal = xFieldFmt(xField!.values.get(dataIdx)).text; xVal = xFieldFmt(xField!.values[dataIdx]).text;
const fieldFmt = field.display || getDisplayProcessor({ field, timeZone, theme }); const fieldFmt = field.display || getDisplayProcessor({ field, timeZone, theme });
const display = fieldFmt(field.values.get(dataIdx)); const display = fieldFmt(field.values[dataIdx]);
tooltip = ( tooltip = (
<SeriesTable <SeriesTable
@ -232,7 +232,7 @@ export const TooltipPlugin = ({
continue; continue;
} }
const v = otherProps.data.fields[i].values.get(focusedPointIdxs[i]!); const v = otherProps.data.fields[i].values[focusedPointIdxs[i]!];
const display = field.display!(v); const display = field.display!(v);
sortIdx.push(v); sortIdx.push(v);

View File

@ -4,7 +4,7 @@ import React, { ReactNode } from 'react';
import { TestProvider } from 'test/helpers/TestProvider'; import { TestProvider } from 'test/helpers/TestProvider';
import { getGrafanaContextMock } from 'test/mocks/getGrafanaContextMock'; import { getGrafanaContextMock } from 'test/mocks/getGrafanaContextMock';
import { ArrayVector, DataFrame, DataFrameView, FieldType, NavModelItem } from '@grafana/data'; import { DataFrame, DataFrameView, FieldType, NavModelItem } from '@grafana/data';
import { config } from '@grafana/runtime'; import { config } from '@grafana/runtime';
import { HOME_NAV_ID } from 'app/core/reducers/navModel'; import { HOME_NAV_ID } from 'app/core/reducers/navModel';
import { DashboardQueryResult, getGrafanaSearcher, QueryResponse } from 'app/features/search/service'; import { DashboardQueryResult, getGrafanaSearcher, QueryResponse } from 'app/features/search/service';
@ -23,12 +23,12 @@ const pageNav: NavModelItem = {
const searchData: DataFrame = { const searchData: DataFrame = {
fields: [ fields: [
{ name: 'kind', type: FieldType.string, config: {}, values: new ArrayVector([]) }, { name: 'kind', type: FieldType.string, config: {}, values: [] },
{ name: 'name', type: FieldType.string, config: {}, values: new ArrayVector([]) }, { name: 'name', type: FieldType.string, config: {}, values: [] },
{ name: 'uid', type: FieldType.string, config: {}, values: new ArrayVector([]) }, { name: 'uid', type: FieldType.string, config: {}, values: [] },
{ name: 'url', type: FieldType.string, config: {}, values: new ArrayVector([]) }, { name: 'url', type: FieldType.string, config: {}, values: [] },
{ name: 'tags', type: FieldType.other, config: {}, values: new ArrayVector([]) }, { name: 'tags', type: FieldType.other, config: {}, values: [] },
{ name: 'location', type: FieldType.string, config: {}, values: new ArrayVector([]) }, { name: 'location', type: FieldType.string, config: {}, values: [] },
], ],
length: 0, length: 0,
}; };

View File

@ -611,13 +611,13 @@ export function findNextStateIndex(field: Field, datapointIdx: number) {
return null; return null;
} }
const startValue = field.values.get(datapointIdx); const startValue = field.values[datapointIdx];
while (end === undefined) { while (end === undefined) {
if (rightPointer >= field.values.length) { if (rightPointer >= field.values.length) {
return null; return null;
} }
const rightValue = field.values.get(rightPointer); const rightValue = field.values[rightPointer];
if (rightValue === undefined || rightValue === startValue) { if (rightValue === undefined || rightValue === startValue) {
rightPointer++; rightPointer++;

View File

@ -329,7 +329,7 @@ function getAllLabels(fields: LogFields): Labels[] {
const { stringField, labelsField } = fields; const { stringField, labelsField } = fields;
if (labelsField !== undefined) { if (labelsField !== undefined) {
return labelsField.values.toArray(); return labelsField.values;
} else { } else {
return [stringField.labels ?? {}]; return [stringField.labels ?? {}];
} }
@ -342,7 +342,7 @@ function getLabelsForFrameRow(fields: LogFields, index: number): Labels {
const { stringField, labelsField } = fields; const { stringField, labelsField } = fields;
if (labelsField !== undefined) { if (labelsField !== undefined) {
return labelsField.values.get(index); return labelsField.values[index];
} else { } else {
return stringField.labels ?? {}; return stringField.labels ?? {};
} }
@ -407,13 +407,13 @@ export function logSeriesToLogsModel(logSeries: DataFrame[], queries: DataQuery[
const { timeField, timeNanosecondField, stringField, logLevelField, idField, series } = info; const { timeField, timeNanosecondField, stringField, logLevelField, idField, series } = info;
for (let j = 0; j < series.length; j++) { for (let j = 0; j < series.length; j++) {
const ts = timeField.values.get(j); const ts = timeField.values[j];
const time = toUtc(ts); const time = toUtc(ts);
const tsNs = timeNanosecondField ? timeNanosecondField.values.get(j) : undefined; const tsNs = timeNanosecondField ? timeNanosecondField.values[j] : undefined;
const timeEpochNs = tsNs ? tsNs : time.valueOf() + '000000'; const timeEpochNs = tsNs ? tsNs : time.valueOf() + '000000';
// In edge cases, this can be undefined. If undefined, we want to replace it with empty string. // In edge cases, this can be undefined. If undefined, we want to replace it with empty string.
const messageValue: unknown = stringField.values.get(j) ?? ''; const messageValue: unknown = stringField.values[j] ?? '';
// This should be string but sometimes isn't (eg elastic) because the dataFrame is not strongly typed. // This should be string but sometimes isn't (eg elastic) because the dataFrame is not strongly typed.
const message: string = typeof messageValue === 'string' ? messageValue : JSON.stringify(messageValue); const message: string = typeof messageValue === 'string' ? messageValue : JSON.stringify(messageValue);
@ -433,7 +433,7 @@ export function logSeriesToLogsModel(logSeries: DataFrame[], queries: DataQuery[
} }
let logLevel = LogLevel.unknown; let logLevel = LogLevel.unknown;
const logLevelKey = (logLevelField && logLevelField.values.get(j)) || (labels && labels['level']); const logLevelKey = (logLevelField && logLevelField.values[j]) || (labels && labels['level']);
if (logLevelKey) { if (logLevelKey) {
logLevel = getLogLevelFromKey(logLevelKey); logLevel = getLogLevelFromKey(logLevelKey);
} else { } else {
@ -459,7 +459,7 @@ export function logSeriesToLogsModel(logSeries: DataFrame[], queries: DataQuery[
entry, entry,
raw: message, raw: message,
labels: labels || {}, labels: labels || {},
uid: idField ? idField.values.get(j) : j.toString(), uid: idField ? idField.values[j] : j.toString(),
datasourceType, datasourceType,
}); });
} }

View File

@ -329,10 +329,10 @@ const TimeseriesRow: FC<FrameProps & { index: number }> = ({ frame, index }) =>
const displayNameFromDS = valueField.config?.displayNameFromDS; const displayNameFromDS = valueField.config?.displayNameFromDS;
const name = displayNameFromDS ?? (hasLabels ? formatLabels(valueField.labels ?? {}) : 'Series ' + index); const name = displayNameFromDS ?? (hasLabels ? formatLabels(valueField.labels ?? {}) : 'Series ' + index);
const timestamps = frame.fields[0].values.toArray(); const timestamps = frame.fields[0].values;
const getTimestampFromIndex = (index: number) => frame.fields[0].values.get(index); const getTimestampFromIndex = (index: number) => frame.fields[0].values[index];
const getValueFromIndex = (index: number) => frame.fields[1].values.get(index); const getValueFromIndex = (index: number) => frame.fields[1].values[index];
return ( return (
<div className={styles.expression.resultsRow}> <div className={styles.expression.resultsRow}>

View File

@ -17,7 +17,7 @@ const getSeriesName = (frame: DataFrame): string => {
}; };
const getSeriesValue = (frame: DataFrame) => { const getSeriesValue = (frame: DataFrame) => {
const value = frame.fields[0]?.values.get(0); const value = frame.fields[0]?.values[0];
if (Number.isFinite(value)) { if (Number.isFinite(value)) {
return roundDecimals(value, 5); return roundDecimals(value, 5);
@ -33,9 +33,7 @@ const formatLabels = (labels: Labels): string => {
}; };
const isEmptySeries = (series: DataFrame[]): boolean => { const isEmptySeries = (series: DataFrame[]): boolean => {
const isEmpty = series.every((serie) => const isEmpty = series.every((serie) => serie.fields.every((field) => field.values.every((value) => value == null)));
serie.fields.every((field) => field.values.toArray().every((value) => value == null))
);
return isEmpty; return isEmpty;
}; };

View File

@ -26,10 +26,7 @@ export function mapDataFrameToAlertPreview({ fields }: DataFrame): AlertPreview
const instances: AlertPreviewInstance[] = []; const instances: AlertPreviewInstance[] = [];
for (let index = 0; index < instanceStatusCount; index++) { for (let index = 0; index < instanceStatusCount; index++) {
const labelValues = labelIndexes.map((labelIndex) => [ const labelValues = labelIndexes.map((labelIndex) => [fields[labelIndex].name, fields[labelIndex].values[index]]);
fields[labelIndex].name,
fields[labelIndex].values.get(index),
]);
const state = fields[stateFieldIndex]?.values?.get(index); const state = fields[stateFieldIndex]?.values?.get(index);
const info = fields[infoFieldIndex]?.values?.get(index); const info = fields[infoFieldIndex]?.values?.get(index);

View File

@ -57,7 +57,7 @@ export class AnnotationFieldMapper extends PureComponent<Props, State> {
description += '...'; description += '...';
break; break;
} }
description += f.values.get(i); description += f.values[i];
} }
if (description.length > 50) { if (description.length > 50) {

View File

@ -223,7 +223,7 @@ export function getAnnotationsFromData(
if (f.text) { if (f.text) {
v = f.text; // TODO support templates! v = f.text; // TODO support templates!
} else if (f.field) { } else if (f.field) {
v = f.field.values.get(i); v = f.field.values[i];
if (v !== undefined && f.regex) { if (v !== undefined && f.regex) {
const match = f.regex.exec(v); const match = f.regex.exec(v);
if (match) { if (match) {

View File

@ -1,4 +1,4 @@
import { ArrayVector, DataFrame, DataFrameView, FieldType } from '@grafana/data'; import { DataFrame, DataFrameView, FieldType } from '@grafana/data';
import { config } from '@grafana/runtime'; import { config } from '@grafana/runtime';
import { ContextSrv, contextSrv } from 'app/core/services/context_srv'; import { ContextSrv, contextSrv } from 'app/core/services/context_srv';
import impressionSrv from 'app/core/services/impression_srv'; import impressionSrv from 'app/core/services/impression_srv';
@ -13,12 +13,12 @@ describe('dashboardActions', () => {
const searchData: DataFrame = { const searchData: DataFrame = {
fields: [ fields: [
{ name: 'kind', type: FieldType.string, config: {}, values: new ArrayVector(['dashboard']) }, { name: 'kind', type: FieldType.string, config: {}, values: ['dashboard'] },
{ name: 'name', type: FieldType.string, config: {}, values: new ArrayVector(['My dashboard 1']) }, { name: 'name', type: FieldType.string, config: {}, values: ['My dashboard 1'] },
{ name: 'uid', type: FieldType.string, config: {}, values: new ArrayVector(['my-dashboard-1']) }, { name: 'uid', type: FieldType.string, config: {}, values: ['my-dashboard-1'] },
{ name: 'url', type: FieldType.string, config: {}, values: new ArrayVector(['/my-dashboard-1']) }, { name: 'url', type: FieldType.string, config: {}, values: ['/my-dashboard-1'] },
{ name: 'tags', type: FieldType.other, config: {}, values: new ArrayVector([['foo', 'bar']]) }, { name: 'tags', type: FieldType.other, config: {}, values: [['foo', 'bar']] },
{ name: 'location', type: FieldType.string, config: {}, values: new ArrayVector(['my-folder-1']) }, { name: 'location', type: FieldType.string, config: {}, values: ['my-folder-1'] },
], ],
meta: { meta: {
custom: { custom: {

View File

@ -2,14 +2,7 @@ import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event'; import userEvent from '@testing-library/user-event';
import React, { ComponentProps } from 'react'; import React, { ComponentProps } from 'react';
import { import { FieldType, LoadingState, MutableDataFrame, SupplementaryQueryType, DataSourceApi } from '@grafana/data';
ArrayVector,
FieldType,
LoadingState,
MutableDataFrame,
SupplementaryQueryType,
DataSourceApi,
} from '@grafana/data';
import { DataQuery } from '@grafana/schema'; import { DataQuery } from '@grafana/schema';
import { LogsSamplePanel } from './LogsSamplePanel'; import { LogsSamplePanel } from './LogsSamplePanel';
@ -43,20 +36,20 @@ const sampleDataFrame = new MutableDataFrame({
{ {
name: 'labels', name: 'labels',
type: FieldType.other, type: FieldType.other,
values: new ArrayVector([ values: [
{ place: 'luna', source: 'data' }, { place: 'luna', source: 'data' },
{ place: 'luna', source: 'data' }, { place: 'luna', source: 'data' },
]), ],
}, },
{ {
name: 'Time', name: 'Time',
type: FieldType.time, type: FieldType.time,
values: new ArrayVector(['2022-02-22T09:28:11.352440161Z', '2022-02-22T14:42:50.991981292Z']), values: ['2022-02-22T09:28:11.352440161Z', '2022-02-22T14:42:50.991981292Z'],
}, },
{ {
name: 'Line', name: 'Line',
type: FieldType.string, type: FieldType.string,
values: new ArrayVector(['line1 ', 'line2']), values: ['line1 ', 'line2'],
}, },
], ],
}); });

View File

@ -9,7 +9,7 @@ export function transformDataFrames(frame?: DataFrame): Trace | null {
let data: TraceResponse = let data: TraceResponse =
frame.fields.length === 1 frame.fields.length === 1
? // For backward compatibility when we sent whole json response in a single field/value ? // For backward compatibility when we sent whole json response in a single field/value
frame.fields[0].values.get(0) frame.fields[0].values[0]
: transformTraceDataFrame(frame); : transformTraceDataFrame(frame);
return transformTraceData(data); return transformTraceData(data);
} }

View File

@ -4,7 +4,6 @@ import { thunkTester } from 'test/core/thunk/thunkTester';
import { assertIsDefined } from 'test/helpers/asserts'; import { assertIsDefined } from 'test/helpers/asserts';
import { import {
ArrayVector,
DataQueryResponse, DataQueryResponse,
DataSourceApi, DataSourceApi,
DataSourceJsonData, DataSourceJsonData,
@ -111,7 +110,7 @@ function setupQueryResponse(state: StoreState) {
error: { message: 'test error' }, error: { message: 'test error' },
data: [ data: [
new MutableDataFrame({ new MutableDataFrame({
fields: [{ name: 'test', values: new ArrayVector() }], fields: [{ name: 'test', values: [] }],
meta: { meta: {
preferredVisualisationType: 'graph', preferredVisualisationType: 'graph',
}, },

View File

@ -267,9 +267,9 @@ describe('decorateWithTableResult', () => {
expect(tableResult?.fields[0].name).toBe('Time'); expect(tableResult?.fields[0].name).toBe('Time');
expect(tableResult?.fields[1].name).toBe('A-series'); expect(tableResult?.fields[1].name).toBe('A-series');
expect(tableResult?.fields[2].name).toBe('B-series'); expect(tableResult?.fields[2].name).toBe('B-series');
expect(tableResult?.fields[0].values.toArray()).toEqual([100, 200, 300]); expect(tableResult?.fields[0].values).toEqual([100, 200, 300]);
expect(tableResult?.fields[1].values.toArray()).toEqual([4, 5, 6]); expect(tableResult?.fields[1].values).toEqual([4, 5, 6]);
expect(tableResult?.fields[2].values.toArray()).toEqual([4, 5, 6]); expect(tableResult?.fields[2].values).toEqual([4, 5, 6]);
}); });
it('should not override fields display property when filled', async () => { it('should not override fields display property when filled', async () => {

View File

@ -18,7 +18,7 @@ export const getRawPrometheusListItemsFromDataFrame = (dataFrame: DataFrame): in
const newFields = dataFrame.fields.filter((field) => !['Time'].includes(field.name)); const newFields = dataFrame.fields.filter((field) => !['Time'].includes(field.name));
// Get name from each series // Get name from each series
let metricNames: string[] = newFields.find((field) => field.name === '__name__')?.values.toArray() ?? []; let metricNames: string[] = newFields.find((field) => field.name === '__name__')?.values ?? [];
if (!metricNames.length && newFields.length && newFields[0].values.length) { if (!metricNames.length && newFields.length && newFields[0].values.length) {
// These results do not have series labels // These results do not have series labels
// Matching the native prometheus UI which appears to only show the permutations of the first field in the query result. // Matching the native prometheus UI which appears to only show the permutations of the first field in the query result.
@ -38,7 +38,7 @@ export const getRawPrometheusListItemsFromDataFrame = (dataFrame: DataFrame): in
if (label !== 'Time') { if (label !== 'Time') {
// Initialize the objects // Initialize the objects
if (typeof field?.display === 'function') { if (typeof field?.display === 'function') {
const stringValue = formattedValueToString(field?.display(field.values.get(i))); const stringValue = formattedValueToString(field?.display(field.values[i]));
if (stringValue) { if (stringValue) {
formattedMetric[label] = stringValue; formattedMetric[label] = stringValue;
} else if (label.includes('Value #')) { } else if (label.includes('Value #')) {

View File

@ -1,5 +1,4 @@
import { import {
ArrayVector,
CoreApp, CoreApp,
DataFrame, DataFrame,
DataLink, DataLink,
@ -211,7 +210,7 @@ describe('explore links utils', () => {
const { field, range, dataFrame } = setup(noHyphenLink, true, { const { field, range, dataFrame } = setup(noHyphenLink, true, {
name: 'fluxDimensions', name: 'fluxDimensions',
type: FieldType.string, type: FieldType.string,
values: new ArrayVector([ROW_WITH_TEXT_VALUE.value, ROW_WITH_NULL_VALUE.value]), values: [ROW_WITH_TEXT_VALUE.value, ROW_WITH_NULL_VALUE.value],
config: { config: {
links: [noHyphenLink], links: [noHyphenLink],
}, },
@ -242,7 +241,7 @@ describe('explore links utils', () => {
{ {
name: 'fluxDimensions', name: 'fluxDimensions',
type: FieldType.string, type: FieldType.string,
values: new ArrayVector([ROW_WITH_TEXT_VALUE.value, ROW_WITH_NULL_VALUE.value]), values: [ROW_WITH_TEXT_VALUE.value, ROW_WITH_NULL_VALUE.value],
config: { config: {
links: [noHyphenLink], links: [noHyphenLink],
}, },
@ -251,7 +250,7 @@ describe('explore links utils', () => {
{ {
name: 'fluxDimension2', name: 'fluxDimension2',
type: FieldType.string, type: FieldType.string,
values: new ArrayVector(['foo2', ROW_WITH_NULL_VALUE.value]), values: ['foo2', ROW_WITH_NULL_VALUE.value],
config: { config: {
links: [noHyphenLink], links: [noHyphenLink],
}, },
@ -286,7 +285,7 @@ describe('explore links utils', () => {
const { field, range, dataFrame } = setup(transformationLink, true, { const { field, range, dataFrame } = setup(transformationLink, true, {
name: 'msg', name: 'msg',
type: FieldType.string, type: FieldType.string,
values: new ArrayVector(['application=foo host=dev-001', 'application=bar host=prod-003']), values: ['application=foo host=dev-001', 'application=bar host=prod-003'],
config: { config: {
links: [transformationLink], links: [transformationLink],
}, },
@ -335,7 +334,7 @@ describe('explore links utils', () => {
const { field, range, dataFrame } = setup(transformationLink, true, { const { field, range, dataFrame } = setup(transformationLink, true, {
name: 'msg', name: 'msg',
type: FieldType.string, type: FieldType.string,
values: new ArrayVector(['fieldA=asparagus fieldB=banana', 'fieldA=broccoli fieldB=apple']), values: ['fieldA=asparagus fieldB=banana', 'fieldA=broccoli fieldB=apple'],
config: { config: {
links: [transformationLink], links: [transformationLink],
}, },
@ -374,7 +373,7 @@ describe('explore links utils', () => {
const { field, range, dataFrame } = setup(transformationLink, true, { const { field, range, dataFrame } = setup(transformationLink, true, {
name: 'msg', name: 'msg',
type: FieldType.string, type: FieldType.string,
values: new ArrayVector(['application=foo online=true', 'application=bar online=false']), values: ['application=foo online=true', 'application=bar online=false'],
config: { config: {
links: [transformationLink], links: [transformationLink],
}, },
@ -417,7 +416,7 @@ describe('explore links utils', () => {
{ {
name: 'fieldWithLink', name: 'fieldWithLink',
type: FieldType.string, type: FieldType.string,
values: new ArrayVector(['application=link', 'application=link2']), values: ['application=link', 'application=link2'],
config: { config: {
links: [transformationLink], links: [transformationLink],
}, },
@ -426,7 +425,7 @@ describe('explore links utils', () => {
{ {
name: 'fieldNamedInTransformation', name: 'fieldNamedInTransformation',
type: FieldType.string, type: FieldType.string,
values: new ArrayVector(['application=transform', 'application=transform2']), values: ['application=transform', 'application=transform2'],
config: {}, config: {},
}, },
] ]
@ -470,7 +469,7 @@ describe('explore links utils', () => {
const { field, range, dataFrame } = setup(transformationLink, true, { const { field, range, dataFrame } = setup(transformationLink, true, {
name: 'msg', name: 'msg',
type: FieldType.string, type: FieldType.string,
values: new ArrayVector(['foo loki prod', 'dev bar grafana', 'prod grafana foo']), values: ['foo loki prod', 'dev bar grafana', 'prod grafana foo'],
config: { config: {
links: [transformationLink], links: [transformationLink],
}, },
@ -545,7 +544,7 @@ describe('explore links utils', () => {
const { field, range, dataFrame } = setup(transformationLink, true, { const { field, range, dataFrame } = setup(transformationLink, true, {
name: 'msg', name: 'msg',
type: FieldType.string, type: FieldType.string,
values: new ArrayVector(['application=foo host=dev-001']), values: ['application=foo host=dev-001'],
config: { config: {
links: [transformationLink], links: [transformationLink],
}, },
@ -570,7 +569,7 @@ describe('explore links utils', () => {
const { field, range, dataFrame } = setup(transformationLink, true, { const { field, range, dataFrame } = setup(transformationLink, true, {
name: 'msg', name: 'msg',
type: FieldType.string, type: FieldType.string,
values: new ArrayVector(['application=foo host=dev-001']), values: ['application=foo host=dev-001'],
config: { config: {
links: [transformationLink], links: [transformationLink],
}, },
@ -712,7 +711,7 @@ function setup(
const field: Field<string | null> = { const field: Field<string | null> = {
name: 'flux-dimensions', name: 'flux-dimensions',
type: FieldType.string, type: FieldType.string,
values: new ArrayVector([ROW_WITH_TEXT_VALUE.value, ROW_WITH_NULL_VALUE.value]), values: [ROW_WITH_TEXT_VALUE.value, ROW_WITH_NULL_VALUE.value],
config: { config: {
links: [link], links: [link],
}, },

View File

@ -71,7 +71,7 @@ export const getFieldLinksForExplore = (options: {
const scopedVars: ScopedVars = { ...(vars || {}) }; const scopedVars: ScopedVars = { ...(vars || {}) };
scopedVars['__value'] = { scopedVars['__value'] = {
value: { value: {
raw: field.values.get(rowIndex), raw: field.values[rowIndex],
}, },
text: 'Raw value', text: 'Raw value',
}; };
@ -130,9 +130,9 @@ export const getFieldLinksForExplore = (options: {
let fieldValue; let fieldValue;
if (transformation.field) { if (transformation.field) {
const transformField = dataFrame?.fields.find((field) => field.name === transformation.field); const transformField = dataFrame?.fields.find((field) => field.name === transformation.field);
fieldValue = transformField?.values.get(rowIndex); fieldValue = transformField?.values[rowIndex];
} else { } else {
fieldValue = field.values.get(rowIndex); fieldValue = field.values[rowIndex];
} }
internalLinkSpecificVars = { internalLinkSpecificVars = {

View File

@ -98,7 +98,7 @@ describe('LogDetails', () => {
if (field.config && field.config.links) { if (field.config && field.config.links) {
return field.config.links.map((link) => { return field.config.links.map((link) => {
return { return {
href: link.url.replace('${__value.text}', field.values.get(rowIndex)), href: link.url.replace('${__value.text}', field.values[rowIndex]),
title: link.title, title: link.title,
target: '_blank', target: '_blank',
origin: field, origin: field,

View File

@ -117,7 +117,7 @@ class UnThemedLogDetails extends PureComponent<Props> {
onClickHideField={onClickHideField} onClickHideField={onClickHideField}
onClickFilterOutLabel={onClickFilterOutLabel} onClickFilterOutLabel={onClickFilterOutLabel}
onClickFilterLabel={onClickFilterLabel} onClickFilterLabel={onClickFilterLabel}
getStats={() => calculateStats(row.dataFrame.fields[fieldIndex].values.toArray())} getStats={() => calculateStats(row.dataFrame.fields[fieldIndex].values)}
displayedFields={displayedFields} displayedFields={displayedFields}
wrapLogMessage={wrapLogMessage} wrapLogMessage={wrapLogMessage}
row={row} row={row}
@ -144,7 +144,7 @@ class UnThemedLogDetails extends PureComponent<Props> {
links={links} links={links}
onClickShowField={onClickShowField} onClickShowField={onClickShowField}
onClickHideField={onClickHideField} onClickHideField={onClickHideField}
getStats={() => calculateStats(row.dataFrame.fields[fieldIndex].values.toArray())} getStats={() => calculateStats(row.dataFrame.fields[fieldIndex].values)}
displayedFields={displayedFields} displayedFields={displayedFields}
wrapLogMessage={wrapLogMessage} wrapLogMessage={wrapLogMessage}
row={row} row={row}
@ -163,7 +163,7 @@ class UnThemedLogDetails extends PureComponent<Props> {
links={links} links={links}
onClickShowField={onClickShowField} onClickShowField={onClickShowField}
onClickHideField={onClickHideField} onClickHideField={onClickHideField}
getStats={() => calculateStats(row.dataFrame.fields[fieldIndex].values.toArray())} getStats={() => calculateStats(row.dataFrame.fields[fieldIndex].values)}
displayedFields={displayedFields} displayedFields={displayedFields}
wrapLogMessage={wrapLogMessage} wrapLogMessage={wrapLogMessage}
row={row} row={row}

View File

@ -1,4 +1,4 @@
import { ArrayVector, FieldType, MutableDataFrame } from '@grafana/data'; import { FieldType, MutableDataFrame } from '@grafana/data';
import { ExploreFieldLinkModel } from 'app/features/explore/utils/links'; import { ExploreFieldLinkModel } from 'app/features/explore/utils/links';
import { createLogRow } from './__mocks__/logRow'; import { createLogRow } from './__mocks__/logRow';
@ -17,7 +17,7 @@ describe('logParser', () => {
name: 'labels', name: 'labels',
type: FieldType.other, type: FieldType.other,
config: {}, config: {},
values: new ArrayVector([{ place: 'luna', source: 'data' }]), values: [{ place: 'luna', source: 'data' }],
}, },
], ],
}), }),
@ -39,7 +39,7 @@ describe('logParser', () => {
name: 'labels', name: 'labels',
type: FieldType.string, type: FieldType.string,
config: {}, config: {},
values: new ArrayVector([{ place: 'luna', source: 'data' }]), values: [{ place: 'luna', source: 'data' }],
}, },
], ],
}), }),
@ -60,7 +60,7 @@ describe('logParser', () => {
name: 'id', name: 'id',
type: FieldType.string, type: FieldType.string,
config: {}, config: {},
values: new ArrayVector(['1659620138401000000_8b1f7688_']), values: ['1659620138401000000_8b1f7688_'],
}, },
], ],
}), }),
@ -129,7 +129,7 @@ describe('logParser', () => {
config: { links: [] }, config: { links: [] },
name: 'Line', name: 'Line',
type: FieldType.string, type: FieldType.string,
values: new ArrayVector(['a', 'b']), values: ['a', 'b'],
}, },
title: 'test', title: 'test',
target: '_self', target: '_self',
@ -163,7 +163,7 @@ describe('logParser', () => {
config: { links: [] }, config: { links: [] },
name: 'Line', name: 'Line',
type: FieldType.string, type: FieldType.string,
values: new ArrayVector(['a', 'b']), values: ['a', 'b'],
}, },
title: 'test', title: 'test',
target: '_self', target: '_self',
@ -186,12 +186,12 @@ const testStringField = {
name: 'test_field_string', name: 'test_field_string',
type: FieldType.string, type: FieldType.string,
config: {}, config: {},
values: new ArrayVector(['abc']), values: ['abc'],
}; };
const testFieldWithNullValue = { const testFieldWithNullValue = {
name: 'test_field_null', name: 'test_field_null',
type: FieldType.string, type: FieldType.string,
config: {}, config: {},
values: new ArrayVector([null]), values: [null],
}; };

View File

@ -71,7 +71,7 @@ export const getDataframeFields = memoizeOne(
const links = getFieldLinks ? getFieldLinks(field, row.rowIndex, row.dataFrame) : []; const links = getFieldLinks ? getFieldLinks(field, row.rowIndex, row.dataFrame) : [];
return { return {
keys: [field.name], keys: [field.name],
values: [field.values.get(row.rowIndex).toString()], values: [field.values[row.rowIndex].toString()],
links: links, links: links,
fieldIndex: field.index, fieldIndex: field.index,
}; };
@ -93,7 +93,7 @@ function shouldRemoveField(field: Field, index: number, row: LogRowModel) {
if ( if (
field.name === firstTimeField?.name && field.name === firstTimeField?.name &&
field.type === FieldType.time && field.type === FieldType.time &&
field.values.get(0) === firstTimeField.values.get(0) field.values[0] === firstTimeField.values[0]
) { ) {
return true; return true;
} }
@ -102,7 +102,7 @@ function shouldRemoveField(field: Field, index: number, row: LogRowModel) {
return true; return true;
} }
// field that has empty value (we want to keep 0 or empty string) // field that has empty value (we want to keep 0 or empty string)
if (field.values.get(row.rowIndex) == null) { if (field.values[row.rowIndex] == null) {
return true; return true;
} }
return false; return false;

View File

@ -223,8 +223,8 @@ export const mergeLogsVolumeDataFrames = (dataFrames: DataFrame[]): { dataFrames
}; };
for (let pointIndex = 0; pointIndex < length; pointIndex++) { for (let pointIndex = 0; pointIndex < length; pointIndex++) {
const time: number = timeField.values.get(pointIndex); const time: number = timeField.values[pointIndex];
const value: number = valueField.values.get(pointIndex); const value: number = valueField.values[pointIndex];
aggregated[level] ??= {}; aggregated[level] ??= {};
aggregated[level][time] = (aggregated[level][time] || 0) + value; aggregated[level][time] = (aggregated[level][time] || 0) + value;

View File

@ -3,7 +3,7 @@ import { defaultsDeep } from 'lodash';
import React from 'react'; import React from 'react';
import { Provider } from 'react-redux'; import { Provider } from 'react-redux';
import { ArrayVector, FieldType, getDefaultTimeRange, LoadingState } from '@grafana/data'; import { FieldType, getDefaultTimeRange, LoadingState } from '@grafana/data';
import { PanelDataErrorViewProps } from '@grafana/runtime'; import { PanelDataErrorViewProps } from '@grafana/runtime';
import { configureStore } from 'app/store/configureStore'; import { configureStore } from 'app/store/configureStore';
@ -28,7 +28,7 @@ describe('PanelDataErrorView', () => {
name: 'time', name: 'time',
type: FieldType.time, type: FieldType.time,
config: {}, config: {},
values: new ArrayVector([]), values: [],
}, },
], ],
length: 0, length: 0,
@ -39,7 +39,7 @@ describe('PanelDataErrorView', () => {
name: 'value', name: 'value',
type: FieldType.number, type: FieldType.number,
config: {}, config: {},
values: new ArrayVector([]), values: [],
}, },
], ],
length: 0, length: 0,

View File

@ -108,7 +108,7 @@ describe('getFieldLinksSupplier', () => {
view: new DataFrameView(data), view: new DataFrameView(data),
rowIndex, rowIndex,
colIndex, colIndex,
display: field.display!(field.values.get(rowIndex)), display: field.display!(field.values[rowIndex]),
hasLinks: true, hasLinks: true,
}; };

View File

@ -85,10 +85,10 @@ export const getFieldLinksSupplier = (value: FieldDisplay): LinkModelSupplier<Fi
const { timeField } = getTimeField(dataFrame); const { timeField } = getTimeField(dataFrame);
scopedVars['__value'] = { scopedVars['__value'] = {
value: { value: {
raw: field.values.get(value.rowIndex), raw: field.values[value.rowIndex],
numeric: value.display.numeric, numeric: value.display.numeric,
text: formattedValueToString(value.display), text: formattedValueToString(value.display),
time: timeField ? timeField.values.get(value.rowIndex) : undefined, time: timeField ? timeField.values[value.rowIndex] : undefined,
}, },
text: 'Value', text: 'Value',
}; };

View File

@ -11,11 +11,11 @@ export class ResponseParser implements ResponseParserType {
if (textField && valueField) { if (textField && valueField) {
for (let i = 0; i < textField.values.length; i++) { for (let i = 0; i < textField.values.length; i++) {
values.push({ text: '' + textField.values.get(i), value: '' + valueField.values.get(i) }); values.push({ text: '' + textField.values[i], value: '' + valueField.values[i] });
} }
} else { } else {
for (const field of frame.fields) { for (const field of frame.fields) {
for (const value of field.values.toArray()) { for (const value of field.values) {
values.push({ text: value }); values.push({ text: value });
} }
} }

View File

@ -2,7 +2,7 @@ import { render, screen, act } from '@testing-library/react';
import userEvent from '@testing-library/user-event'; import userEvent from '@testing-library/user-event';
import React from 'react'; import React from 'react';
import { ArrayVector, DataFrame, DataFrameView, FieldType } from '@grafana/data'; import { DataFrame, DataFrameView, FieldType } from '@grafana/data';
import { DashboardQueryResult, getGrafanaSearcher, QueryResponse } from '../../service'; import { DashboardQueryResult, getGrafanaSearcher, QueryResponse } from '../../service';
import { DashboardSearchItemType, DashboardViewItem } from '../../types'; import { DashboardSearchItemType, DashboardViewItem } from '../../types';
@ -29,12 +29,12 @@ describe('FolderSection', () => {
describe('when there are no results', () => { describe('when there are no results', () => {
const emptySearchData: DataFrame = { const emptySearchData: DataFrame = {
fields: [ fields: [
{ name: 'kind', type: FieldType.string, config: {}, values: new ArrayVector([]) }, { name: 'kind', type: FieldType.string, config: {}, values: [] },
{ name: 'name', type: FieldType.string, config: {}, values: new ArrayVector([]) }, { name: 'name', type: FieldType.string, config: {}, values: [] },
{ name: 'uid', type: FieldType.string, config: {}, values: new ArrayVector([]) }, { name: 'uid', type: FieldType.string, config: {}, values: [] },
{ name: 'url', type: FieldType.string, config: {}, values: new ArrayVector([]) }, { name: 'url', type: FieldType.string, config: {}, values: [] },
{ name: 'tags', type: FieldType.other, config: {}, values: new ArrayVector([]) }, { name: 'tags', type: FieldType.other, config: {}, values: [] },
{ name: 'location', type: FieldType.string, config: {}, values: new ArrayVector([]) }, { name: 'location', type: FieldType.string, config: {}, values: [] },
], ],
length: 0, length: 0,
}; };
@ -95,12 +95,12 @@ describe('FolderSection', () => {
describe('when there are results', () => { describe('when there are results', () => {
const searchData: DataFrame = { const searchData: DataFrame = {
fields: [ fields: [
{ name: 'kind', type: FieldType.string, config: {}, values: new ArrayVector([DashboardSearchItemType.DashDB]) }, { name: 'kind', type: FieldType.string, config: {}, values: [DashboardSearchItemType.DashDB] },
{ name: 'name', type: FieldType.string, config: {}, values: new ArrayVector(['My dashboard 1']) }, { name: 'name', type: FieldType.string, config: {}, values: ['My dashboard 1'] },
{ name: 'uid', type: FieldType.string, config: {}, values: new ArrayVector(['my-dashboard-1']) }, { name: 'uid', type: FieldType.string, config: {}, values: ['my-dashboard-1'] },
{ name: 'url', type: FieldType.string, config: {}, values: new ArrayVector(['/my-dashboard-1']) }, { name: 'url', type: FieldType.string, config: {}, values: ['/my-dashboard-1'] },
{ name: 'tags', type: FieldType.other, config: {}, values: new ArrayVector([['foo', 'bar']]) }, { name: 'tags', type: FieldType.other, config: {}, values: [['foo', 'bar']] },
{ name: 'location', type: FieldType.string, config: {}, values: new ArrayVector(['my-folder-1']) }, { name: 'location', type: FieldType.string, config: {}, values: ['my-folder-1'] },
], ],
meta: { meta: {
custom: { custom: {

View File

@ -1,7 +1,7 @@
import { render, screen, act } from '@testing-library/react'; import { render, screen, act } from '@testing-library/react';
import React from 'react'; import React from 'react';
import { ArrayVector, DataFrame, DataFrameView, FieldType } from '@grafana/data'; import { DataFrame, DataFrameView, FieldType } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors'; import { selectors } from '@grafana/e2e-selectors';
import { ContextSrv, setContextSrv } from '../../../../core/services/context_srv'; import { ContextSrv, setContextSrv } from '../../../../core/services/context_srv';
@ -30,11 +30,11 @@ describe('RootFolderView', () => {
name: 'kind', name: 'kind',
type: FieldType.string, type: FieldType.string,
config: {}, config: {},
values: new ArrayVector([DashboardSearchItemType.DashFolder]), values: [DashboardSearchItemType.DashFolder],
}, },
{ name: 'name', type: FieldType.string, config: {}, values: new ArrayVector(['My folder 1']) }, { name: 'name', type: FieldType.string, config: {}, values: ['My folder 1'] },
{ name: 'uid', type: FieldType.string, config: {}, values: new ArrayVector(['my-folder-1']) }, { name: 'uid', type: FieldType.string, config: {}, values: ['my-folder-1'] },
{ name: 'url', type: FieldType.string, config: {}, values: new ArrayVector(['/my-folder-1']) }, { name: 'url', type: FieldType.string, config: {}, values: ['/my-folder-1'] },
], ],
length: 1, length: 1,
}; };

View File

@ -2,7 +2,7 @@ import { render, screen } from '@testing-library/react';
import React from 'react'; import React from 'react';
import { Subject } from 'rxjs'; import { Subject } from 'rxjs';
import { ArrayVector, DataFrame, DataFrameView, FieldType } from '@grafana/data'; import { DataFrame, DataFrameView, FieldType } from '@grafana/data';
import { DashboardQueryResult, getGrafanaSearcher, QueryResponse } from '../../service'; import { DashboardQueryResult, getGrafanaSearcher, QueryResponse } from '../../service';
import { DashboardSearchItemType } from '../../types'; import { DashboardSearchItemType } from '../../types';
@ -19,14 +19,14 @@ describe('SearchResultsCards', () => {
describe('when there is data', () => { describe('when there is data', () => {
const searchData: DataFrame = { const searchData: DataFrame = {
fields: [ fields: [
{ name: 'kind', type: FieldType.string, config: {}, values: new ArrayVector([DashboardSearchItemType.DashDB]) }, { name: 'kind', type: FieldType.string, config: {}, values: [DashboardSearchItemType.DashDB] },
{ name: 'uid', type: FieldType.string, config: {}, values: new ArrayVector(['my-dashboard-1']) }, { name: 'uid', type: FieldType.string, config: {}, values: ['my-dashboard-1'] },
{ name: 'name', type: FieldType.string, config: {}, values: new ArrayVector(['My dashboard 1']) }, { name: 'name', type: FieldType.string, config: {}, values: ['My dashboard 1'] },
{ name: 'panel_type', type: FieldType.string, config: {}, values: new ArrayVector(['']) }, { name: 'panel_type', type: FieldType.string, config: {}, values: [''] },
{ name: 'url', type: FieldType.string, config: {}, values: new ArrayVector(['/my-dashboard-1']) }, { name: 'url', type: FieldType.string, config: {}, values: ['/my-dashboard-1'] },
{ name: 'tags', type: FieldType.other, config: {}, values: new ArrayVector([['foo', 'bar']]) }, { name: 'tags', type: FieldType.other, config: {}, values: [['foo', 'bar']] },
{ name: 'ds_uid', type: FieldType.other, config: {}, values: new ArrayVector(['']) }, { name: 'ds_uid', type: FieldType.other, config: {}, values: [''] },
{ name: 'location', type: FieldType.string, config: {}, values: new ArrayVector(['folder0/my-dashboard-1']) }, { name: 'location', type: FieldType.string, config: {}, values: ['folder0/my-dashboard-1'] },
], ],
meta: { meta: {
custom: { custom: {
@ -90,12 +90,12 @@ describe('SearchResultsCards', () => {
describe('when there is no data', () => { describe('when there is no data', () => {
const emptySearchData: DataFrame = { const emptySearchData: DataFrame = {
fields: [ fields: [
{ name: 'kind', type: FieldType.string, config: {}, values: new ArrayVector([]) }, { name: 'kind', type: FieldType.string, config: {}, values: [] },
{ name: 'name', type: FieldType.string, config: {}, values: new ArrayVector([]) }, { name: 'name', type: FieldType.string, config: {}, values: [] },
{ name: 'uid', type: FieldType.string, config: {}, values: new ArrayVector([]) }, { name: 'uid', type: FieldType.string, config: {}, values: [] },
{ name: 'url', type: FieldType.string, config: {}, values: new ArrayVector([]) }, { name: 'url', type: FieldType.string, config: {}, values: [] },
{ name: 'tags', type: FieldType.other, config: {}, values: new ArrayVector([]) }, { name: 'tags', type: FieldType.other, config: {}, values: [] },
{ name: 'location', type: FieldType.string, config: {}, values: new ArrayVector([]) }, { name: 'location', type: FieldType.string, config: {}, values: [] },
], ],
length: 0, length: 0,
}; };

View File

@ -2,15 +2,7 @@ import { render, screen } from '@testing-library/react';
import React from 'react'; import React from 'react';
import { Subject } from 'rxjs'; import { Subject } from 'rxjs';
import { import { applyFieldOverrides, createTheme, DataFrame, DataFrameView, FieldType, toDataFrame } from '@grafana/data';
applyFieldOverrides,
ArrayVector,
createTheme,
DataFrame,
DataFrameView,
FieldType,
toDataFrame,
} from '@grafana/data';
import { DashboardQueryResult, getGrafanaSearcher, QueryResponse } from '../../service'; import { DashboardQueryResult, getGrafanaSearcher, QueryResponse } from '../../service';
import { DashboardSearchItemType } from '../../types'; import { DashboardSearchItemType } from '../../types';
@ -121,12 +113,12 @@ describe('SearchResultsTable', () => {
describe('when there is no data', () => { describe('when there is no data', () => {
const emptySearchData: DataFrame = { const emptySearchData: DataFrame = {
fields: [ fields: [
{ name: 'kind', type: FieldType.string, config: {}, values: new ArrayVector([]) }, { name: 'kind', type: FieldType.string, config: {}, values: [] },
{ name: 'name', type: FieldType.string, config: {}, values: new ArrayVector([]) }, { name: 'name', type: FieldType.string, config: {}, values: [] },
{ name: 'uid', type: FieldType.string, config: {}, values: new ArrayVector([]) }, { name: 'uid', type: FieldType.string, config: {}, values: [] },
{ name: 'url', type: FieldType.string, config: {}, values: new ArrayVector([]) }, { name: 'url', type: FieldType.string, config: {}, values: [] },
{ name: 'tags', type: FieldType.other, config: {}, values: new ArrayVector([]) }, { name: 'tags', type: FieldType.other, config: {}, values: [] },
{ name: 'location', type: FieldType.string, config: {}, values: new ArrayVector([]) }, { name: 'location', type: FieldType.string, config: {}, values: [] },
], ],
length: 0, length: 0,
}; };

View File

@ -108,7 +108,7 @@ export const SearchResultsTable = React.memo(
const row = rows[rowIndex]; const row = rows[rowIndex];
prepareRow(row); prepareRow(row);
const url = response.view.fields.url?.values.get(rowIndex); const url = response.view.fields.url?.values[rowIndex];
let className = styles.rowContainer; let className = styles.rowContainer;
if (rowIndex === highlightIndex.y) { if (rowIndex === highlightIndex.y) {
className += ' ' + styles.selectedRow; className += ' ' + styles.selectedRow;

View File

@ -5,7 +5,7 @@ import { Provider } from 'react-redux';
import configureMockStore from 'redux-mock-store'; import configureMockStore from 'redux-mock-store';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { ArrayVector, DataFrame, DataFrameView, FieldType } from '@grafana/data'; import { DataFrame, DataFrameView, FieldType } from '@grafana/data';
import { config } from '@grafana/runtime'; import { config } from '@grafana/runtime';
import { DashboardQueryResult, getGrafanaSearcher, QueryResponse } from '../../service'; import { DashboardQueryResult, getGrafanaSearcher, QueryResponse } from '../../service';
@ -50,11 +50,11 @@ describe('SearchView', () => {
name: 'kind', name: 'kind',
type: FieldType.string, type: FieldType.string,
config: {}, config: {},
values: new ArrayVector([DashboardSearchItemType.DashFolder]), values: [DashboardSearchItemType.DashFolder],
}, },
{ name: 'name', type: FieldType.string, config: {}, values: new ArrayVector(['My folder 1']) }, { name: 'name', type: FieldType.string, config: {}, values: ['My folder 1'] },
{ name: 'uid', type: FieldType.string, config: {}, values: new ArrayVector(['my-folder-1']) }, { name: 'uid', type: FieldType.string, config: {}, values: ['my-folder-1'] },
{ name: 'url', type: FieldType.string, config: {}, values: new ArrayVector(['/my-folder-1']) }, { name: 'url', type: FieldType.string, config: {}, values: ['/my-folder-1'] },
], ],
length: 1, length: 1,
}; };

View File

@ -92,8 +92,8 @@ export const generateColumns = (
); );
}, },
Cell: (p) => { Cell: (p) => {
const uid = uidField.values.get(p.row.index); const uid = uidField.values[p.row.index];
const kind = kindField ? kindField.values.get(p.row.index) : 'dashboard'; // HACK for now const kind = kindField ? kindField.values[p.row.index] : 'dashboard'; // HACK for now
const selected = selection(kind, uid); const selected = selection(kind, uid);
const hasUID = uid != null; // Panels don't have UID! Likely should not be shown on pages with manage options const hasUID = uid != null; // Panels don't have UID! Likely should not be shown on pages with manage options
return ( return (
@ -120,7 +120,7 @@ export const generateColumns = (
columns.push({ columns.push({
Cell: (p) => { Cell: (p) => {
let classNames = cx(styles.nameCellStyle); let classNames = cx(styles.nameCellStyle);
let name = access.name.values.get(p.row.index); let name = access.name.values[p.row.index];
if (!name?.length) { if (!name?.length) {
const loading = p.row.index >= response.view.dataFrame.length; const loading = p.row.index >= response.view.dataFrame.length;
name = loading ? 'Loading...' : 'Missing title'; // normal for panels name = loading ? 'Loading...' : 'Missing title'; // normal for panels
@ -166,7 +166,7 @@ export const generateColumns = (
availableWidth -= width; availableWidth -= width;
columns.push({ columns.push({
Cell: (p) => { Cell: (p) => {
const parts = (access.location?.values.get(p.row.index) ?? '').split('/'); const parts = (access.location?.values[p.row.index] ?? '').split('/');
return ( return (
<div {...p.cellProps} className={cx(styles.locationCellStyle)}> <div {...p.cellProps} className={cx(styles.locationCellStyle)}>
{parts.map((p) => { {parts.map((p) => {
@ -226,8 +226,8 @@ export const generateColumns = (
new ShowModalReactEvent({ new ShowModalReactEvent({
component: ExplainScorePopup, component: ExplainScorePopup,
props: { props: {
name: access.name.values.get(row), name: access.name.values[row],
explain: access.explain.values.get(row), explain: access.explain.values[row],
frame: response.view.dataFrame, frame: response.view.dataFrame,
row: row, row: row,
}, },
@ -255,7 +255,7 @@ export const generateColumns = (
function hasValue(f: Field): boolean { function hasValue(f: Field): boolean {
for (let i = 0; i < f.values.length; i++) { for (let i = 0; i < f.values.length; i++) {
if (f.values.get(i) != null) { if (f.values[i] != null) {
return true; return true;
} }
} }
@ -276,7 +276,7 @@ function makeDataSourceColumn(
field, field,
Header: t('search.results-table.datasource-header', 'Data source'), Header: t('search.results-table.datasource-header', 'Data source'),
Cell: (p) => { Cell: (p) => {
const dslist = field.values.get(p.row.index); const dslist = field.values[p.row.index];
if (!dslist?.length) { if (!dslist?.length) {
return null; return null;
} }
@ -325,7 +325,7 @@ function makeTypeColumn(
Header: t('search.results-table.type-header', 'Type'), Header: t('search.results-table.type-header', 'Type'),
Cell: (p) => { Cell: (p) => {
const i = p.row.index; const i = p.row.index;
const kind = kindField?.values.get(i) ?? 'dashboard'; const kind = kindField?.values[i] ?? 'dashboard';
let icon: IconName = 'apps'; let icon: IconName = 'apps';
let txt = 'Dashboard'; let txt = 'Dashboard';
if (kind) { if (kind) {
@ -342,7 +342,7 @@ function makeTypeColumn(
case 'panel': case 'panel':
icon = `${PluginIconName.panel}`; icon = `${PluginIconName.panel}`;
const type = typeField.values.get(i); const type = typeField.values[i];
if (type) { if (type) {
txt = type; txt = type;
const info = config.panels[txt]; const info = config.panels[txt];
@ -384,7 +384,7 @@ function makeTagsColumn(
): TableColumn { ): TableColumn {
return { return {
Cell: (p) => { Cell: (p) => {
const tags = field.values.get(p.row.index); const tags = field.values[p.row.index];
return tags ? ( return tags ? (
<div {...p.cellProps}> <div {...p.cellProps}>
<TagList className={tagListClass} tags={tags} onClick={onTagSelected} /> <TagList className={tagListClass} tags={tags} onClick={onTagSelected} />
@ -409,8 +409,8 @@ function getDisplayValue({
index: number; index: number;
getDisplay: DisplayProcessor; getDisplay: DisplayProcessor;
}) { }) {
const value = sortField.values.get(index); const value = sortField.values[index];
if (['folder', 'panel'].includes(kind.values.get(index)) && value === 0) { if (['folder', 'panel'].includes(kind.values[index]) && value === 0) {
return '-'; return '-';
} }
return formattedValueToString(getDisplay(value)); return formattedValueToString(getDisplay(value));

View File

@ -25,7 +25,7 @@ describe('FrontendSearcher', () => {
}; };
const results = await frontendSearcher.search(query); const results = await frontendSearcher.search(query);
expect(results.view.fields.name.values.toArray()).toMatchInlineSnapshot(` expect(results.view.fields.name.values).toMatchInlineSnapshot(`
[ [
"foo cat", "foo cat",
"bar dog", "bar dog",
@ -43,7 +43,7 @@ describe('FrontendSearcher', () => {
}; };
const results = await frontendSearcher.search(query); const results = await frontendSearcher.search(query);
expect(results.view.fields.name.values.toArray()).toMatchInlineSnapshot(` expect(results.view.fields.name.values).toMatchInlineSnapshot(`
[ [
"bar dog", "bar dog",
"cow baz", "cow baz",
@ -60,7 +60,7 @@ describe('FrontendSearcher', () => {
}; };
const results = await frontendSearcher.search(query); const results = await frontendSearcher.search(query);
expect(results.view.fields.name.values.toArray()).toMatchInlineSnapshot(` expect(results.view.fields.name.values).toMatchInlineSnapshot(`
[ [
"bar dog", "bar dog",
] ]

View File

@ -1,6 +1,6 @@
import uFuzzy from '@leeoniya/ufuzzy'; import uFuzzy from '@leeoniya/ufuzzy';
import { DataFrameView, SelectableValue, ArrayVector } from '@grafana/data'; import { DataFrameView, SelectableValue } from '@grafana/data';
import { TermCount } from 'app/core/components/TagFilter/TagFilter'; import { TermCount } from 'app/core/components/TagFilter/TagFilter';
import { DashboardQueryResult, GrafanaSearcher, QueryResponse, SearchQuery } from '.'; import { DashboardQueryResult, GrafanaSearcher, QueryResponse, SearchQuery } from '.';
@ -94,12 +94,12 @@ class FullResultCache {
}); });
constructor(private full: DataFrameView<DashboardQueryResult>) { constructor(private full: DataFrameView<DashboardQueryResult>) {
this.names = this.full.fields.name.values.toArray(); this.names = this.full.fields.name.values;
// Copy with empty values // Copy with empty values
this.empty = new DataFrameView<DashboardQueryResult>({ this.empty = new DataFrameView<DashboardQueryResult>({
...this.full.dataFrame, // copy folder metadata ...this.full.dataFrame, // copy folder metadata
fields: this.full.dataFrame.fields.map((v) => ({ ...v, values: new ArrayVector([]) })), fields: this.full.dataFrame.fields.map((v) => ({ ...v, values: [] })),
length: 0, // for now length: 0, // for now
}); });
} }
@ -119,7 +119,7 @@ class FullResultCache {
let [idxs, info, order] = this.ufuzzy.search(haystack, query, true); let [idxs, info, order] = this.ufuzzy.search(haystack, query, true);
for (let c = 0; c < allFields.length; c++) { for (let c = 0; c < allFields.length; c++) {
let src = allFields[c].values.toArray(); let src = allFields[c].values;
let dst = values[c]; let dst = values[c];
// <= 1000 matches (ranked) // <= 1000 matches (ranked)
@ -140,7 +140,7 @@ class FullResultCache {
// mutates the search object // mutates the search object
this.empty.dataFrame.fields.forEach((f, idx) => { this.empty.dataFrame.fields.forEach((f, idx) => {
f.values = new ArrayVector(values[idx]); // or just set it? f.values = values[idx]; // or just set it?
}); });
this.empty.dataFrame.length = this.empty.dataFrame.fields[0].values.length; this.empty.dataFrame.length = this.empty.dataFrame.fields[0].values.length;

View File

@ -1,4 +1,4 @@
import { ArrayVector, DataFrame, DataFrameView, FieldType, getDisplayProcessor, SelectableValue } from '@grafana/data'; import { DataFrame, DataFrameView, FieldType, getDisplayProcessor, SelectableValue } from '@grafana/data';
import { config } from '@grafana/runtime'; import { config } from '@grafana/runtime';
import { TermCount } from 'app/core/components/TagFilter/TagFilter'; import { TermCount } from 'app/core/components/TagFilter/TagFilter';
import { backendSrv } from 'app/core/services/backend_srv'; import { backendSrv } from 'app/core/services/backend_srv';
@ -182,12 +182,12 @@ export class SQLSearcher implements GrafanaSearcher {
const data: DataFrame = { const data: DataFrame = {
fields: [ fields: [
{ name: 'kind', type: FieldType.string, config: {}, values: new ArrayVector(kind) }, { name: 'kind', type: FieldType.string, config: {}, values: kind },
{ name: 'name', type: FieldType.string, config: {}, values: new ArrayVector(name) }, { name: 'name', type: FieldType.string, config: {}, values: name },
{ name: 'uid', type: FieldType.string, config: {}, values: new ArrayVector(uid) }, { name: 'uid', type: FieldType.string, config: {}, values: uid },
{ name: 'url', type: FieldType.string, config: {}, values: new ArrayVector(url) }, { name: 'url', type: FieldType.string, config: {}, values: url },
{ name: 'tags', type: FieldType.other, config: {}, values: new ArrayVector(tags) }, { name: 'tags', type: FieldType.other, config: {}, values: tags },
{ name: 'location', type: FieldType.string, config: {}, values: new ArrayVector(location) }, { name: 'location', type: FieldType.string, config: {}, values: location },
], ],
length: name.length, length: name.length,
meta: { meta: {
@ -206,7 +206,7 @@ export class SQLSearcher implements GrafanaSearcher {
name: sortMetaName, // Used in display name: sortMetaName, // Used in display
type: FieldType.number, type: FieldType.number,
config: {}, config: {},
values: new ArrayVector(sortBy), values: sortBy,
}); });
} }

View File

@ -21,7 +21,7 @@ export function StorageFolderPage(props: Props) {
const renderListing = () => { const renderListing = () => {
if (listing.value) { if (listing.value) {
const names = listing.value.fields[0].values.toArray(); const names = listing.value.fields[0].values;
return names.map((item: string) => { return names.map((item: string) => {
let name = item; let name = item;
const isFolder = name.indexOf('.') < 0; const isFolder = name.indexOf('.') < 0;

View File

@ -68,7 +68,7 @@ export default function StoragePage(props: Props) {
frame.fields[0] = { frame.fields[0] = {
...name, ...name,
getLinks: (cfg: ValueLinkConfig) => { getLinks: (cfg: ValueLinkConfig) => {
const n = name.values.get(cfg.valueRowIndex ?? 0); const n = name.values[cfg.valueRowIndex ?? 0];
const p = path + '/' + n; const p = path + '/' + n;
return [ return [
{ {
@ -93,7 +93,7 @@ export default function StoragePage(props: Props) {
if (listing.value) { if (listing.value) {
const length = listing.value.length; const length = listing.value.length;
if (length === 1) { if (length === 1) {
const first = listing.value.fields[0].values.get(0) as string; const first = listing.value.fields[0].values[0] as string;
isFolder = !path.endsWith(first); isFolder = !path.endsWith(first);
} else { } else {
// TODO: handle files/folders which do not exist // TODO: handle files/folders which do not exist
@ -104,12 +104,7 @@ export default function StoragePage(props: Props) {
}, [path, listing]); }, [path, listing]);
const fileNames = useMemo(() => { const fileNames = useMemo(() => {
return ( return listing.value?.fields?.find((f) => f.name === 'name')?.values.filter((v) => typeof v === 'string') ?? [];
listing.value?.fields
?.find((f) => f.name === 'name')
?.values?.toArray()
?.filter((v) => typeof v === 'string') ?? []
);
}, [listing]); }, [listing]);
const renderView = () => { const renderView = () => {

View File

@ -54,10 +54,10 @@ function getValueForValueMacro(match: string, fieldPath?: string, scopedVars?: S
if (fieldPath === 'time') { if (fieldPath === 'time') {
const timeField = frame.fields.find((f) => f.type === FieldType.time); const timeField = frame.fields.find((f) => f.type === FieldType.time);
return timeField ? timeField.values.get(rowIndex) : undefined; return timeField ? timeField.values[rowIndex] : undefined;
} }
const value = field.values.get(rowIndex); const value = field.values[rowIndex];
if (fieldPath === 'raw') { if (fieldPath === 'raw') {
return value; return value;
} }

View File

@ -53,7 +53,7 @@ export function getFieldConfigFromFrame(
continue; continue;
} }
const configValue = field.values.get(rowIndex); const configValue = field.values[rowIndex];
if (configValue === null || configValue === undefined) { if (configValue === null || configValue === undefined) {
continue; continue;

View File

@ -72,10 +72,10 @@ export function toMetricFindValues(): OperatorFunction<PanelData, MetricFindValu
for (const frame of frames) { for (const frame of frames) {
for (let index = 0; index < frame.length; index++) { for (let index = 0; index < frame.length; index++) {
const expandable = expandableIndex !== -1 ? frame.fields[expandableIndex].values.get(index) : undefined; const expandable = expandableIndex !== -1 ? frame.fields[expandableIndex].values[index] : undefined;
const string = frame.fields[stringIndex].values.get(index); const string = frame.fields[stringIndex].values[index];
const text = textIndex !== -1 ? frame.fields[textIndex].values.get(index) : null; const text = textIndex !== -1 ? frame.fields[textIndex].values[index] : null;
const value = valueIndex !== -1 ? frame.fields[valueIndex].values.get(index) : null; const value = valueIndex !== -1 ? frame.fields[valueIndex].values[index] : null;
if (valueIndex === -1 && textIndex === -1) { if (valueIndex === -1 && textIndex === -1) {
metrics.push({ text: string, value: string, expandable }); metrics.push({ text: string, value: string, expandable });

View File

@ -4,7 +4,6 @@ import {
DataFrame, DataFrame,
dataFrameToJSON, dataFrameToJSON,
MutableDataFrame, MutableDataFrame,
ArrayVector,
DataSourceInstanceSettings, DataSourceInstanceSettings,
DataSourceJsonData, DataSourceJsonData,
DataSourceRef, DataSourceRef,
@ -35,15 +34,15 @@ export function setupForLogs() {
fields: [ fields: [
{ {
name: '@message', name: '@message',
values: new ArrayVector(['something']), values: ['something'],
}, },
{ {
name: '@timestamp', name: '@timestamp',
values: new ArrayVector([1]), values: [1],
}, },
{ {
name: '@xrayTraceId', name: '@xrayTraceId',
values: new ArrayVector(['1-613f0d6b-3e7cb34375b60662359611bd']), values: ['1-613f0d6b-3e7cb34375b60662359611bd'],
}, },
], ],
meta: { custom: { Status: CloudWatchLogsQueryStatus.Complete } }, meta: { custom: { Status: CloudWatchLogsQueryStatus.Complete } },

View File

@ -128,7 +128,7 @@ export class CloudWatchLogsQueryRunner extends CloudWatchRequest {
// This queries for the results // This queries for the results
this.logsQuery( this.logsQuery(
frames.map((dataFrame) => ({ frames.map((dataFrame) => ({
queryId: dataFrame.fields[0].values.get(0), queryId: dataFrame.fields[0].values[0],
region: dataFrame.meta?.custom?.['Region'] ?? 'default', region: dataFrame.meta?.custom?.['Region'] ?? 'default',
refId: dataFrame.refId!, refId: dataFrame.refId!,
statsGroups: logQueries.find((target) => target.refId === dataFrame.refId)?.statsGroups, statsGroups: logQueries.find((target) => target.refId === dataFrame.refId)?.statsGroups,
@ -350,8 +350,8 @@ export class CloudWatchLogsQueryRunner extends CloudWatchRequest {
limit, limit,
startFromHead: direction !== LogRowContextQueryDirection.Backward, startFromHead: direction !== LogRowContextQueryDirection.Backward,
region: query?.region, region: query?.region,
logGroupName: parseLogGroupName(logField!.values.get(row.rowIndex)), logGroupName: parseLogGroupName(logField!.values[row.rowIndex]),
logStreamName: logStreamField!.values.get(row.rowIndex), logStreamName: logStreamField!.values[row.rowIndex],
}; };
if (direction === LogRowContextQueryDirection.Backward) { if (direction === LogRowContextQueryDirection.Backward) {

View File

@ -120,8 +120,8 @@ describe('runWithRetry', () => {
// dataframe fields // dataframe fields
expect(values.length).toBe(1); expect(values.length).toBe(1);
expect(values[0].frames.length).toBe(2); expect(values[0].frames.length).toBe(2);
expect(values[0].frames[0].fields[0].values.get(0)).toBe('A'); expect(values[0].frames[0].fields[0].values[0]).toBe('A');
expect(values[0].frames[1].fields[0].values.get(0)).toBe('B'); expect(values[0].frames[1].fields[0].values[0]).toBe('B');
}); });
it('sends data and also error if only one query gets limit error', async () => { it('sends data and also error if only one query gets limit error', async () => {
@ -145,7 +145,7 @@ describe('runWithRetry', () => {
expect(queryFunc).nthCalledWith(1, targets); expect(queryFunc).nthCalledWith(1, targets);
expect(values.length).toBe(1); expect(values.length).toBe(1);
expect(values[0].frames.length).toBe(1); expect(values[0].frames.length).toBe(1);
expect(values[0].frames[0].fields[0].values.get(0)).toBe('A'); expect(values[0].frames[0].fields[0].values[0]).toBe('A');
expect(values[0].error).toEqual({ message: 'Some queries timed out: LimitExceededException' }); expect(values[0].error).toEqual({ message: 'Some queries timed out: LimitExceededException' });
}); });
@ -190,8 +190,8 @@ describe('runWithRetry', () => {
expect(queryFunc).nthCalledWith(3, [targetC]); expect(queryFunc).nthCalledWith(3, [targetC]);
expect(values.length).toBe(1); expect(values.length).toBe(1);
expect(values[0].frames.length).toBe(2); expect(values[0].frames.length).toBe(2);
expect(values[0].frames[0].fields[0].values.get(0)).toBe('A'); expect(values[0].frames[0].fields[0].values[0]).toBe('A');
expect(values[0].frames[1].fields[0].values.get(0)).toBe('B'); expect(values[0].frames[1].fields[0].values[0]).toBe('B');
expect(values[0].error).toEqual({ message: 'Some queries timed out: LimitExceededException' }); expect(values[0].error).toEqual({ message: 'Some queries timed out: LimitExceededException' });
}); });
}); });

View File

@ -315,8 +315,8 @@ describe('ElasticResponse', () => {
const frame = result.data[0]; const frame = result.data[0];
expect(frame.name).toBe('Count'); expect(frame.name).toBe('Count');
expect(frame.length).toBe(2); expect(frame.length).toBe(2);
expect(getTimeField(frame).values.get(0)).toBe(1000); expect(getTimeField(frame).values[0]).toBe(1000);
expect(getValueField(frame).values.get(0)).toBe(10); expect(getValueField(frame).values[0]).toBe(10);
}); });
}); });
@ -367,11 +367,11 @@ describe('ElasticResponse', () => {
const frame1 = result.data[0]; const frame1 = result.data[0];
const frame2 = result.data[1]; const frame2 = result.data[1];
expect(frame1.length).toBe(2); expect(frame1.length).toBe(2);
expect(getValueField(frame1).values.get(0)).toBe(10); expect(getValueField(frame1).values[0]).toBe(10);
expect(getTimeField(frame1).values.get(0)).toBe(1000); expect(getTimeField(frame1).values[0]).toBe(1000);
expect(frame2.name).toBe('Average value'); expect(frame2.name).toBe('Average value');
expect(getValueField(frame2).values.toArray()).toEqual([88, 99]); expect(getValueField(frame2).values).toEqual([88, 99]);
}); });
}); });
@ -546,9 +546,9 @@ describe('ElasticResponse', () => {
expect(result.data[0].length).toBe(2); expect(result.data[0].length).toBe(2);
expect(result.data[0].name).toBe('p75 @value'); expect(result.data[0].name).toBe('p75 @value');
expect(result.data[1].name).toBe('p90 @value'); expect(result.data[1].name).toBe('p90 @value');
expect(getValueField(result.data[0]).values.get(0)).toBe(3.3); expect(getValueField(result.data[0]).values[0]).toBe(3.3);
expect(getTimeField(result.data[0]).values.get(0)).toBe(1000); expect(getTimeField(result.data[0]).values[0]).toBe(1000);
expect(getValueField(result.data[1]).values.get(1)).toBe(4.5); expect(getValueField(result.data[1]).values[1]).toBe(4.5);
}); });
}); });
@ -629,8 +629,8 @@ describe('ElasticResponse', () => {
expect(result.data[0].name).toBe('server1 Max @value'); expect(result.data[0].name).toBe('server1 Max @value');
expect(result.data[1].name).toBe('server1 Std Dev Upper @value'); expect(result.data[1].name).toBe('server1 Std Dev Upper @value');
expect(getValueField(result.data[0]).values.get(0)).toBe(10.2); expect(getValueField(result.data[0]).values[0]).toBe(10.2);
expect(getValueField(result.data[1]).values.get(0)).toBe(3); expect(getValueField(result.data[1]).values[0]).toBe(3);
}); });
}); });
@ -688,20 +688,20 @@ describe('ElasticResponse', () => {
const firstSeries = result.data[0]; const firstSeries = result.data[0];
expect(firstSeries.name).toBe('Top Metrics @value'); expect(firstSeries.name).toBe('Top Metrics @value');
expect(firstSeries.length).toBe(2); expect(firstSeries.length).toBe(2);
expect(getTimeField(firstSeries).values.toArray()).toEqual([ expect(getTimeField(firstSeries).values).toEqual([
new Date('2021-01-01T00:00:00.000Z').valueOf(), new Date('2021-01-01T00:00:00.000Z').valueOf(),
new Date('2021-01-01T00:00:10.000Z').valueOf(), new Date('2021-01-01T00:00:10.000Z').valueOf(),
]); ]);
expect(getValueField(firstSeries).values.toArray()).toEqual([1, 1]); expect(getValueField(firstSeries).values).toEqual([1, 1]);
const secondSeries = result.data[1]; const secondSeries = result.data[1];
expect(secondSeries.name).toBe('Top Metrics @anotherValue'); expect(secondSeries.name).toBe('Top Metrics @anotherValue');
expect(secondSeries.length).toBe(2); expect(secondSeries.length).toBe(2);
expect(getTimeField(secondSeries).values.toArray()).toEqual([ expect(getTimeField(secondSeries).values).toEqual([
new Date('2021-01-01T00:00:00.000Z').valueOf(), new Date('2021-01-01T00:00:00.000Z').valueOf(),
new Date('2021-01-01T00:00:10.000Z').valueOf(), new Date('2021-01-01T00:00:10.000Z').valueOf(),
]); ]);
expect(getValueField(secondSeries).values.toArray()).toEqual([2, 2]); expect(getValueField(secondSeries).values).toEqual([2, 2]);
}); });
}); });
@ -1044,9 +1044,9 @@ describe('ElasticResponse', () => {
expect(field2.name).toBe('p75 value'); expect(field2.name).toBe('p75 value');
expect(field3.name).toBe('p90 value'); expect(field3.name).toBe('p90 value');
expect(field1.values.toArray()).toEqual(['id1', 'id2']); expect(field1.values).toEqual(['id1', 'id2']);
expect(field2.values.toArray()).toEqual([3.3, 2.3]); expect(field2.values).toEqual([3.3, 2.3]);
expect(field3.values.toArray()).toEqual([5.5, 4.5]); expect(field3.values).toEqual([5.5, 4.5]);
}); });
}); });
@ -1088,9 +1088,9 @@ describe('ElasticResponse', () => {
it('should include field in metric name', () => { it('should include field in metric name', () => {
expect(result.data[0].length).toBe(1); expect(result.data[0].length).toBe(1);
expect(result.data[0].fields.length).toBe(3); expect(result.data[0].fields.length).toBe(3);
expect(result.data[0].fields[0].values.toArray()).toEqual(['server-1']); expect(result.data[0].fields[0].values).toEqual(['server-1']);
expect(result.data[0].fields[1].values.toArray()).toEqual([1000]); expect(result.data[0].fields[1].values).toEqual([1000]);
expect(result.data[0].fields[2].values.toArray()).toEqual([3000]); expect(result.data[0].fields[2].values).toEqual([3000]);
}); });
}); });
@ -1139,7 +1139,7 @@ describe('ElasticResponse', () => {
expect(fields.length).toBe(1); expect(fields.length).toBe(1);
const field = fields[0]; const field = fields[0];
expect(field.type === FieldType.other); expect(field.type === FieldType.other);
const values = field.values.toArray(); const values = field.values;
expect(values.length).toBe(2); expect(values.length).toBe(2);
expect(values[0].sourceProp).toBe('asd'); expect(values[0].sourceProp).toBe('asd');
expect(values[0].fieldProp).toBe('field'); expect(values[0].fieldProp).toBe('field');
@ -1206,12 +1206,12 @@ describe('ElasticResponse', () => {
expect(result.data[0].name).toBe('Sum @value'); expect(result.data[0].name).toBe('Sum @value');
expect(result.data[1].name).toBe('Max @value'); expect(result.data[1].name).toBe('Max @value');
expect(result.data[2].name).toBe('Sum @value * Max @value'); expect(result.data[2].name).toBe('Sum @value * Max @value');
expect(getValueField(result.data[0]).values.get(0)).toBe(2); expect(getValueField(result.data[0]).values[0]).toBe(2);
expect(getValueField(result.data[1]).values.get(0)).toBe(3); expect(getValueField(result.data[1]).values[0]).toBe(3);
expect(getValueField(result.data[2]).values.get(0)).toBe(6); expect(getValueField(result.data[2]).values[0]).toBe(6);
expect(getValueField(result.data[0]).values.get(1)).toBe(3); expect(getValueField(result.data[0]).values[1]).toBe(3);
expect(getValueField(result.data[1]).values.get(1)).toBe(4); expect(getValueField(result.data[1]).values[1]).toBe(4);
expect(getValueField(result.data[2]).values.get(1)).toBe(12); expect(getValueField(result.data[2]).values[1]).toBe(12);
}); });
}); });
@ -1286,11 +1286,11 @@ describe('ElasticResponse', () => {
expect(frame.length).toBe(2); expect(frame.length).toBe(2);
const { fields } = frame; const { fields } = frame;
expect(fields.length).toBe(5); expect(fields.length).toBe(5);
expect(fields[0].values.toArray()).toEqual([1000, 2000]); expect(fields[0].values).toEqual([1000, 2000]);
expect(fields[1].values.toArray()).toEqual([2, 3]); expect(fields[1].values).toEqual([2, 3]);
expect(fields[2].values.toArray()).toEqual([3, 4]); expect(fields[2].values).toEqual([3, 4]);
expect(fields[3].values.toArray()).toEqual([6, 12]); expect(fields[3].values).toEqual([6, 12]);
expect(fields[4].values.toArray()).toEqual([24, 48]); expect(fields[4].values).toEqual([24, 48]);
}); });
}); });
@ -1338,7 +1338,7 @@ describe('ElasticResponse', () => {
it('should have time field values in DateTime format', () => { it('should have time field values in DateTime format', () => {
const timeField = result.data[0].fields.find((field) => field.name === '@timestamp'); const timeField = result.data[0].fields.find((field) => field.name === '@timestamp');
expect(timeField).toBeDefined(); expect(timeField).toBeDefined();
expect(timeField?.values.get(0)).toBe(1546300800000); expect(timeField?.values[0]).toBe(1546300800000);
}); });
}); });
@ -1467,14 +1467,14 @@ describe('ElasticResponse', () => {
const result = new ElasticResponse(targets, response).getLogs(undefined, 'level'); const result = new ElasticResponse(targets, response).getLogs(undefined, 'level');
const fieldCache = new FieldCache(result.data[0]); const fieldCache = new FieldCache(result.data[0]);
const field = fieldCache.getFieldByName('level'); const field = fieldCache.getFieldByName('level');
expect(field?.values.toArray()).toEqual(['debug', 'error']); expect(field?.values).toEqual(['debug', 'error']);
}); });
it('should re map levels field to new field', () => { it('should re map levels field to new field', () => {
const result = new ElasticResponse(targets, response).getLogs(undefined, 'fields.lvl'); const result = new ElasticResponse(targets, response).getLogs(undefined, 'fields.lvl');
const fieldCache = new FieldCache(result.data[0]); const fieldCache = new FieldCache(result.data[0]);
const field = fieldCache.getFieldByName('level'); const field = fieldCache.getFieldByName('level');
expect(field?.values.toArray()).toEqual(['debug', 'info']); expect(field?.values).toEqual(['debug', 'info']);
}); });
it('should correctly guess field types', () => { it('should correctly guess field types', () => {

View File

@ -604,7 +604,7 @@ export class ElasticResponse {
for (let frame of dataFrame) { for (let frame of dataFrame) {
for (let field of frame.fields) { 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; field.values = convertFieldType(field, { destinationType: FieldType.time }).values;
} }
} }

View File

@ -528,7 +528,7 @@ export class ElasticDatasource
); );
} else { } else {
const sortField = row.dataFrame.fields.find((f) => f.name === 'sort'); const sortField = row.dataFrame.fields.find((f) => f.name === 'sort');
const searchAfter = sortField?.values.get(row.rowIndex) || [row.timeEpochMs]; const searchAfter = sortField?.values[row.rowIndex] || [row.timeEpochMs];
const sort = options?.direction === LogRowContextQueryDirection.Forward ? 'asc' : 'desc'; const sort = options?.direction === LogRowContextQueryDirection.Forward ? 'asc' : 'desc';
const header = const header =
@ -1125,7 +1125,7 @@ export class ElasticDatasource
// Sorting of results in the context query // Sorting of results in the context query
sortDirection: direction === LogRowContextQueryDirection.Backward ? 'desc' : 'asc', sortDirection: direction === LogRowContextQueryDirection.Backward ? 'desc' : 'asc',
// Used to get the next log lines before/after the current log line using sort field of selected log line // Used to get the next log lines before/after the current log line using sort field of selected log line
searchAfter: row.dataFrame.fields.find((f) => f.name === 'sort')?.values.get(row.rowIndex) ?? [row.timeEpochMs], searchAfter: row.dataFrame.fields.find((f) => f.name === 'sort')?.values[row.rowIndex] ?? [row.timeEpochMs],
}, },
}; };

View File

@ -134,7 +134,7 @@ export class UnthemedQueryEditor extends PureComponent<Props, State> {
next: (rsp) => { next: (rsp) => {
if (rsp.data.length) { if (rsp.data.length) {
const names = (rsp.data[0] as DataFrame).fields[0]; const names = (rsp.data[0] as DataFrame).fields[0];
const folders = names.values.toArray().map((v) => ({ const folders = names.values.map((v) => ({
value: v, value: v,
label: v, label: v,
})); }));

View File

@ -178,7 +178,7 @@ describe('graphiteDatasource', () => {
it('should convert to millisecond resolution', async () => { it('should convert to millisecond resolution', async () => {
await expect(response).toEmitValuesWith((values: any) => { await expect(response).toEmitValuesWith((values: any) => {
const results = values[0]; const results = values[0];
expect(results.data[0].fields[1].values.get(0)).toBe(10); expect(results.data[0].fields[1].values[0]).toBe(10);
}); });
}); });
}); });

View File

@ -376,8 +376,8 @@ export class GraphiteDatasource
const target = result.data[i]; const target = result.data[i];
for (let y = 0; y < target.length; y++) { for (let y = 0; y < target.length; y++) {
const time = target.fields[0].values.get(y); const time = target.fields[0].values[y];
const value = target.fields[1].values.get(y); const value = target.fields[1].values[y];
if (!value) { if (!value) {
continue; continue;

View File

@ -4,7 +4,6 @@ import { catchError, map } from 'rxjs/operators';
import { import {
AnnotationEvent, AnnotationEvent,
ArrayVector,
DataFrame, DataFrame,
DataQueryError, DataQueryError,
DataQueryRequest, DataQueryRequest,
@ -89,7 +88,7 @@ function timeSeriesToDataFrame(timeSeries: TimeSeries): DataFrame {
name: TIME_SERIES_TIME_FIELD_NAME, name: TIME_SERIES_TIME_FIELD_NAME,
type: FieldType.time, type: FieldType.time,
config: {}, config: {},
values: new ArrayVector<number>(times), values: times,
}; };
const valueField = { const valueField = {
@ -98,7 +97,7 @@ function timeSeriesToDataFrame(timeSeries: TimeSeries): DataFrame {
config: { config: {
displayNameFromDS: timeSeries.title, displayNameFromDS: timeSeries.title,
}, },
values: new ArrayVector<unknown>(values), values: values,
labels: timeSeries.tags, labels: timeSeries.tags,
}; };

View File

@ -234,12 +234,12 @@ function getTableCols(dfs: DataFrame[], table: TableModel, target: InfluxQuery):
} }
function getTableRows(dfs: DataFrame[], table: TableModel, labels: string[]): TableModel { function getTableRows(dfs: DataFrame[], table: TableModel, labels: string[]): TableModel {
const values = dfs[0].fields[0].values.toArray(); const values = dfs[0].fields[0].values;
for (let i = 0; i < values.length; i++) { for (let i = 0; i < values.length; i++) {
const time = values[i]; const time = values[i];
const metrics = dfs.map((df: DataFrame) => { const metrics = dfs.map((df: DataFrame) => {
return df.fields[1] ? df.fields[1].values.toArray()[i] : null; return df.fields[1] ? df.fields[1].values[i] : null;
}); });
if (metrics.indexOf(null) < 0) { if (metrics.indexOf(null) < 0) {
table.rows.push([time, ...labels, ...metrics]); table.rows.push([time, ...labels, ...metrics]);

View File

@ -125,7 +125,7 @@ export class LogContextProvider {
if (tsField === undefined) { if (tsField === undefined) {
throw new Error('loki: data frame missing time-field, should never happen'); throw new Error('loki: data frame missing time-field, should never happen');
} }
const tsValue = tsField.values.get(row.rowIndex); const tsValue = tsField.values[row.rowIndex];
const timestamp = toUtc(tsValue); const timestamp = toUtc(tsValue);
const range = const range =

View File

@ -1,6 +1,6 @@
import { cloneDeep } from 'lodash'; import { cloneDeep } from 'lodash';
import { ArrayVector, DataFrame, DataQueryResponse, Field, FieldType } from '@grafana/data'; import { DataFrame, DataQueryResponse, Field, FieldType } from '@grafana/data';
import { transformBackendResult } from './backendResultTransformer'; import { transformBackendResult } from './backendResultTransformer';
@ -31,34 +31,34 @@ const inputFrame: DataFrame = {
name: 'Time', name: 'Time',
type: FieldType.time, type: FieldType.time,
config: {}, config: {},
values: new ArrayVector([1645030244810, 1645030247027]), values: [1645030244810, 1645030247027],
}, },
{ {
name: 'Line', name: 'Line',
type: FieldType.string, type: FieldType.string,
config: {}, config: {},
values: new ArrayVector(['line1', 'line2']), values: ['line1', 'line2'],
}, },
{ {
name: 'labels', name: 'labels',
type: FieldType.other, type: FieldType.other,
config: {}, config: {},
values: new ArrayVector([ values: [
{ level: 'info', code: '41🌙' }, { level: 'info', code: '41🌙' },
{ level: 'error', code: '41🌙' }, { level: 'error', code: '41🌙' },
]), ],
}, },
{ {
name: 'tsNs', name: 'tsNs',
type: FieldType.string, type: FieldType.string,
config: {}, config: {},
values: new ArrayVector(['1645030244810757120', '1645030247027735040']), values: ['1645030244810757120', '1645030247027735040'],
}, },
{ {
name: 'id', name: 'id',
type: FieldType.string, type: FieldType.string,
config: {}, config: {},
values: new ArrayVector(['id1', 'id2']), values: ['id1', 'id2'],
}, },
], ],
length: 5, length: 5,
@ -132,13 +132,13 @@ describe('loki backendResultTransformer', () => {
{ {
name: 'time', name: 'time',
config: {}, config: {},
values: new ArrayVector([1]), values: [1],
type: FieldType.time, type: FieldType.time,
}, },
{ {
name: 'line', name: 'line',
config: {}, config: {},
values: new ArrayVector(['line1']), values: ['line1'],
type: FieldType.string, type: FieldType.string,
}, },
], ],
@ -167,10 +167,10 @@ describe('loki backendResultTransformer', () => {
name: 'labels', name: 'labels',
type: FieldType.string, type: FieldType.string,
config: {}, config: {},
values: new ArrayVector([ values: [
{ level: 'info', code: '41🌙', __error__: 'LogfmtParserErr' }, { level: 'info', code: '41🌙', __error__: 'LogfmtParserErr' },
{ level: 'error', code: '41🌙' }, { level: 'error', code: '41🌙' },
]), ],
}; };
const response: DataQueryResponse = { data: [clonedFrame] }; const response: DataQueryResponse = { data: [clonedFrame] };

View File

@ -2,7 +2,7 @@ import { css } from '@emotion/css';
import cx from 'classnames'; import cx from 'classnames';
import React, { ReactNode, useState } from 'react'; import React, { ReactNode, useState } from 'react';
import { ArrayVector, Field, FieldType, LinkModel } from '@grafana/data'; import { Field, FieldType, LinkModel } from '@grafana/data';
import { LegacyForms } from '@grafana/ui'; import { LegacyForms } from '@grafana/ui';
import { getFieldLinksForExplore } from '../../../../features/explore/utils/links'; import { getFieldLinksForExplore } from '../../../../features/explore/utils/links';
@ -102,7 +102,7 @@ function makeDebugFields(derivedFields: DerivedFieldConfig[], debugText: string)
field: { field: {
name: '', name: '',
type: FieldType.string, type: FieldType.string,
values: new ArrayVector([value]), values: [value],
config: { config: {
links: [{ title: '', url: field.url }], links: [{ title: '', url: field.url }],
}, },

View File

@ -5,7 +5,6 @@ import { getQueryOptions } from 'test/helpers/getQueryOptions';
import { import {
AbstractLabelOperator, AbstractLabelOperator,
AnnotationQueryRequest, AnnotationQueryRequest,
ArrayVector,
CoreApp, CoreApp,
DataFrame, DataFrame,
dataFrameToJSON, dataFrameToJSON,
@ -57,19 +56,19 @@ const testFrame: DataFrame = {
name: 'Time', name: 'Time',
type: FieldType.time, type: FieldType.time,
config: {}, config: {},
values: new ArrayVector([1, 2]), values: [1, 2],
}, },
{ {
name: 'Line', name: 'Line',
type: FieldType.string, type: FieldType.string,
config: {}, config: {},
values: new ArrayVector(['line1', 'line2']), values: ['line1', 'line2'],
}, },
{ {
name: 'labels', name: 'labels',
type: FieldType.other, type: FieldType.other,
config: {}, config: {},
values: new ArrayVector([ values: [
{ {
label: 'value', label: 'value',
label2: 'value ', label2: 'value ',
@ -79,19 +78,19 @@ const testFrame: DataFrame = {
label2: 'value2', label2: 'value2',
label3: ' ', label3: ' ',
}, },
]), ],
}, },
{ {
name: 'tsNs', name: 'tsNs',
type: FieldType.string, type: FieldType.string,
config: {}, config: {},
values: new ArrayVector(['1000000', '2000000']), values: ['1000000', '2000000'],
}, },
{ {
name: 'id', name: 'id',
type: FieldType.string, type: FieldType.string,
config: {}, config: {},
values: new ArrayVector(['id1', 'id2']), values: ['id1', 'id2'],
}, },
], ],
length: 2, length: 2,
@ -400,19 +399,19 @@ describe('LokiDatasource', () => {
name: 'Time', name: 'Time',
type: FieldType.time, type: FieldType.time,
config: {}, config: {},
values: new ArrayVector([1, 2]), values: [1, 2],
}, },
{ {
name: 'Line', name: 'Line',
type: FieldType.string, type: FieldType.string,
config: {}, config: {},
values: new ArrayVector(['hello', 'hello 2']), values: ['hello', 'hello 2'],
}, },
{ {
name: 'labels', name: 'labels',
type: FieldType.other, type: FieldType.other,
config: {}, config: {},
values: new ArrayVector([ values: [
{ {
label: 'value', label: 'value',
label2: 'value ', label2: 'value ',
@ -422,19 +421,19 @@ describe('LokiDatasource', () => {
label2: 'value2', label2: 'value2',
label3: ' ', label3: ' ',
}, },
]), ],
}, },
{ {
name: 'tsNs', name: 'tsNs',
type: FieldType.string, type: FieldType.string,
config: {}, config: {},
values: new ArrayVector(['1000000', '2000000']), values: ['1000000', '2000000'],
}, },
{ {
name: 'id', name: 'id',
type: FieldType.string, type: FieldType.string,
config: {}, config: {},
values: new ArrayVector(['id1', 'id2']), values: ['id1', 'id2'],
}, },
], ],
length: 2, length: 2,
@ -457,37 +456,37 @@ describe('LokiDatasource', () => {
name: 'Time', name: 'Time',
type: FieldType.time, type: FieldType.time,
config: {}, config: {},
values: new ArrayVector([1]), values: [1],
}, },
{ {
name: 'Line', name: 'Line',
type: FieldType.string, type: FieldType.string,
config: {}, config: {},
values: new ArrayVector(['hello']), values: ['hello'],
}, },
{ {
name: 'labels', name: 'labels',
type: FieldType.other, type: FieldType.other,
config: {}, config: {},
values: new ArrayVector([ values: [
{ {
label: 'value', label: 'value',
label2: 'value2', label2: 'value2',
label3: 'value3', label3: 'value3',
}, },
]), ],
}, },
{ {
name: 'tsNs', name: 'tsNs',
type: FieldType.string, type: FieldType.string,
config: {}, config: {},
values: new ArrayVector(['1000000']), values: ['1000000'],
}, },
{ {
name: 'id', name: 'id',
type: FieldType.string, type: FieldType.string,
config: {}, config: {},
values: new ArrayVector(['id1']), values: ['id1'],
}, },
], ],
length: 1, length: 1,

View File

@ -39,14 +39,14 @@ describe('getDerivedFields', () => {
]); ]);
expect(newFields.length).toBe(2); expect(newFields.length).toBe(2);
const trace1 = newFields.find((f) => f.name === 'trace1'); const trace1 = newFields.find((f) => f.name === 'trace1');
expect(trace1!.values.toArray()).toEqual([null, '1234', null]); expect(trace1!.values).toEqual([null, '1234', null]);
expect(trace1!.config.links![0]).toEqual({ expect(trace1!.config.links![0]).toEqual({
url: 'http://localhost/${__value.raw}', url: 'http://localhost/${__value.raw}',
title: '', title: '',
}); });
const trace2 = newFields.find((f) => f.name === 'trace2'); const trace2 = newFields.find((f) => f.name === 'trace2');
expect(trace2!.values.toArray()).toEqual([null, null, 'foo']); expect(trace2!.values).toEqual([null, null, 'foo']);
expect(trace2!.config.links!.length).toBe(2); expect(trace2!.config.links!.length).toBe(2);
expect(trace2!.config.links![0]).toEqual({ expect(trace2!.config.links![0]).toEqual({
title: '', title: '',

View File

@ -1,6 +1,6 @@
import { groupBy } from 'lodash'; import { groupBy } from 'lodash';
import { FieldType, DataFrame, ArrayVector, DataLink, Field } from '@grafana/data'; import { FieldType, DataFrame, DataLink, Field } from '@grafana/data';
import { getDataSourceSrv } from '@grafana/runtime'; import { getDataSourceSrv } from '@grafana/runtime';
import { DerivedFieldConfig } from './types'; import { DerivedFieldConfig } from './types';
@ -22,7 +22,7 @@ export function getDerivedFields(dataFrame: DataFrame, derivedFieldConfigs: Deri
throw new Error('invalid logs-dataframe, string-field missing'); throw new Error('invalid logs-dataframe, string-field missing');
} }
lineField.values.toArray().forEach((line) => { lineField.values.forEach((line) => {
for (const field of newFields) { for (const field of newFields) {
const logMatch = line.match(derivedFieldsGrouped[field.name][0].matcherRegex); const logMatch = line.match(derivedFieldsGrouped[field.name][0].matcherRegex);
field.values.add(logMatch && logMatch[1]); field.values.add(logMatch && logMatch[1]);
@ -35,7 +35,7 @@ export function getDerivedFields(dataFrame: DataFrame, derivedFieldConfigs: Deri
/** /**
* Transform derivedField config into dataframe field with config that contains link. * Transform derivedField config into dataframe field with config that contains link.
*/ */
function fieldFromDerivedFieldConfig(derivedFieldConfigs: DerivedFieldConfig[]): Field<any, ArrayVector> { function fieldFromDerivedFieldConfig(derivedFieldConfigs: DerivedFieldConfig[]): Field {
const dataSourceSrv = getDataSourceSrv(); const dataSourceSrv = getDataSourceSrv();
const dataLinks = derivedFieldConfigs.reduce<DataLink[]>((acc, derivedFieldConfig) => { const dataLinks = derivedFieldConfigs.reduce<DataLink[]>((acc, derivedFieldConfig) => {
@ -72,6 +72,6 @@ function fieldFromDerivedFieldConfig(derivedFieldConfigs: DerivedFieldConfig[]):
links: dataLinks, links: dataLinks,
}, },
// We are adding values later on // We are adding values later on
values: new ArrayVector<string>([]), values: [],
}; };
} }

View File

@ -1,4 +1,4 @@
import { ArrayVector, DataFrame, FieldType } from '@grafana/data'; import { DataFrame, FieldType } from '@grafana/data';
import { makeTableFrames } from './makeTableFrames'; import { makeTableFrames } from './makeTableFrames';
@ -13,7 +13,7 @@ const frame1: DataFrame = {
name: 'Time', name: 'Time',
type: FieldType.time, type: FieldType.time,
config: {}, config: {},
values: new ArrayVector([1645029699311]), values: [1645029699311],
}, },
{ {
name: 'Value', name: 'Value',
@ -26,7 +26,7 @@ const frame1: DataFrame = {
config: { config: {
displayNameFromDS: '{level="error", location="moon", protocol="http"}', displayNameFromDS: '{level="error", location="moon", protocol="http"}',
}, },
values: new ArrayVector([23]), values: [23],
}, },
], ],
length: 1, length: 1,
@ -43,7 +43,7 @@ const frame2: DataFrame = {
name: 'Time', name: 'Time',
type: FieldType.time, type: FieldType.time,
config: {}, config: {},
values: new ArrayVector([1645029699311]), values: [1645029699311],
}, },
{ {
name: 'Value', name: 'Value',
@ -56,7 +56,7 @@ const frame2: DataFrame = {
config: { config: {
displayNameFromDS: '{level="info", location="moon", protocol="http"}', displayNameFromDS: '{level="info", location="moon", protocol="http"}',
}, },
values: new ArrayVector([45]), values: [45],
}, },
], ],
length: 1, length: 1,
@ -73,7 +73,7 @@ const frame3: DataFrame = {
name: 'Time', name: 'Time',
type: FieldType.time, type: FieldType.time,
config: {}, config: {},
values: new ArrayVector([1645029699311]), values: [1645029699311],
}, },
{ {
name: 'Value', name: 'Value',
@ -86,7 +86,7 @@ const frame3: DataFrame = {
config: { config: {
displayNameFromDS: '{level="error", location="moon", protocol="http"}', displayNameFromDS: '{level="error", location="moon", protocol="http"}',
}, },
values: new ArrayVector([72]), values: [72],
}, },
], ],
length: 1, length: 1,
@ -95,11 +95,11 @@ const frame3: DataFrame = {
const outputSingle = [ const outputSingle = [
{ {
fields: [ fields: [
{ config: {}, name: 'Time', type: 'time', values: new ArrayVector([1645029699311]) }, { config: {}, name: 'Time', type: 'time', values: [1645029699311] },
{ config: { filterable: true }, name: 'level', type: 'string', values: new ArrayVector(['error']) }, { config: { filterable: true }, name: 'level', type: 'string', values: ['error'] },
{ config: { filterable: true }, name: 'location', type: 'string', values: new ArrayVector(['moon']) }, { config: { filterable: true }, name: 'location', type: 'string', values: ['moon'] },
{ config: { filterable: true }, name: 'protocol', type: 'string', values: new ArrayVector(['http']) }, { config: { filterable: true }, name: 'protocol', type: 'string', values: ['http'] },
{ config: {}, name: 'Value #A', type: 'number', values: new ArrayVector([23]) }, { config: {}, name: 'Value #A', type: 'number', values: [23] },
], ],
length: 1, length: 1,
meta: { preferredVisualisationType: 'table' }, meta: { preferredVisualisationType: 'table' },
@ -110,11 +110,11 @@ const outputSingle = [
const outputMulti = [ const outputMulti = [
{ {
fields: [ fields: [
{ config: {}, name: 'Time', type: 'time', values: new ArrayVector([1645029699311, 1645029699311]) }, { config: {}, name: 'Time', type: 'time', values: [1645029699311, 1645029699311] },
{ config: { filterable: true }, name: 'level', type: 'string', values: new ArrayVector(['error', 'info']) }, { config: { filterable: true }, name: 'level', type: 'string', values: ['error', 'info'] },
{ config: { filterable: true }, name: 'location', type: 'string', values: new ArrayVector(['moon', 'moon']) }, { config: { filterable: true }, name: 'location', type: 'string', values: ['moon', 'moon'] },
{ config: { filterable: true }, name: 'protocol', type: 'string', values: new ArrayVector(['http', 'http']) }, { config: { filterable: true }, name: 'protocol', type: 'string', values: ['http', 'http'] },
{ config: {}, name: 'Value #A', type: 'number', values: new ArrayVector([23, 45]) }, { config: {}, name: 'Value #A', type: 'number', values: [23, 45] },
], ],
length: 2, length: 2,
meta: { preferredVisualisationType: 'table' }, meta: { preferredVisualisationType: 'table' },
@ -122,11 +122,11 @@ const outputMulti = [
}, },
{ {
fields: [ fields: [
{ config: {}, name: 'Time', type: 'time', values: new ArrayVector([1645029699311]) }, { config: {}, name: 'Time', type: 'time', values: [1645029699311] },
{ config: { filterable: true }, name: 'level', type: 'string', values: new ArrayVector(['error']) }, { config: { filterable: true }, name: 'level', type: 'string', values: ['error'] },
{ config: { filterable: true }, name: 'location', type: 'string', values: new ArrayVector(['moon']) }, { config: { filterable: true }, name: 'location', type: 'string', values: ['moon'] },
{ config: { filterable: true }, name: 'protocol', type: 'string', values: new ArrayVector(['http']) }, { config: { filterable: true }, name: 'protocol', type: 'string', values: ['http'] },
{ config: {}, name: 'Value #B', type: 'number', values: new ArrayVector([72]) }, { config: {}, name: 'Value #B', type: 'number', values: [72] },
], ],
length: 1, length: 1,
meta: { preferredVisualisationType: 'table' }, meta: { preferredVisualisationType: 'table' },

View File

@ -1,6 +1,6 @@
import { groupBy } from 'lodash'; import { groupBy } from 'lodash';
import { DataFrame, Field, FieldType, ArrayVector } from '@grafana/data'; import { DataFrame, Field, FieldType } from '@grafana/data';
export function makeTableFrames(instantMetricFrames: DataFrame[]): DataFrame[] { export function makeTableFrames(instantMetricFrames: DataFrame[]): DataFrame[] {
// first we remove frames that have no refId // first we remove frames that have no refId
@ -12,15 +12,15 @@ export function makeTableFrames(instantMetricFrames: DataFrame[]): DataFrame[] {
return Object.entries(framesByRefId).map(([refId, frames]) => makeTableFrame(frames, refId)); return Object.entries(framesByRefId).map(([refId, frames]) => makeTableFrame(frames, refId));
} }
type NumberField = Field<number, ArrayVector<number>>; type NumberField = Field<number, number[]>;
type StringField = Field<string, ArrayVector<string>>; type StringField = Field<string, string[]>;
function makeTableFrame(instantMetricFrames: DataFrame[], refId: string): DataFrame { function makeTableFrame(instantMetricFrames: DataFrame[], refId: string): DataFrame {
const tableTimeField: NumberField = { name: 'Time', config: {}, values: new ArrayVector(), type: FieldType.time }; const tableTimeField: NumberField = { name: 'Time', config: {}, values: [], type: FieldType.time };
const tableValueField: NumberField = { const tableValueField: NumberField = {
name: `Value #${refId}`, name: `Value #${refId}`,
config: {}, config: {},
values: new ArrayVector(), values: [],
type: FieldType.number, type: FieldType.number,
}; };
@ -34,7 +34,7 @@ function makeTableFrame(instantMetricFrames: DataFrame[], refId: string): DataFr
const labelFields: StringField[] = sortedLabelNames.map((labelName) => ({ const labelFields: StringField[] = sortedLabelNames.map((labelName) => ({
name: labelName, name: labelName,
config: { filterable: true }, config: { filterable: true },
values: new ArrayVector(), values: [],
type: FieldType.string, type: FieldType.string,
})); }));
@ -45,15 +45,15 @@ function makeTableFrame(instantMetricFrames: DataFrame[], refId: string): DataFr
return; return;
} }
const timeArray = timeField.values.toArray(); const timeArray = timeField.values;
const valueArray = valueField.values.toArray(); const valueArray = valueField.values;
for (let x of timeArray) { for (let x of timeArray) {
tableTimeField.values.add(x); tableTimeField.values.push(x);
} }
for (let x of valueArray) { for (let x of valueArray) {
tableValueField.values.add(x); tableValueField.values.push(x);
} }
const labels = valueField.labels ?? {}; const labels = valueField.labels ?? {};
@ -62,7 +62,7 @@ function makeTableFrame(instantMetricFrames: DataFrame[], refId: string): DataFr
const text = labels[f.name] ?? ''; const text = labels[f.name] ?? '';
// we insert the labels as many times as we have values // we insert the labels as many times as we have values
for (let i = 0; i < valueArray.length; i++) { for (let i = 0; i < valueArray.length; i++) {
f.values.add(text); f.values.push(text);
} }
} }
}); });

View File

@ -1,5 +1,4 @@
import { import {
ArrayVector,
DataFrame, DataFrame,
DataFrameType, DataFrameType,
DataSourceInstanceSettings, DataSourceInstanceSettings,
@ -117,38 +116,38 @@ export function getMockFrames() {
name: 'Time', name: 'Time',
type: FieldType.time, type: FieldType.time,
config: {}, config: {},
values: new ArrayVector([3, 4]), values: [3, 4],
}, },
{ {
name: 'Line', name: 'Line',
type: FieldType.string, type: FieldType.string,
config: {}, config: {},
values: new ArrayVector(['line1', 'line2']), values: ['line1', 'line2'],
}, },
{ {
name: 'labels', name: 'labels',
type: FieldType.other, type: FieldType.other,
config: {}, config: {},
values: new ArrayVector([ values: [
{ {
label: 'value', label: 'value',
}, },
{ {
otherLabel: 'other value', otherLabel: 'other value',
}, },
]), ],
}, },
{ {
name: 'tsNs', name: 'tsNs',
type: FieldType.string, type: FieldType.string,
config: {}, config: {},
values: new ArrayVector(['3000000', '4000000']), values: ['3000000', '4000000'],
}, },
{ {
name: 'id', name: 'id',
type: FieldType.string, type: FieldType.string,
config: {}, config: {},
values: new ArrayVector(['id1', 'id2']), values: ['id1', 'id2'],
}, },
], ],
meta: { meta: {
@ -170,35 +169,35 @@ export function getMockFrames() {
name: 'Time', name: 'Time',
type: FieldType.time, type: FieldType.time,
config: {}, config: {},
values: new ArrayVector([1, 2]), values: [1, 2],
}, },
{ {
name: 'Line', name: 'Line',
type: FieldType.string, type: FieldType.string,
config: {}, config: {},
values: new ArrayVector(['line3', 'line4']), values: ['line3', 'line4'],
}, },
{ {
name: 'labels', name: 'labels',
type: FieldType.other, type: FieldType.other,
config: {}, config: {},
values: new ArrayVector([ values: [
{ {
otherLabel: 'other value', otherLabel: 'other value',
}, },
]), ],
}, },
{ {
name: 'tsNs', name: 'tsNs',
type: FieldType.string, type: FieldType.string,
config: {}, config: {},
values: new ArrayVector(['1000000', '2000000']), values: ['1000000', '2000000'],
}, },
{ {
name: 'id', name: 'id',
type: FieldType.string, type: FieldType.string,
config: {}, config: {},
values: new ArrayVector(['id3', 'id4']), values: ['id3', 'id4'],
}, },
], ],
meta: { meta: {
@ -220,13 +219,13 @@ export function getMockFrames() {
name: 'Time', name: 'Time',
type: FieldType.time, type: FieldType.time,
config: {}, config: {},
values: new ArrayVector([3000000, 4000000]), values: [3000000, 4000000],
}, },
{ {
name: 'Value', name: 'Value',
type: FieldType.number, type: FieldType.number,
config: {}, config: {},
values: new ArrayVector([5, 4]), values: [5, 4],
labels: { labels: {
level: 'debug', level: 'debug',
}, },
@ -249,13 +248,13 @@ export function getMockFrames() {
name: 'Time', name: 'Time',
type: FieldType.time, type: FieldType.time,
config: {}, config: {},
values: new ArrayVector([1000000, 2000000]), values: [1000000, 2000000],
}, },
{ {
name: 'Value', name: 'Value',
type: FieldType.number, type: FieldType.number,
config: {}, config: {},
values: new ArrayVector([6, 7]), values: [6, 7],
labels: { labels: {
level: 'debug', level: 'debug',
}, },
@ -279,13 +278,13 @@ export function getMockFrames() {
name: 'Time', name: 'Time',
type: FieldType.time, type: FieldType.time,
config: {}, config: {},
values: new ArrayVector([3000000, 4000000]), values: [3000000, 4000000],
}, },
{ {
name: 'Value', name: 'Value',
type: FieldType.number, type: FieldType.number,
config: {}, config: {},
values: new ArrayVector([6, 7]), values: [6, 7],
labels: { labels: {
level: 'error', level: 'error',
}, },

View File

@ -1,4 +1,4 @@
import { ArrayVector, DataFrame, FieldType } from '@grafana/data'; import { DataFrame, FieldType } from '@grafana/data';
import { getQueryHints } from './queryHints'; import { getQueryHints } from './queryHints';
@ -12,7 +12,7 @@ describe('getQueryHints', () => {
name: 'Line', name: 'Line',
type: FieldType.string, type: FieldType.string,
config: {}, config: {},
values: new ArrayVector(['{"foo": "bar", "bar": "baz"}', '{"foo": "bar", "bar": "baz"}']), values: ['{"foo": "bar", "bar": "baz"}', '{"foo": "bar", "bar": "baz"}'],
}, },
], ],
}; };
@ -39,7 +39,7 @@ describe('getQueryHints', () => {
name: 'Line', name: 'Line',
type: FieldType.string, type: FieldType.string,
config: {}, config: {},
values: new ArrayVector(['foo="bar" bar="baz"', 'foo="bar" bar="baz"']), values: ['foo="bar" bar="baz"', 'foo="bar" bar="baz"'],
}, },
], ],
}; };
@ -66,7 +66,7 @@ describe('getQueryHints', () => {
name: 'Line', name: 'Line',
type: FieldType.string, type: FieldType.string,
config: {}, config: {},
values: new ArrayVector(['{"foo": "bar", "bar": "baz"}', 'foo="bar" bar="baz"']), values: ['{"foo": "bar", "bar": "baz"}', 'foo="bar" bar="baz"'],
}, },
], ],
}; };
@ -99,7 +99,7 @@ describe('getQueryHints', () => {
name: 'Line', name: 'Line',
type: FieldType.string, type: FieldType.string,
config: {}, config: {},
values: new ArrayVector(['{"_entry": "bar", "bar": "baz"}']), values: ['{"_entry": "bar", "bar": "baz"}'],
}, },
], ],
}; };
@ -139,13 +139,13 @@ describe('getQueryHints', () => {
name: 'Line', name: 'Line',
type: FieldType.string, type: FieldType.string,
config: {}, config: {},
values: new ArrayVector(['{"foo": "bar", "bar": "baz"}', 'foo="bar" bar="baz"']), values: ['{"foo": "bar", "bar": "baz"}', 'foo="bar" bar="baz"'],
}, },
{ {
name: 'labels', name: 'labels',
type: FieldType.other, type: FieldType.other,
config: {}, config: {},
values: new ArrayVector([labelVariable, { job: 'baz', foo: 'bar' }]), values: [labelVariable, { job: 'baz', foo: 'bar' }],
}, },
], ],
}; };
@ -172,7 +172,7 @@ describe('getQueryHints', () => {
name: 'Line', name: 'Line',
type: FieldType.string, type: FieldType.string,
config: {}, config: {},
values: new ArrayVector(['{"foo": "bar", "bar": "baz"}', 'foo="bar" bar="baz"']), values: ['{"foo": "bar", "bar": "baz"}', 'foo="bar" bar="baz"'],
}, },
], ],
}; };
@ -199,7 +199,7 @@ describe('getQueryHints', () => {
name: 'Line', name: 'Line',
type: FieldType.string, type: FieldType.string,
config: {}, config: {},
values: new ArrayVector(['{"foo": "bar", "bar": "baz"}', 'foo="bar" bar="baz"']), values: ['{"foo": "bar", "bar": "baz"}', 'foo="bar" bar="baz"'],
}, },
], ],
}; };
@ -226,7 +226,7 @@ describe('getQueryHints', () => {
name: 'labels', name: 'labels',
type: FieldType.other, type: FieldType.other,
config: {}, config: {},
values: new ArrayVector([{ __error__: 'some error', job: 'a' }]), values: [{ __error__: 'some error', job: 'a' }],
}, },
], ],
}; };

View File

@ -1,6 +1,6 @@
import { cloneDeep } from 'lodash'; import { cloneDeep } from 'lodash';
import { ArrayVector, DataQueryResponse, QueryResultMetaStat, DataFrame, FieldType } from '@grafana/data'; import { DataQueryResponse, QueryResultMetaStat, DataFrame, FieldType } from '@grafana/data';
import { getMockFrames } from './mocks'; import { getMockFrames } from './mocks';
import { import {
@ -21,19 +21,19 @@ const frame: DataFrame = {
name: 'Time', name: 'Time',
config: {}, config: {},
type: FieldType.time, type: FieldType.time,
values: new ArrayVector([1]), values: [1],
}, },
{ {
name: 'labels', name: 'labels',
config: {}, config: {},
type: FieldType.other, type: FieldType.other,
values: new ArrayVector([{ level: 'info' }]), values: [{ level: 'info' }],
}, },
{ {
name: 'Line', name: 'Line',
config: {}, config: {},
type: FieldType.string, type: FieldType.string,
values: new ArrayVector(['line1']), values: ['line1'],
}, },
], ],
}; };
@ -41,7 +41,7 @@ const frame: DataFrame = {
describe('dataFrameHasParsingError', () => { describe('dataFrameHasParsingError', () => {
it('handles frame with parsing error', () => { it('handles frame with parsing error', () => {
const input = cloneDeep(frame); const input = cloneDeep(frame);
input.fields[1].values = new ArrayVector([{ level: 'info', __error__: 'error' }]); input.fields[1].values = [{ level: 'info', __error__: 'error' }];
expect(dataFrameHasLokiError(input)).toBe(true); expect(dataFrameHasLokiError(input)).toBe(true);
}); });
it('handles frame without parsing error', () => { it('handles frame without parsing error', () => {
@ -53,12 +53,12 @@ describe('dataFrameHasParsingError', () => {
describe('dataFrameHasLevelLabel', () => { describe('dataFrameHasLevelLabel', () => {
it('returns true if level label is present', () => { it('returns true if level label is present', () => {
const input = cloneDeep(frame); const input = cloneDeep(frame);
input.fields[1].values = new ArrayVector([{ level: 'info' }]); input.fields[1].values = [{ level: 'info' }];
expect(dataFrameHasLevelLabel(input)).toBe(true); expect(dataFrameHasLevelLabel(input)).toBe(true);
}); });
it('returns false if level label is present', () => { it('returns false if level label is present', () => {
const input = cloneDeep(frame); const input = cloneDeep(frame);
input.fields[1].values = new ArrayVector([{ foo: 'bar' }]); input.fields[1].values = [{ foo: 'bar' }];
expect(dataFrameHasLevelLabel(input)).toBe(false); expect(dataFrameHasLevelLabel(input)).toBe(false);
}); });
}); });
@ -66,17 +66,17 @@ describe('dataFrameHasLevelLabel', () => {
describe('extractLevelLikeLabelFromDataFrame', () => { describe('extractLevelLikeLabelFromDataFrame', () => {
it('returns label if lvl label is present', () => { it('returns label if lvl label is present', () => {
const input = cloneDeep(frame); const input = cloneDeep(frame);
input.fields[1].values = new ArrayVector([{ lvl: 'info' }]); input.fields[1].values = [{ lvl: 'info' }];
expect(extractLevelLikeLabelFromDataFrame(input)).toBe('lvl'); expect(extractLevelLikeLabelFromDataFrame(input)).toBe('lvl');
}); });
it('returns label if level-like label is present', () => { it('returns label if level-like label is present', () => {
const input = cloneDeep(frame); const input = cloneDeep(frame);
input.fields[1].values = new ArrayVector([{ error_level: 'info' }]); input.fields[1].values = [{ error_level: 'info' }];
expect(extractLevelLikeLabelFromDataFrame(input)).toBe('error_level'); expect(extractLevelLikeLabelFromDataFrame(input)).toBe('error_level');
}); });
it('returns undefined if no level-like label is present', () => { it('returns undefined if no level-like label is present', () => {
const input = cloneDeep(frame); const input = cloneDeep(frame);
input.fields[1].values = new ArrayVector([{ foo: 'info' }]); input.fields[1].values = [{ foo: 'info' }];
expect(extractLevelLikeLabelFromDataFrame(input)).toBe(null); expect(extractLevelLikeLabelFromDataFrame(input)).toBe(null);
}); });
}); });
@ -88,12 +88,12 @@ describe('extractLogParserFromDataFrame', () => {
}); });
it('identifies JSON', () => { it('identifies JSON', () => {
const input = cloneDeep(frame); const input = cloneDeep(frame);
input.fields[2].values = new ArrayVector(['{"a":"b"}']); input.fields[2].values = ['{"a":"b"}'];
expect(extractLogParserFromDataFrame(input)).toEqual({ hasJSON: true, hasLogfmt: false, hasPack: false }); expect(extractLogParserFromDataFrame(input)).toEqual({ hasJSON: true, hasLogfmt: false, hasPack: false });
}); });
it('identifies logfmt', () => { it('identifies logfmt', () => {
const input = cloneDeep(frame); const input = cloneDeep(frame);
input.fields[2].values = new ArrayVector(['a=b']); input.fields[2].values = ['a=b'];
expect(extractLogParserFromDataFrame(input)).toEqual({ hasJSON: false, hasLogfmt: true, hasPack: false }); expect(extractLogParserFromDataFrame(input)).toEqual({ hasJSON: false, hasLogfmt: true, hasPack: false });
}); });
}); });
@ -101,7 +101,7 @@ describe('extractLogParserFromDataFrame', () => {
describe('extractLabelKeysFromDataFrame', () => { describe('extractLabelKeysFromDataFrame', () => {
it('returns empty by default', () => { it('returns empty by default', () => {
const input = cloneDeep(frame); const input = cloneDeep(frame);
input.fields[1].values = new ArrayVector([]); input.fields[1].values = [];
expect(extractLabelKeysFromDataFrame(input)).toEqual([]); expect(extractLabelKeysFromDataFrame(input)).toEqual([]);
}); });
it('extracts label keys', () => { it('extracts label keys', () => {
@ -113,12 +113,12 @@ describe('extractLabelKeysFromDataFrame', () => {
describe('extractUnwrapLabelKeysFromDataFrame', () => { describe('extractUnwrapLabelKeysFromDataFrame', () => {
it('returns empty by default', () => { it('returns empty by default', () => {
const input = cloneDeep(frame); const input = cloneDeep(frame);
input.fields[1].values = new ArrayVector([]); input.fields[1].values = [];
expect(extractUnwrapLabelKeysFromDataFrame(input)).toEqual([]); expect(extractUnwrapLabelKeysFromDataFrame(input)).toEqual([]);
}); });
it('extracts possible unwrap label keys', () => { it('extracts possible unwrap label keys', () => {
const input = cloneDeep(frame); const input = cloneDeep(frame);
input.fields[1].values = new ArrayVector([{ number: 13 }]); input.fields[1].values = [{ number: 13 }];
expect(extractUnwrapLabelKeysFromDataFrame(input)).toEqual(['number']); expect(extractUnwrapLabelKeysFromDataFrame(input)).toEqual(['number']);
}); });
}); });
@ -152,19 +152,19 @@ describe('combineResponses', () => {
config: {}, config: {},
name: 'Time', name: 'Time',
type: 'time', type: 'time',
values: new ArrayVector([1, 2, 3, 4]), values: [1, 2, 3, 4],
}, },
{ {
config: {}, config: {},
name: 'Line', name: 'Line',
type: 'string', type: 'string',
values: new ArrayVector(['line3', 'line4', 'line1', 'line2']), values: ['line3', 'line4', 'line1', 'line2'],
}, },
{ {
config: {}, config: {},
name: 'labels', name: 'labels',
type: 'other', type: 'other',
values: new ArrayVector([ values: [
{ {
otherLabel: 'other value', otherLabel: 'other value',
}, },
@ -174,19 +174,19 @@ describe('combineResponses', () => {
{ {
otherLabel: 'other value', otherLabel: 'other value',
}, },
]), ],
}, },
{ {
config: {}, config: {},
name: 'tsNs', name: 'tsNs',
type: 'string', type: 'string',
values: new ArrayVector(['1000000', '2000000', '3000000', '4000000']), values: ['1000000', '2000000', '3000000', '4000000'],
}, },
{ {
config: {}, config: {},
name: 'id', name: 'id',
type: 'string', type: 'string',
values: new ArrayVector(['id3', 'id4', 'id1', 'id2']), values: ['id3', 'id4', 'id1', 'id2'],
}, },
], ],
length: 4, length: 4,
@ -224,13 +224,13 @@ describe('combineResponses', () => {
config: {}, config: {},
name: 'Time', name: 'Time',
type: 'time', type: 'time',
values: new ArrayVector([1000000, 2000000, 3000000, 4000000]), values: [1000000, 2000000, 3000000, 4000000],
}, },
{ {
config: {}, config: {},
name: 'Value', name: 'Value',
type: 'number', type: 'number',
values: new ArrayVector([6, 7, 5, 4]), values: [6, 7, 5, 4],
labels: { labels: {
level: 'debug', level: 'debug',
}, },
@ -269,13 +269,13 @@ describe('combineResponses', () => {
config: {}, config: {},
name: 'Time', name: 'Time',
type: 'time', type: 'time',
values: new ArrayVector([1000000, 2000000, 3000000, 4000000]), values: [1000000, 2000000, 3000000, 4000000],
}, },
{ {
config: {}, config: {},
name: 'Value', name: 'Value',
type: 'number', type: 'number',
values: new ArrayVector([6, 7, 5, 4]), values: [6, 7, 5, 4],
labels: { labels: {
level: 'debug', level: 'debug',
}, },

View File

@ -1,5 +1,4 @@
import { import {
ArrayVector,
DataFrame, DataFrame,
DataFrameType, DataFrameType,
DataQueryResponse, DataQueryResponse,
@ -16,12 +15,12 @@ import { isBytesString } from './languageUtils';
import { isLogLineJSON, isLogLineLogfmt, isLogLinePacked } from './lineParser'; import { isLogLineJSON, isLogLineLogfmt, isLogLinePacked } from './lineParser';
export function dataFrameHasLokiError(frame: DataFrame): boolean { export function dataFrameHasLokiError(frame: DataFrame): boolean {
const labelSets: Labels[] = frame.fields.find((f) => f.name === 'labels')?.values.toArray() ?? []; const labelSets: Labels[] = frame.fields.find((f) => f.name === 'labels')?.values ?? [];
return labelSets.some((labels) => labels.__error__ !== undefined); return labelSets.some((labels) => labels.__error__ !== undefined);
} }
export function dataFrameHasLevelLabel(frame: DataFrame): boolean { export function dataFrameHasLevelLabel(frame: DataFrame): boolean {
const labelSets: Labels[] = frame.fields.find((f) => f.name === 'labels')?.values.toArray() ?? []; const labelSets: Labels[] = frame.fields.find((f) => f.name === 'labels')?.values ?? [];
return labelSets.some((labels) => labels.level !== undefined); return labelSets.some((labels) => labels.level !== undefined);
} }
@ -35,7 +34,7 @@ export function extractLogParserFromDataFrame(frame: DataFrame): {
return { hasJSON: false, hasLogfmt: false, hasPack: false }; return { hasJSON: false, hasLogfmt: false, hasPack: false };
} }
const logLines: string[] = lineField.values.toArray(); const logLines: string[] = lineField.values;
let hasJSON = false; let hasJSON = false;
let hasLogfmt = false; let hasLogfmt = false;
@ -57,7 +56,7 @@ export function extractLogParserFromDataFrame(frame: DataFrame): {
export function extractLabelKeysFromDataFrame(frame: DataFrame): string[] { export function extractLabelKeysFromDataFrame(frame: DataFrame): string[] {
const labelsArray: Array<{ [key: string]: string }> | undefined = const labelsArray: Array<{ [key: string]: string }> | undefined =
frame?.fields?.find((field) => field.name === 'labels')?.values.toArray() ?? []; frame?.fields?.find((field) => field.name === 'labels')?.values ?? [];
if (!labelsArray?.length) { if (!labelsArray?.length) {
return []; return [];
@ -68,7 +67,7 @@ export function extractLabelKeysFromDataFrame(frame: DataFrame): string[] {
export function extractUnwrapLabelKeysFromDataFrame(frame: DataFrame): string[] { export function extractUnwrapLabelKeysFromDataFrame(frame: DataFrame): string[] {
const labelsArray: Array<{ [key: string]: string }> | undefined = const labelsArray: Array<{ [key: string]: string }> | undefined =
frame?.fields?.find((field) => field.name === 'labels')?.values.toArray() ?? []; frame?.fields?.find((field) => field.name === 'labels')?.values ?? [];
if (!labelsArray?.length) { if (!labelsArray?.length) {
return []; return [];
@ -94,7 +93,7 @@ export function extractHasErrorLabelFromDataFrame(frame: DataFrame): boolean {
return false; return false;
} }
const labels: Array<{ [key: string]: string }> = labelField.values.toArray(); const labels: Array<{ [key: string]: string }> = labelField.values;
return labels.some((label) => label['__error__']); return labels.some((label) => label['__error__']);
} }
@ -106,7 +105,7 @@ export function extractLevelLikeLabelFromDataFrame(frame: DataFrame): string | n
// Depending on number of labels, this can be pretty heavy operation. // Depending on number of labels, this can be pretty heavy operation.
// Let's just look at first 2 lines If needed, we can introduce more later. // Let's just look at first 2 lines If needed, we can introduce more later.
const labelsArray: Array<{ [key: string]: string }> = labelField.values.toArray().slice(0, 2); const labelsArray: Array<{ [key: string]: string }> = labelField.values.slice(0, 2);
let levelLikeLabel: string | null = null; let levelLikeLabel: string | null = null;
// Find first level-like label // Find first level-like label
@ -203,9 +202,7 @@ export function combineResponses(currentResult: DataQueryResponse | null, newRes
function combineFrames(dest: DataFrame, source: DataFrame) { function combineFrames(dest: DataFrame, source: DataFrame) {
const totalFields = dest.fields.length; const totalFields = dest.fields.length;
for (let i = 0; i < totalFields; i++) { for (let i = 0; i < totalFields; i++) {
dest.fields[i].values = new ArrayVector( dest.fields[i].values = [].concat.apply(source.fields[i].values, dest.fields[i].values);
[].concat.apply(source.fields[i].values.toArray(), dest.fields[i].values.toArray())
);
} }
dest.length += source.length; dest.length += source.length;
dest.meta = { dest.meta = {
@ -251,9 +248,9 @@ export function cloneQueryResponse(response: DataQueryResponse): DataQueryRespon
function cloneDataFrame(frame: DataQueryResponseData): DataQueryResponseData { function cloneDataFrame(frame: DataQueryResponseData): DataQueryResponseData {
return { return {
...frame, ...frame,
fields: frame.fields.map((field: Field<unknown, ArrayVector>) => ({ fields: frame.fields.map((field: Field) => ({
...field, ...field,
values: new ArrayVector(field.values.toArray()), values: field.values,
})), })),
}; };
} }

View File

@ -1,4 +1,4 @@
import { ArrayVector, DataFrame, FieldType } from '@grafana/data'; import { DataFrame, FieldType } from '@grafana/data';
import { sortDataFrameByTime, SortDirection } from './sortDataFrame'; import { sortDataFrameByTime, SortDirection } from './sortDataFrame';
@ -9,19 +9,19 @@ const inputFrame: DataFrame = {
name: 'time', name: 'time',
type: FieldType.time, type: FieldType.time,
config: {}, config: {},
values: new ArrayVector([1005, 1001, 1004, 1002, 1003]), values: [1005, 1001, 1004, 1002, 1003],
}, },
{ {
name: 'value', name: 'value',
type: FieldType.string, type: FieldType.string,
config: {}, config: {},
values: new ArrayVector(['line5', 'line1', 'line4', 'line2', 'line3']), values: ['line5', 'line1', 'line4', 'line2', 'line3'],
}, },
{ {
name: 'tsNs', name: 'tsNs',
type: FieldType.time, type: FieldType.time,
config: {}, config: {},
values: new ArrayVector([`1005000000`, `1001000000`, `1004000000`, `1002000000`, `1003000000`]), values: [`1005000000`, `1001000000`, `1004000000`, `1002000000`, `1003000000`],
}, },
], ],
length: 5, length: 5,
@ -31,23 +31,23 @@ describe('loki sortDataFrame', () => {
it('sorts a dataframe ascending', () => { it('sorts a dataframe ascending', () => {
const sortedFrame = sortDataFrameByTime(inputFrame, SortDirection.Ascending); const sortedFrame = sortDataFrameByTime(inputFrame, SortDirection.Ascending);
expect(sortedFrame.length).toBe(5); expect(sortedFrame.length).toBe(5);
const timeValues = sortedFrame.fields[0].values.toArray(); const timeValues = sortedFrame.fields[0].values;
const lineValues = sortedFrame.fields[1].values.toArray(); const lineValues = sortedFrame.fields[1].values;
const tsNsValues = sortedFrame.fields[2].values.toArray(); const tsNsValues = sortedFrame.fields[2].values;
expect(timeValues).toStrictEqual([1001, 1002, 1003, 1004, 1005]); expect(timeValues).toEqual([1001, 1002, 1003, 1004, 1005]);
expect(lineValues).toStrictEqual(['line1', 'line2', 'line3', 'line4', 'line5']); expect(lineValues).toEqual(['line1', 'line2', 'line3', 'line4', 'line5']);
expect(tsNsValues).toStrictEqual([`1001000000`, `1002000000`, `1003000000`, `1004000000`, `1005000000`]); expect(tsNsValues).toEqual([`1001000000`, `1002000000`, `1003000000`, `1004000000`, `1005000000`]);
}); });
it('sorts a dataframe descending', () => { it('sorts a dataframe descending', () => {
const sortedFrame = sortDataFrameByTime(inputFrame, SortDirection.Descending); const sortedFrame = sortDataFrameByTime(inputFrame, SortDirection.Descending);
expect(sortedFrame.length).toBe(5); expect(sortedFrame.length).toBe(5);
const timeValues = sortedFrame.fields[0].values.toArray(); const timeValues = sortedFrame.fields[0].values;
const lineValues = sortedFrame.fields[1].values.toArray(); const lineValues = sortedFrame.fields[1].values;
const tsNsValues = sortedFrame.fields[2].values.toArray(); const tsNsValues = sortedFrame.fields[2].values;
expect(timeValues).toStrictEqual([1005, 1004, 1003, 1002, 1001]); expect(timeValues).toEqual([1005, 1004, 1003, 1002, 1001]);
expect(lineValues).toStrictEqual(['line5', 'line4', 'line3', 'line2', 'line1']); expect(lineValues).toEqual(['line5', 'line4', 'line3', 'line2', 'line1']);
expect(tsNsValues).toStrictEqual([`1005000000`, `1004000000`, `1003000000`, `1002000000`, `1001000000`]); expect(tsNsValues).toEqual([`1005000000`, `1004000000`, `1003000000`, `1002000000`, `1001000000`]);
}); });
}); });

View File

@ -16,7 +16,7 @@ export enum SortDirection {
// - the first row will become the second // - the first row will become the second
// - the second row will become the third // - the second row will become the third
function makeIndex(field: Field<string>, dir: SortDirection): number[] { function makeIndex(field: Field<string>, dir: SortDirection): number[] {
const fieldValues: string[] = field.values.toArray(); const fieldValues: string[] = field.values;
// we first build an array which is [0,1,2,3....] // we first build an array which is [0,1,2,3....]
const index = Array(fieldValues.length); const index = Array(fieldValues.length);
@ -65,7 +65,7 @@ export function sortDataFrameByTime(frame: DataFrame, dir: SortDirection): DataF
...rest, ...rest,
fields: fields.map((field) => ({ fields: fields.map((field) => ({
...field, ...field,
values: new SortedVector(field.values, index), values: new SortedVector(field.values, index).toArray(),
})), })),
}; };

View File

@ -23,13 +23,13 @@ export class MssqlDatasource extends SqlDatasource {
async fetchDatasets(): Promise<string[]> { async fetchDatasets(): Promise<string[]> {
const datasets = await this.runSql<{ name: string[] }>(showDatabases(), { refId: 'datasets' }); const datasets = await this.runSql<{ name: string[] }>(showDatabases(), { refId: 'datasets' });
return datasets.fields.name?.values.toArray().flat() ?? []; return datasets.fields.name?.values.flat() ?? [];
} }
async fetchTables(dataset?: string): Promise<string[]> { async fetchTables(dataset?: string): Promise<string[]> {
// We get back the table name with the schema as well. like dbo.table // We get back the table name with the schema as well. like dbo.table
const tables = await this.runSql<{ schemaAndName: string[] }>(getSchemaAndName(dataset), { refId: 'tables' }); const tables = await this.runSql<{ schemaAndName: string[] }>(getSchemaAndName(dataset), { refId: 'tables' });
return tables.fields.schemaAndName?.values.toArray().flat() ?? []; return tables.fields.schemaAndName?.values.flat() ?? [];
} }
async fetchFields(query: SQLQuery): Promise<SQLSelectableValue[]> { async fetchFields(query: SQLQuery): Promise<SQLSelectableValue[]> {
@ -42,8 +42,8 @@ export class MssqlDatasource extends SqlDatasource {
}); });
const result: SQLSelectableValue[] = []; const result: SQLSelectableValue[] = [];
for (let i = 0; i < schema.length; i++) { for (let i = 0; i < schema.length; i++) {
const column = schema.fields.column.values.get(i); const column = schema.fields.column.values[i];
const type = schema.fields.type.values.get(i); const type = schema.fields.type.values[i];
result.push({ label: column, value: column, type, icon: getIcon(type), raqbFieldType: getRAQBType(type) }); result.push({ label: column, value: column, type, icon: getIcon(type), raqbFieldType: getRAQBType(type) });
} }
return result; return result;

View File

@ -24,7 +24,7 @@ export class PostgresDatasource extends SqlDatasource {
async getVersion(): Promise<string> { async getVersion(): Promise<string> {
const value = await this.runSql<{ version: number }>(getVersion()); const value = await this.runSql<{ version: number }>(getVersion());
const results = value.fields.version?.values.toArray(); const results = value.fields.version?.values;
if (!results) { if (!results) {
return ''; return '';
@ -35,7 +35,7 @@ export class PostgresDatasource extends SqlDatasource {
async getTimescaleDBVersion(): Promise<string | undefined> { async getTimescaleDBVersion(): Promise<string | undefined> {
const value = await this.runSql<{ extversion: string }>(getTimescaleDBVersion()); const value = await this.runSql<{ extversion: string }>(getTimescaleDBVersion());
const results = value.fields.extversion?.values.toArray(); const results = value.fields.extversion?.values;
if (!results) { if (!results) {
return undefined; return undefined;
@ -46,7 +46,7 @@ export class PostgresDatasource extends SqlDatasource {
async fetchTables(): Promise<string[]> { async fetchTables(): Promise<string[]> {
const tables = await this.runSql<{ table: string[] }>(showTables(), { refId: 'tables' }); const tables = await this.runSql<{ table: string[] }>(showTables(), { refId: 'tables' });
return tables.fields.table?.values.toArray().flat() ?? []; return tables.fields.table?.values.flat() ?? [];
} }
getSqlLanguageDefinition(db: DB): LanguageDefinition { getSqlLanguageDefinition(db: DB): LanguageDefinition {
@ -70,8 +70,8 @@ export class PostgresDatasource extends SqlDatasource {
const schema = await this.runSql<{ column: string; type: string }>(getSchema(query.table), { refId: 'columns' }); const schema = await this.runSql<{ column: string; type: string }>(getSchema(query.table), { refId: 'columns' });
const result: SQLSelectableValue[] = []; const result: SQLSelectableValue[] = [];
for (let i = 0; i < schema.length; i++) { for (let i = 0; i < schema.length; i++) {
const column = schema.fields.column.values.get(i); const column = schema.fields.column.values[i];
const type = schema.fields.type.values.get(i); const type = schema.fields.type.values[i];
result.push({ label: column, value: column, type, ...getFieldConfig(type) }); result.push({ label: column, value: column, type, ...getFieldConfig(type) });
} }
return result; return result;

View File

@ -396,9 +396,9 @@ describe('PrometheusDatasource', () => {
ds.performTimeSeriesQuery = jest.fn().mockReturnValue(of(responseMock)); ds.performTimeSeriesQuery = jest.fn().mockReturnValue(of(responseMock));
await expect(ds.query(query)).toEmitValuesWith((result) => { await expect(ds.query(query)).toEmitValuesWith((result) => {
const results = result[0].data; const results = result[0].data;
expect(results[0].fields[1].values.toArray()).toEqual([10, 10]); expect(results[0].fields[1].values).toEqual([10, 10]);
expect(results[0].fields[2].values.toArray()).toEqual([10, 0]); expect(results[0].fields[2].values).toEqual([10, 0]);
expect(results[0].fields[3].values.toArray()).toEqual([5, 0]); expect(results[0].fields[3].values).toEqual([5, 0]);
}); });
}); });
@ -1018,27 +1018,27 @@ describe('PrometheusDatasource2', () => {
}); });
it('should fill null until first datapoint in response', () => { it('should fill null until first datapoint in response', () => {
expect(results.data[0].fields[0].values.get(0)).toBe(start * 1000); expect(results.data[0].fields[0].values[0]).toBe(start * 1000);
expect(results.data[0].fields[1].values.get(0)).toBe(null); expect(results.data[0].fields[1].values[0]).toBe(null);
expect(results.data[0].fields[0].values.get(1)).toBe((start + step * 1) * 1000); expect(results.data[0].fields[0].values[1]).toBe((start + step * 1) * 1000);
expect(results.data[0].fields[1].values.get(1)).toBe(3846); expect(results.data[0].fields[1].values[1]).toBe(3846);
}); });
it('should fill null after last datapoint in response', () => { it('should fill null after last datapoint in response', () => {
const length = (end - start) / step + 1; const length = (end - start) / step + 1;
expect(results.data[0].fields[0].values.get(length - 2)).toBe((end - step * 1) * 1000); expect(results.data[0].fields[0].values[length - 2]).toBe((end - step * 1) * 1000);
expect(results.data[0].fields[1].values.get(length - 2)).toBe(3848); expect(results.data[0].fields[1].values[length - 2]).toBe(3848);
expect(results.data[0].fields[0].values.get(length - 1)).toBe(end * 1000); expect(results.data[0].fields[0].values[length - 1]).toBe(end * 1000);
expect(results.data[0].fields[1].values.get(length - 1)).toBe(null); expect(results.data[0].fields[1].values[length - 1]).toBe(null);
}); });
it('should fill null at gap between series', () => { it('should fill null at gap between series', () => {
expect(results.data[0].fields[0].values.get(2)).toBe((start + step * 2) * 1000); expect(results.data[0].fields[0].values[2]).toBe((start + step * 2) * 1000);
expect(results.data[0].fields[1].values.get(2)).toBe(null); expect(results.data[0].fields[1].values[2]).toBe(null);
expect(results.data[1].fields[0].values.get(1)).toBe((start + step * 1) * 1000); expect(results.data[1].fields[0].values[1]).toBe((start + step * 1) * 1000);
expect(results.data[1].fields[1].values.get(1)).toBe(null); expect(results.data[1].fields[1].values[1]).toBe(null);
expect(results.data[1].fields[0].values.get(3)).toBe((start + step * 3) * 1000); expect(results.data[1].fields[0].values[3]).toBe((start + step * 3) * 1000);
expect(results.data[1].fields[1].values.get(3)).toBe(null); expect(results.data[1].fields[1].values[3]).toBe(null);
}); });
}); });

View File

@ -866,10 +866,10 @@ export class PrometheusDatasource
const timeValueTuple: Array<[number, number]> = []; const timeValueTuple: Array<[number, number]> = [];
let idx = 0; let idx = 0;
valueField.values.toArray().forEach((value: string) => { valueField.values.forEach((value: string) => {
let timeStampValue: number; let timeStampValue: number;
let valueValue: number; let valueValue: number;
const time = timeField.values.get(idx); const time = timeField.values[idx];
// If we want to use value as a time, we use value as timeStampValue and valueValue will be 1 // If we want to use value as a time, we use value as timeStampValue and valueValue will be 1
if (options.annotation.useValueForTime) { if (options.annotation.useValueForTime) {

View File

@ -268,7 +268,7 @@ describe('QueryCache', function () {
// All of the new values should be the ones that were stored, this is overkill // All of the new values should be the ones that were stored, this is overkill
secondFrames.forEach((frame, frameIdx) => { secondFrames.forEach((frame, frameIdx) => {
frame.fields.forEach((field, fieldIdx) => { frame.fields.forEach((field, fieldIdx) => {
secondFrames[frameIdx].fields[fieldIdx].values.toArray().forEach((value) => { secondFrames[frameIdx].fields[fieldIdx].values.forEach((value) => {
expect(secondStoredFrames[frameIdx].fields[fieldIdx].values).toContain(value); expect(secondStoredFrames[frameIdx].fields[fieldIdx].values).toContain(value);
}); });
}); });
@ -394,12 +394,8 @@ describe('QueryCache', function () {
// Since the step is 15s, and the request was 30 seconds later, we should have 2 extra frames, but we should evict the first two, so we should get the same length // Since the step is 15s, and the request was 30 seconds later, we should have 2 extra frames, but we should evict the first two, so we should get the same length
expect(firstMergedLength).toEqual(secondMergedLength); expect(firstMergedLength).toEqual(secondMergedLength);
expect(firstQueryResult[0].fields[0].values.toArray()[2]).toEqual( expect(firstQueryResult[0].fields[0].values[2]).toEqual(secondQueryResult[0].fields[0].values[0]);
secondQueryResult[0].fields[0].values.toArray()[0] expect(firstQueryResult[0].fields[0].values[0] + 30000).toEqual(secondQueryResult[0].fields[0].values[0]);
);
expect(firstQueryResult[0].fields[0].values.toArray()[0] + 30000).toEqual(
secondQueryResult[0].fields[0].values.toArray()[0]
);
cache.set(targetIdentity, `'1=1'|${interval}|${JSON.stringify(thirdRange.raw)}`); cache.set(targetIdentity, `'1=1'|${interval}|${JSON.stringify(thirdRange.raw)}`);
@ -418,7 +414,7 @@ describe('QueryCache', function () {
); );
const cachedAfterThird = storage.cache.get(targetIdentity); const cachedAfterThird = storage.cache.get(targetIdentity);
const storageLengthAfterThirdQuery = cachedAfterThird?.frames[0].fields[0].values.toArray().length; const storageLengthAfterThirdQuery = cachedAfterThird?.frames[0].fields[0].values.length;
expect(storageLengthAfterThirdQuery).toEqual(20); expect(storageLengthAfterThirdQuery).toEqual(20);
}); });

View File

@ -1,5 +1,4 @@
import { import {
ArrayVector,
DataFrame, DataFrame,
DataQueryRequest, DataQueryRequest,
dateTime, dateTime,
@ -360,16 +359,15 @@ export class QueryCache {
// amend & re-cache // amend & re-cache
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
let prevTable: Table = cachedFrame.fields.map((field) => field.values.toArray()) as Table; let prevTable: Table = cachedFrame.fields.map((field) => field.values) as Table;
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
let nextTable: Table = respFrame.fields.map((field) => field.values.toArray()) as Table; let nextTable: Table = respFrame.fields.map((field) => field.values) as Table;
let amendedTable = amendTable(prevTable, nextTable); let amendedTable = amendTable(prevTable, nextTable);
if (amendedTable) { if (amendedTable) {
for (let i = 0; i < amendedTable.length; i++) { for (let i = 0; i < amendedTable.length; i++) {
cachedFrame.fields[i].values = new ArrayVector(amendedTable[i]); cachedFrame.fields[i].values = amendedTable[i];
} }
cachedFrame.length = cachedFrame.fields[0].values.length; cachedFrame.length = cachedFrame.fields[0].values.length;
} }
} }
@ -380,13 +378,13 @@ export class QueryCache {
cachedFrames.forEach((frame) => { cachedFrames.forEach((frame) => {
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
let table: Table = frame.fields.map((field) => field.values.toArray()) as Table; let table: Table = frame.fields.map((field) => field.values) as Table;
let trimmed = trimTable(table, newFrom, newTo); let trimmed = trimTable(table, newFrom, newTo);
if (trimmed[0].length > 0) { if (trimmed[0].length > 0) {
for (let i = 0; i < trimmed.length; i++) { for (let i = 0; i < trimmed.length; i++) {
frame.fields[i].values = new ArrayVector(trimmed[i]); frame.fields[i].values = trimmed[i];
} }
nonEmptyCachedFrames.push(frame); nonEmptyCachedFrames.push(frame);
} }
@ -409,7 +407,7 @@ export class QueryCache {
config: { config: {
...field.config, // prevents mutatative exemplars links (re)enrichment ...field.config, // prevents mutatative exemplars links (re)enrichment
}, },
values: new ArrayVector(field.values.toArray().slice()), values: field.values.slice(),
})), })),
})); }));
} }

View File

@ -1,20 +1,18 @@
import { clone } from 'lodash'; import { clone } from 'lodash';
import { ArrayVector } from '@grafana/data/src';
/** /**
* *
* @param length - Number of values to add * @param length - Number of values to add
* @param start - First timestamp (ms) * @param start - First timestamp (ms)
* @param step - step duration (ms) * @param step - step duration (ms)
*/ */
export const getMockTimeFrameArray = (length: number, start: number, step: number): ArrayVector => { export const getMockTimeFrameArray = (length: number, start: number, step: number) => {
let timeValues = []; let timeValues: number[] = [];
for (let i = 0; i < length; i++) { for (let i = 0; i < length; i++) {
timeValues.push(start + i * step); timeValues.push(start + i * step);
} }
return new ArrayVector(timeValues); return timeValues;
}; };
/** /**
@ -22,8 +20,8 @@ export const getMockTimeFrameArray = (length: number, start: number, step: numbe
* @param values * @param values
* @param high * @param high
*/ */
export const getMockValueFrameArray = (length: number, values = 0): ArrayVector => { export const getMockValueFrameArray = (length: number, values = 0): number[] => {
return new ArrayVector(Array(length).fill(values)); return Array(length).fill(values);
}; };
const timeFrameWithMissingValuesInMiddle = getMockTimeFrameArray(721, 1675262550000, 30000); const timeFrameWithMissingValuesInMiddle = getMockTimeFrameArray(721, 1675262550000, 30000);
@ -31,9 +29,9 @@ const timeFrameWithMissingValuesAtStart = getMockTimeFrameArray(721, 16752625500
const timeFrameWithMissingValuesAtEnd = getMockTimeFrameArray(721, 1675262550000, 30000); const timeFrameWithMissingValuesAtEnd = getMockTimeFrameArray(721, 1675262550000, 30000);
// Deleting some out the middle // Deleting some out the middle
timeFrameWithMissingValuesInMiddle.toArray().splice(360, 721 - 684); timeFrameWithMissingValuesInMiddle.splice(360, 721 - 684);
timeFrameWithMissingValuesAtStart.toArray().splice(0, 721 - 684); timeFrameWithMissingValuesAtStart.splice(0, 721 - 684);
timeFrameWithMissingValuesAtEnd.toArray().splice(721 - 684, 721 - 684); timeFrameWithMissingValuesAtEnd.splice(721 - 684, 721 - 684);
const mockLabels = { const mockLabels = {
__name__: 'cortex_request_duration_seconds_bucket', __name__: 'cortex_request_duration_seconds_bucket',

View File

@ -366,9 +366,9 @@ describe('Prometheus Result Transformer', () => {
const series = transformV2(response, options, {}); const series = transformV2(response, options, {});
expect(series.data[0].fields.length).toEqual(4); expect(series.data[0].fields.length).toEqual(4);
expect(series.data[0].fields[1].values.toArray()).toEqual([10, 10, 0]); expect(series.data[0].fields[1].values).toEqual([10, 10, 0]);
expect(series.data[0].fields[2].values.toArray()).toEqual([10, 0, 30]); expect(series.data[0].fields[2].values).toEqual([10, 0, 30]);
expect(series.data[0].fields[3].values.toArray()).toEqual([10, 0, 10]); expect(series.data[0].fields[3].values).toEqual([10, 0, 10]);
expect(series.data[0].fields[1].name).toEqual('1'); expect(series.data[0].fields[1].name).toEqual('1');
expect(series.data[0].fields[2].name).toEqual('2'); expect(series.data[0].fields[2].name).toEqual('2');
expect(series.data[0].fields[3].name).toEqual('+Inf'); expect(series.data[0].fields[3].name).toEqual('+Inf');
@ -467,9 +467,9 @@ describe('Prometheus Result Transformer', () => {
const series = transformV2(response, options, {}); const series = transformV2(response, options, {});
expect(series.data[0].fields.length).toEqual(4); expect(series.data[0].fields.length).toEqual(4);
expect(series.data[0].fields[1].values.toArray()).toEqual([10, 10, 0]); expect(series.data[0].fields[1].values).toEqual([10, 10, 0]);
expect(series.data[0].fields[2].values.toArray()).toEqual([10, 0, 30]); expect(series.data[0].fields[2].values).toEqual([10, 0, 30]);
expect(series.data[0].fields[3].values.toArray()).toEqual([10, 0, 10]); expect(series.data[0].fields[3].values).toEqual([10, 0, 10]);
}); });
it('results with heatmap format and multiple histograms should be grouped and de-accumulated by non-le labels', () => { it('results with heatmap format and multiple histograms should be grouped and de-accumulated by non-le labels', () => {
@ -600,17 +600,17 @@ describe('Prometheus Result Transformer', () => {
const series = transformV2(response, options, {}); const series = transformV2(response, options, {});
expect(series.data[0].fields.length).toEqual(4); expect(series.data[0].fields.length).toEqual(4);
expect(series.data[0].fields[1].values.toArray()).toEqual([10, 10, 0]); expect(series.data[0].fields[1].values).toEqual([10, 10, 0]);
expect(series.data[0].fields[2].values.toArray()).toEqual([10, 0, 30]); expect(series.data[0].fields[2].values).toEqual([10, 0, 30]);
expect(series.data[0].fields[3].values.toArray()).toEqual([10, 0, 10]); expect(series.data[0].fields[3].values).toEqual([10, 0, 10]);
expect(series.data[1].fields[1].values.toArray()).toEqual([0, 10, 10]); expect(series.data[1].fields[1].values).toEqual([0, 10, 10]);
expect(series.data[1].fields[2].values.toArray()).toEqual([20, 0, 30]); expect(series.data[1].fields[2].values).toEqual([20, 0, 30]);
expect(series.data[1].fields[3].values.toArray()).toEqual([10, 0, 20]); expect(series.data[1].fields[3].values).toEqual([10, 0, 20]);
expect(series.data[2].fields[1].values.toArray()).toEqual([30, 30, 60]); expect(series.data[2].fields[1].values).toEqual([30, 30, 60]);
expect(series.data[2].fields[2].values.toArray()).toEqual([0, 10, 0]); expect(series.data[2].fields[2].values).toEqual([0, 10, 0]);
expect(series.data[2].fields[3].values.toArray()).toEqual([10, 0, 0]); expect(series.data[2].fields[3].values).toEqual([10, 0, 0]);
}); });
it('Retains exemplar frames when data returned is a heatmap', () => { it('Retains exemplar frames when data returned is a heatmap', () => {
@ -667,14 +667,7 @@ describe('Prometheus Result Transformer', () => {
const series = transformV2(response, options, {}); const series = transformV2(response, options, {});
expect(series.data[0].fields.length).toEqual(2); expect(series.data[0].fields.length).toEqual(2);
expect(series.data.length).toEqual(2); expect(series.data.length).toEqual(2);
expect(series.data[1].fields[2].values.toArray()).toEqual([ expect(series.data[1].fields[2].values).toEqual(['hello', 'doctor', 'name', 'continue', 'yesterday', 'tomorrow']);
'hello',
'doctor',
'name',
'continue',
'yesterday',
'tomorrow',
]);
expect(series.data[1].fields.length).toEqual(3); expect(series.data[1].fields.length).toEqual(3);
}); });
@ -765,9 +758,9 @@ describe('Prometheus Result Transformer', () => {
expect(tableDf.fields.length).toBe(4); expect(tableDf.fields.length).toBe(4);
expect(tableDf.fields[0].name).toBe('Time'); expect(tableDf.fields[0].name).toBe('Time');
expect(tableDf.fields[1].name).toBe('label1'); expect(tableDf.fields[1].name).toBe('label1');
expect(tableDf.fields[1].values.get(0)).toBe('value1'); expect(tableDf.fields[1].values[0]).toBe('value1');
expect(tableDf.fields[2].name).toBe('label2'); expect(tableDf.fields[2].name).toBe('label2');
expect(tableDf.fields[2].values.get(0)).toBe('value2'); expect(tableDf.fields[2].values[0]).toBe('value2');
expect(tableDf.fields[3].name).toBe('Value'); expect(tableDf.fields[3].name).toBe('Value');
}); });
@ -789,9 +782,9 @@ describe('Prometheus Result Transformer', () => {
expect(tableDf.fields.length).toBe(4); expect(tableDf.fields.length).toBe(4);
expect(tableDf.fields[0].name).toBe('Time'); expect(tableDf.fields[0].name).toBe('Time');
expect(tableDf.fields[1].name).toBe('label1'); expect(tableDf.fields[1].name).toBe('label1');
expect(tableDf.fields[1].values.get(0)).toBe('value1'); expect(tableDf.fields[1].values[0]).toBe('value1');
expect(tableDf.fields[2].name).toBe('label2'); expect(tableDf.fields[2].name).toBe('label2');
expect(tableDf.fields[2].values.get(0)).toBe('value2'); expect(tableDf.fields[2].values[0]).toBe('value2');
expect(tableDf.fields[3].name).toBe('Value'); expect(tableDf.fields[3].name).toBe('Value');
}); });
@ -824,16 +817,16 @@ describe('Prometheus Result Transformer', () => {
expect(transformedTableDataFrames[0].fields.length).toBe(4); expect(transformedTableDataFrames[0].fields.length).toBe(4);
expect(transformedTableDataFrames[0].fields[0].name).toBe('Time'); expect(transformedTableDataFrames[0].fields[0].name).toBe('Time');
expect(transformedTableDataFrames[0].fields[1].name).toBe('label1'); expect(transformedTableDataFrames[0].fields[1].name).toBe('label1');
expect(transformedTableDataFrames[0].fields[1].values.get(0)).toBe(value1); expect(transformedTableDataFrames[0].fields[1].values[0]).toBe(value1);
expect(transformedTableDataFrames[0].fields[2].name).toBe('label2'); expect(transformedTableDataFrames[0].fields[2].name).toBe('label2');
expect(transformedTableDataFrames[0].fields[2].values.get(0)).toBe(value2); expect(transformedTableDataFrames[0].fields[2].values[0]).toBe(value2);
expect(transformedTableDataFrames[0].fields[3].name).toBe('Value #A'); expect(transformedTableDataFrames[0].fields[3].name).toBe('Value #A');
// Expect the invalid/empty results not to throw an error and to return empty arrays // Expect the invalid/empty results not to throw an error and to return empty arrays
expect(transformedTableDataFrames[1].fields[1].labels).toBe(undefined); expect(transformedTableDataFrames[1].fields[1].labels).toBe(undefined);
expect(transformedTableDataFrames[1].fields[1].name).toBe('Value #B'); expect(transformedTableDataFrames[1].fields[1].name).toBe('Value #B');
expect(transformedTableDataFrames[1].fields[1].values.toArray()).toEqual([]); expect(transformedTableDataFrames[1].fields[1].values).toEqual([]);
expect(transformedTableDataFrames[1].fields[0].values.toArray()).toEqual([]); expect(transformedTableDataFrames[1].fields[0].values).toEqual([]);
}); });
}); });
@ -901,22 +894,20 @@ describe('Prometheus Result Transformer', () => {
format: 'table', format: 'table',
}, },
}); });
expect(result[0].fields[0].values.toArray()).toEqual([ expect(result[0].fields[0].values).toEqual([1443454528000, 1443454530000, 1443454529000, 1443454531000]);
1443454528000, 1443454530000, 1443454529000, 1443454531000,
]);
expect(result[0].fields[0].name).toBe('Time'); expect(result[0].fields[0].name).toBe('Time');
expect(result[0].fields[0].type).toBe(FieldType.time); expect(result[0].fields[0].type).toBe(FieldType.time);
expect(result[0].fields[1].values.toArray()).toEqual(['test', 'test', 'test2', 'test2']); expect(result[0].fields[1].values).toEqual(['test', 'test', 'test2', 'test2']);
expect(result[0].fields[1].name).toBe('__name__'); expect(result[0].fields[1].name).toBe('__name__');
expect(result[0].fields[1].config.filterable).toBe(true); expect(result[0].fields[1].config.filterable).toBe(true);
expect(result[0].fields[1].type).toBe(FieldType.string); expect(result[0].fields[1].type).toBe(FieldType.string);
expect(result[0].fields[2].values.toArray()).toEqual(['', '', 'localhost:8080', 'localhost:8080']); expect(result[0].fields[2].values).toEqual(['', '', 'localhost:8080', 'localhost:8080']);
expect(result[0].fields[2].name).toBe('instance'); expect(result[0].fields[2].name).toBe('instance');
expect(result[0].fields[2].type).toBe(FieldType.string); expect(result[0].fields[2].type).toBe(FieldType.string);
expect(result[0].fields[3].values.toArray()).toEqual(['testjob', 'testjob', 'otherjob', 'otherjob']); expect(result[0].fields[3].values).toEqual(['testjob', 'testjob', 'otherjob', 'otherjob']);
expect(result[0].fields[3].name).toBe('job'); expect(result[0].fields[3].name).toBe('job');
expect(result[0].fields[3].type).toBe(FieldType.string); expect(result[0].fields[3].type).toBe(FieldType.string);
expect(result[0].fields[4].values.toArray()).toEqual([3846, 3848, 3847, 3849]); expect(result[0].fields[4].values).toEqual([3846, 3848, 3847, 3849]);
expect(result[0].fields[4].name).toEqual('Value'); expect(result[0].fields[4].name).toEqual('Value');
expect(result[0].fields[4].type).toBe(FieldType.number); expect(result[0].fields[4].type).toBe(FieldType.number);
expect(result[0].refId).toBe('A'); expect(result[0].refId).toBe('A');
@ -952,13 +943,13 @@ describe('Prometheus Result Transformer', () => {
it('should return data frame', () => { it('should return data frame', () => {
const result = transform({ data: response } as any, { ...options, target: { format: 'table' } }); const result = transform({ data: response } as any, { ...options, target: { format: 'table' } });
expect(result[0].fields[0].values.toArray()).toEqual([1443454528000]); expect(result[0].fields[0].values).toEqual([1443454528000]);
expect(result[0].fields[0].name).toBe('Time'); expect(result[0].fields[0].name).toBe('Time');
expect(result[0].fields[1].values.toArray()).toEqual(['test']); expect(result[0].fields[1].values).toEqual(['test']);
expect(result[0].fields[1].name).toBe('__name__'); expect(result[0].fields[1].name).toBe('__name__');
expect(result[0].fields[2].values.toArray()).toEqual(['testjob']); expect(result[0].fields[2].values).toEqual(['testjob']);
expect(result[0].fields[2].name).toBe('job'); expect(result[0].fields[2].name).toBe('job');
expect(result[0].fields[3].values.toArray()).toEqual([3846]); expect(result[0].fields[3].values).toEqual([3846]);
expect(result[0].fields[3].name).toEqual('Value'); expect(result[0].fields[3].name).toEqual('Value');
}); });
@ -976,7 +967,7 @@ describe('Prometheus Result Transformer', () => {
}, },
}; };
const result = transform({ data: response } as any, { ...options, target: { format: 'table' } }); const result = transform({ data: response } as any, { ...options, target: { format: 'table' } });
expect(result[0].fields[1].values.toArray()).toEqual([102]); expect(result[0].fields[1].values).toEqual([102]);
expect(result[0].fields[1].type).toEqual(FieldType.number); expect(result[0].fields[1].type).toEqual(FieldType.number);
}); });
}); });
@ -1046,10 +1037,10 @@ describe('Prometheus Result Transformer', () => {
]); ]);
const result = transform({ data: response } as any, { query: options, target: options } as any); const result = transform({ data: response } as any, { query: options, target: options } as any);
expect(result[0].fields[0].values.toArray()).toEqual([1445000010000, 1445000020000, 1445000030000]); expect(result[0].fields[0].values).toEqual([1445000010000, 1445000020000, 1445000030000]);
expect(result[0].fields[1].values.toArray()).toEqual([10, 10, 0]); expect(result[0].fields[1].values).toEqual([10, 10, 0]);
expect(result[0].fields[2].values.toArray()).toEqual([10, 0, 30]); expect(result[0].fields[2].values).toEqual([10, 0, 30]);
expect(result[0].fields[3].values.toArray()).toEqual([10, 0, 10]); expect(result[0].fields[3].values).toEqual([10, 0, 10]);
}); });
it('should handle missing datapoints', () => { it('should handle missing datapoints', () => {
@ -1078,9 +1069,9 @@ describe('Prometheus Result Transformer', () => {
}, },
]); ]);
const result = transform({ data: response } as any, { query: options, target: options } as any); const result = transform({ data: response } as any, { query: options, target: options } as any);
expect(result[0].fields[1].values.toArray()).toEqual([1, 2]); expect(result[0].fields[1].values).toEqual([1, 2]);
expect(result[0].fields[2].values.toArray()).toEqual([1, 3, 1]); expect(result[0].fields[2].values).toEqual([1, 3, 1]);
expect(result[0].fields[3].values.toArray()).toEqual([1, 2]); expect(result[0].fields[3].values).toEqual([1, 2]);
}); });
}); });
@ -1137,8 +1128,8 @@ describe('Prometheus Result Transformer', () => {
end: 2, end: 2,
}, },
}); });
expect(result[0].fields[0].values.toArray()).toEqual([0, 1000, 2000]); expect(result[0].fields[0].values).toEqual([0, 1000, 2000]);
expect(result[0].fields[1].values.toArray()).toEqual([10, 10, 0]); expect(result[0].fields[1].values).toEqual([10, 10, 0]);
expect(result[0].name).toBe('test{job="testjob"}'); expect(result[0].name).toBe('test{job="testjob"}');
}); });
@ -1148,8 +1139,8 @@ describe('Prometheus Result Transformer', () => {
query: { step: 1, start: 0, end: 2 }, query: { step: 1, start: 0, end: 2 },
}); });
expect(result[0].fields[0].values.toArray()).toEqual([0, 1000, 2000]); expect(result[0].fields[0].values).toEqual([0, 1000, 2000]);
expect(result[0].fields[1].values.toArray()).toEqual([null, 10, 0]); expect(result[0].fields[1].values).toEqual([null, 10, 0]);
}); });
it('should use __name__ label as series name', () => { it('should use __name__ label as series name', () => {
@ -1242,8 +1233,8 @@ describe('Prometheus Result Transformer', () => {
}; };
const result = transform({ data: response } as any, { ...options, query: { step: 2, start: 0, end: 8 } }); const result = transform({ data: response } as any, { ...options, query: { step: 2, start: 0, end: 8 } });
expect(result[0].fields[0].values.toArray()).toEqual([0, 2000, 4000, 6000, 8000]); expect(result[0].fields[0].values).toEqual([0, 2000, 4000, 6000, 8000]);
expect(result[0].fields[1].values.toArray()).toEqual([null, null, 10, null, 10]); expect(result[0].fields[1].values).toEqual([null, null, 10, null, 10]);
}); });
}); });
@ -1262,7 +1253,7 @@ describe('Prometheus Result Transformer', () => {
...options, ...options,
target: { format: 'table' }, target: { format: 'table' },
}); });
expect(result[0].fields[1].values.toArray()).toEqual([Number.POSITIVE_INFINITY]); expect(result[0].fields[1].values).toEqual([Number.POSITIVE_INFINITY]);
}); });
}); });
@ -1290,7 +1281,7 @@ describe('Prometheus Result Transformer', () => {
...options, ...options,
target: { format: 'table' }, target: { format: 'table' },
}); });
expect(result[0].fields[3].values.toArray()).toEqual([Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY]); expect(result[0].fields[3].values).toEqual([Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY]);
}); });
}); });
}); });

View File

@ -3,7 +3,6 @@ import { flatten, forOwn, groupBy, partition } from 'lodash';
import { import {
ArrayDataFrame, ArrayDataFrame,
ArrayVector,
CoreApp, CoreApp,
DataFrame, DataFrame,
DataFrameType, DataFrameType,
@ -226,7 +225,7 @@ export function transformDFToTable(dfs: DataFrame[]): DataFrame[] {
name: label, name: label,
config: { filterable: true }, config: { filterable: true },
type: numberField ? FieldType.number : FieldType.string, type: numberField ? FieldType.number : FieldType.string,
values: new ArrayVector(), values: [],
}); });
} }
}); });
@ -234,10 +233,10 @@ export function transformDFToTable(dfs: DataFrame[]): DataFrame[] {
// Fill valueField, timeField and labelFields with values // Fill valueField, timeField and labelFields with values
dataFramesByRefId[refId].forEach((df) => { dataFramesByRefId[refId].forEach((df) => {
const timeFields = df.fields[0]?.values ?? new ArrayVector(); const timeFields = df.fields[0]?.values ?? [];
const dataFields = df.fields[1]?.values ?? new ArrayVector(); const dataFields = df.fields[1]?.values ?? [];
timeFields.toArray().forEach((value) => timeField.values.add(value)); timeFields.forEach((value) => timeField.values.add(value));
dataFields.toArray().forEach((value) => { dataFields.forEach((value) => {
valueField.values.add(parseSampleValue(value)); valueField.values.add(parseSampleValue(value));
const labelsForField = df.fields[1].labels ?? {}; const labelsForField = df.fields[1].labels ?? {};
labelFields.forEach((field) => field.values.add(getLabelValue(labelsForField, field.name))); labelFields.forEach((field) => field.values.add(getLabelValue(labelsForField, field.name)));
@ -515,12 +514,13 @@ function transformMetricDataToTable(md: MatrixOrVectorResult[], options: Transfo
// Labels have string field type, otherwise table tries to figure out the type which can result in unexpected results // Labels have string field type, otherwise table tries to figure out the type which can result in unexpected results
// Only "le" label has a number field type // Only "le" label has a number field type
const numberField = label === HISTOGRAM_QUANTILE_LABEL_NAME; const numberField = label === HISTOGRAM_QUANTILE_LABEL_NAME;
return { const field: Field = {
name: label, name: label,
config: { filterable: true }, config: { filterable: true },
type: numberField ? FieldType.number : FieldType.string, type: numberField ? FieldType.number : FieldType.string,
values: new ArrayVector(), values: [],
}; };
return field;
}); });
const valueField = getValueField({ data: [], valueName: valueText }); const valueField = getValueField({ data: [], valueName: valueText });
@ -528,12 +528,12 @@ function transformMetricDataToTable(md: MatrixOrVectorResult[], options: Transfo
if (isMatrixData(d)) { if (isMatrixData(d)) {
d.values.forEach((val) => { d.values.forEach((val) => {
timeField.values.add(val[0] * 1000); timeField.values.add(val[0] * 1000);
metricFields.forEach((metricField) => metricField.values.add(getLabelValue(d.metric, metricField.name))); metricFields.forEach((metricField) => metricField.values.push(getLabelValue(d.metric, metricField.name)));
valueField.values.add(parseSampleValue(val[1])); valueField.values.add(parseSampleValue(val[1]));
}); });
} else { } else {
timeField.values.add(d.value[0] * 1000); timeField.values.add(d.value[0] * 1000);
metricFields.forEach((metricField) => metricField.values.add(getLabelValue(d.metric, metricField.name))); metricFields.forEach((metricField) => metricField.values.push(getLabelValue(d.metric, metricField.name)));
valueField.values.add(parseSampleValue(d.value[1])); valueField.values.add(parseSampleValue(d.value[1]));
} }
}); });
@ -561,7 +561,7 @@ function getTimeField(data: PromValue[], isMs = false): MutableField {
name: TIME_SERIES_TIME_FIELD_NAME, name: TIME_SERIES_TIME_FIELD_NAME,
type: FieldType.time, type: FieldType.time,
config: {}, config: {},
values: new ArrayVector<number>(data.map((val) => (isMs ? val[0] : val[0] * 1000))), values: data.map((val) => (isMs ? val[0] : val[0] * 1000)),
}; };
} }
@ -588,7 +588,7 @@ function getValueField({
displayNameFromDS, displayNameFromDS,
}, },
labels, labels,
values: new ArrayVector<number | null>(data.map((val) => (parseValue ? parseSampleValue(val[1]) : val[1]))), values: data.map((val) => (parseValue ? parseSampleValue(val[1]) : val[1])),
}; };
} }
@ -660,8 +660,8 @@ function transformToHistogramOverTime(seriesList: DataFrame[]) {
} }
for (let j = 0; j < topSeries.values.length; j++) { for (let j = 0; j < topSeries.values.length; j++) {
const bottomPoint = bottomSeries.values.get(j) || [0]; const bottomPoint = bottomSeries.values[j] || [0];
topSeries.values.toArray()[j] -= bottomPoint; topSeries.values[j] -= bottomPoint;
} }
} }

View File

@ -2,7 +2,6 @@ import { lastValueFrom, Observable, of } from 'rxjs';
import { createFetchResponse } from 'test/helpers/createFetchResponse'; import { createFetchResponse } from 'test/helpers/createFetchResponse';
import { import {
ArrayVector,
DataFrame, DataFrame,
dataFrameToJSON, dataFrameToJSON,
DataSourceInstanceSettings, DataSourceInstanceSettings,
@ -144,7 +143,7 @@ describe('Tempo data source', () => {
expect( expect(
(response.data[0] as DataFrame).fields.map((f) => ({ (response.data[0] as DataFrame).fields.map((f) => ({
name: f.name, name: f.name,
values: f.values.toArray(), values: f.values,
})) }))
).toMatchObject([ ).toMatchObject([
{ name: 'traceID', values: ['04450900759028499335'] }, { name: 'traceID', values: ['04450900759028499335'] },
@ -162,7 +161,7 @@ describe('Tempo data source', () => {
expect( expect(
(response.data[1] as DataFrame).fields.map((f) => ({ (response.data[1] as DataFrame).fields.map((f) => ({
name: f.name, name: f.name,
values: f.values.toArray(), values: f.values,
})) }))
).toMatchObject([ ).toMatchObject([
{ name: 'id', values: ['4322526419282105830'] }, { name: 'id', values: ['4322526419282105830'] },
@ -176,7 +175,7 @@ describe('Tempo data source', () => {
expect( expect(
(response.data[2] as DataFrame).fields.map((f) => ({ (response.data[2] as DataFrame).fields.map((f) => ({
name: f.name, name: f.name,
values: f.values.toArray(), values: f.values,
})) }))
).toMatchObject([ ).toMatchObject([
{ name: 'id', values: [] }, { name: 'id', values: [] },
@ -196,7 +195,7 @@ describe('Tempo data source', () => {
const field = response.data[0].fields[0]; const field = response.data[0].fields[0];
expect(field.name).toBe('traceID'); expect(field.name).toBe('traceID');
expect(field.type).toBe(FieldType.string); expect(field.type).toBe(FieldType.string);
expect(field.values.get(0)).toBe('60ba2abb44f13eae'); expect(field.values[0]).toBe('60ba2abb44f13eae');
expect(field.values.length).toBe(6); expect(field.values.length).toBe(6);
}); });
@ -457,14 +456,14 @@ describe('Tempo service graph view', () => {
// Service Graph view // Service Graph view
expect(response.data[0].fields[0].name).toBe('Name'); expect(response.data[0].fields[0].name).toBe('Name');
expect(response.data[0].fields[0].values.toArray().length).toBe(2); expect(response.data[0].fields[0].values.length).toBe(2);
expect(response.data[0].fields[0].values.toArray()[0]).toBe('HTTP Client'); expect(response.data[0].fields[0].values[0]).toBe('HTTP Client');
expect(response.data[0].fields[0].values.toArray()[1]).toBe('HTTP GET - root'); expect(response.data[0].fields[0].values[1]).toBe('HTTP GET - root');
expect(response.data[0].fields[1].name).toBe('Rate'); expect(response.data[0].fields[1].name).toBe('Rate');
expect(response.data[0].fields[1].values.toArray().length).toBe(2); expect(response.data[0].fields[1].values.length).toBe(2);
expect(response.data[0].fields[1].values.toArray()[0]).toBe(12.75164671814457); expect(response.data[0].fields[1].values[0]).toBe(12.75164671814457);
expect(response.data[0].fields[1].values.toArray()[1]).toBe(12.121331111401608); expect(response.data[0].fields[1].values[1]).toBe(12.121331111401608);
expect(response.data[0].fields[1].config.decimals).toBe(2); expect(response.data[0].fields[1].config.decimals).toBe(2);
expect(response.data[0].fields[1].config.links[0].title).toBe('Rate'); expect(response.data[0].fields[1].config.links[0].title).toBe('Rate');
expect(response.data[0].fields[1].config.links[0].internal.query.expr).toBe( expect(response.data[0].fields[1].config.links[0].internal.query.expr).toBe(
@ -474,9 +473,9 @@ describe('Tempo service graph view', () => {
expect(response.data[0].fields[1].config.links[0].internal.query.exemplar).toBe(true); expect(response.data[0].fields[1].config.links[0].internal.query.exemplar).toBe(true);
expect(response.data[0].fields[1].config.links[0].internal.query.instant).toBe(false); expect(response.data[0].fields[1].config.links[0].internal.query.instant).toBe(false);
expect(response.data[0].fields[2].values.toArray().length).toBe(2); expect(response.data[0].fields[2].values.length).toBe(2);
expect(response.data[0].fields[2].values.toArray()[0]).toBe(12.75164671814457); expect(response.data[0].fields[2].values[0]).toBe(12.75164671814457);
expect(response.data[0].fields[2].values.toArray()[1]).toBe(12.121331111401608); expect(response.data[0].fields[2].values[1]).toBe(12.121331111401608);
expect(response.data[0].fields[2].config.color.mode).toBe('continuous-BlPu'); expect(response.data[0].fields[2].config.color.mode).toBe('continuous-BlPu');
expect(response.data[0].fields[2].config.custom.cellOptions.mode).toBe(BarGaugeDisplayMode.Lcd); expect(response.data[0].fields[2].config.custom.cellOptions.mode).toBe(BarGaugeDisplayMode.Lcd);
expect(response.data[0].fields[2].config.custom.cellOptions.type).toBe(TableCellDisplayMode.Gauge); expect(response.data[0].fields[2].config.custom.cellOptions.type).toBe(TableCellDisplayMode.Gauge);
@ -678,7 +677,7 @@ describe('Tempo service graph view', () => {
filterable: true, filterable: true,
}, },
type: 'string', type: 'string',
values: new ArrayVector(['HTTP Client', 'HTTP GET', 'HTTP GET - root', 'HTTP POST', 'HTTP POST - post']), values: ['HTTP Client', 'HTTP GET', 'HTTP GET - root', 'HTTP POST', 'HTTP POST - post'],
}, },
], ],
}, },

View File

@ -597,7 +597,7 @@ function errorAndDurationQuery(
let serviceGraphViewMetrics = []; let serviceGraphViewMetrics = [];
let errorRateBySpanName = ''; let errorRateBySpanName = '';
let durationsBySpanName: string[] = []; let durationsBySpanName: string[] = [];
const spanNames = rateResponse.data[0][0]?.fields[1]?.values.toArray() ?? []; const spanNames = rateResponse.data[0][0]?.fields[1]?.values ?? [];
if (spanNames.length > 0) { if (spanNames.length > 0) {
errorRateBySpanName = buildExpr(errorRateMetric, 'span_name=~"' + spanNames.join('|') + '"', request); errorRateBySpanName = buildExpr(errorRateMetric, 'span_name=~"' + spanNames.join('|') + '"', request);
@ -797,8 +797,8 @@ function getServiceGraphView(
} }
if (errorRate.length > 0 && errorRate[0].fields?.length > 2) { if (errorRate.length > 0 && errorRate[0].fields?.length > 2) {
const errorRateNames = errorRate[0].fields[1]?.values.toArray() ?? []; const errorRateNames = errorRate[0].fields[1]?.values ?? [];
const errorRateValues = errorRate[0].fields[2]?.values.toArray() ?? []; const errorRateValues = errorRate[0].fields[2]?.values ?? [];
let errorRateObj: any = {}; let errorRateObj: any = {};
errorRateNames.map((name: string, index: number) => { errorRateNames.map((name: string, index: number) => {
errorRateObj[name] = { value: errorRateValues[index] }; errorRateObj[name] = { value: errorRateValues[index] };
@ -848,7 +848,7 @@ function getServiceGraphView(
duration.map((d) => { duration.map((d) => {
const delimiter = d.refId?.includes('span_name=~"') ? 'span_name=~"' : 'span_name="'; const delimiter = d.refId?.includes('span_name=~"') ? 'span_name=~"' : 'span_name="';
const name = d.refId?.split(delimiter)[1].split('"}')[0]; const name = d.refId?.split(delimiter)[1].split('"}')[0];
durationObj[name] = { value: d.fields[1].values.toArray()[0] }; durationObj[name] = { value: d.fields[1].values[0] };
}); });
df.fields.push({ df.fields.push({
@ -918,7 +918,7 @@ export function getRateAlignedValues(
rateResp: DataQueryResponseData[], rateResp: DataQueryResponseData[],
objToAlign: { [x: string]: { value: string } } objToAlign: { [x: string]: { value: string } }
) { ) {
const rateNames = rateResp[0]?.fields[1]?.values.toArray() ?? []; const rateNames = rateResp[0]?.fields[1]?.values ?? [];
let values: string[] = []; let values: string[] = [];
for (let i = 0; i < rateNames.length; i++) { for (let i = 0; i < rateNames.length; i++) {

View File

@ -85,7 +85,7 @@ export function createTableFrame(
const match = (line as string).match(traceRegex); const match = (line as string).match(traceRegex);
if (match) { if (match) {
const traceId = match[1]; const traceId = match[1];
const time = timeField ? timeField.values.get(i) : null; const time = timeField ? timeField.values[i] : null;
tableFrame.fields[0].values.add(time); tableFrame.fields[0].values.add(time);
tableFrame.fields[1].values.add(traceId); tableFrame.fields[1].values.add(traceId);
tableFrame.fields[2].values.add(line); tableFrame.fields[2].values.add(line);

View File

@ -1,11 +1,4 @@
import { import { FieldColorModeId, FieldDTO, FieldType, MutableDataFrame, NodeGraphDataFrameFieldNames } from '@grafana/data';
ArrayVector,
FieldColorModeId,
FieldDTO,
FieldType,
MutableDataFrame,
NodeGraphDataFrameFieldNames,
} from '@grafana/data';
import { nodes, edges } from './testData/serviceMapResponse'; import { nodes, edges } from './testData/serviceMapResponse';
@ -51,9 +44,9 @@ export function generateRandomNodes(count = 10) {
nodes[sourceIndex].edges.push(nodes[targetIndex].id); nodes[sourceIndex].edges.push(nodes[targetIndex].id);
} }
const nodeFields: Record<string, Omit<FieldDTO, 'name'> & { values: ArrayVector }> = { const nodeFields: Record<string, Omit<FieldDTO, 'name'> & { values: any[] }> = {
[NodeGraphDataFrameFieldNames.id]: { [NodeGraphDataFrameFieldNames.id]: {
values: new ArrayVector(), values: [],
type: FieldType.string, type: FieldType.string,
config: { config: {
links: [ links: [
@ -70,35 +63,35 @@ export function generateRandomNodes(count = 10) {
}, },
}, },
[NodeGraphDataFrameFieldNames.title]: { [NodeGraphDataFrameFieldNames.title]: {
values: new ArrayVector(), values: [],
type: FieldType.string, type: FieldType.string,
}, },
[NodeGraphDataFrameFieldNames.subTitle]: { [NodeGraphDataFrameFieldNames.subTitle]: {
values: new ArrayVector(), values: [],
type: FieldType.string, type: FieldType.string,
}, },
[NodeGraphDataFrameFieldNames.mainStat]: { [NodeGraphDataFrameFieldNames.mainStat]: {
values: new ArrayVector(), values: [],
type: FieldType.number, type: FieldType.number,
config: { displayName: 'Transactions per second' }, config: { displayName: 'Transactions per second' },
}, },
[NodeGraphDataFrameFieldNames.secondaryStat]: { [NodeGraphDataFrameFieldNames.secondaryStat]: {
values: new ArrayVector(), values: [],
type: FieldType.number, type: FieldType.number,
config: { displayName: 'Average duration' }, config: { displayName: 'Average duration' },
}, },
[NodeGraphDataFrameFieldNames.arc + 'success']: { [NodeGraphDataFrameFieldNames.arc + 'success']: {
values: new ArrayVector(), values: [],
type: FieldType.number, type: FieldType.number,
config: { color: { fixedColor: 'green', mode: FieldColorModeId.Fixed }, displayName: 'Success' }, config: { color: { fixedColor: 'green', mode: FieldColorModeId.Fixed }, displayName: 'Success' },
}, },
[NodeGraphDataFrameFieldNames.arc + 'errors']: { [NodeGraphDataFrameFieldNames.arc + 'errors']: {
values: new ArrayVector(), values: [],
type: FieldType.number, type: FieldType.number,
config: { color: { fixedColor: 'red', mode: FieldColorModeId.Fixed }, displayName: 'Errors' }, config: { color: { fixedColor: 'red', mode: FieldColorModeId.Fixed }, displayName: 'Errors' },
}, },
[NodeGraphDataFrameFieldNames.icon]: { [NodeGraphDataFrameFieldNames.icon]: {
values: new ArrayVector(), values: [],
type: FieldType.string, type: FieldType.string,
}, },
}; };
@ -115,10 +108,10 @@ export function generateRandomNodes(count = 10) {
const edgesFrame = new MutableDataFrame({ const edgesFrame = new MutableDataFrame({
name: 'edges', name: 'edges',
fields: [ fields: [
{ name: NodeGraphDataFrameFieldNames.id, values: new ArrayVector(), type: FieldType.string }, { name: NodeGraphDataFrameFieldNames.id, values: [], type: FieldType.string },
{ name: NodeGraphDataFrameFieldNames.source, values: new ArrayVector(), type: FieldType.string }, { name: NodeGraphDataFrameFieldNames.source, values: [], type: FieldType.string },
{ name: NodeGraphDataFrameFieldNames.target, values: new ArrayVector(), type: FieldType.string }, { name: NodeGraphDataFrameFieldNames.target, values: [], type: FieldType.string },
{ name: NodeGraphDataFrameFieldNames.mainStat, values: new ArrayVector(), type: FieldType.number }, { name: NodeGraphDataFrameFieldNames.mainStat, values: [], type: FieldType.number },
], ],
meta: { preferredVisualisationType: 'nodeGraph' }, meta: { preferredVisualisationType: 'nodeGraph' },
}); });

View File

@ -220,7 +220,7 @@ export const BarChartPanel = ({ data, options, fieldConfig, width, height, timeZ
}; };
const rawValue = (seriesIdx: number, valueIdx: number) => { const rawValue = (seriesIdx: number, valueIdx: number) => {
return frame0Ref.current!.fields[seriesIdx].values.get(valueIdx); return frame0Ref.current!.fields[seriesIdx].values[valueIdx];
}; };
// Color by value // Color by value
@ -233,7 +233,7 @@ export const BarChartPanel = ({ data, options, fieldConfig, width, height, timeZ
const disp = colorByField.display!; const disp = colorByField.display!;
fillOpacity = (colorByField.config.custom.fillOpacity ?? 100) / 100; fillOpacity = (colorByField.config.custom.fillOpacity ?? 100) / 100;
// gradientMode? ignore? // gradientMode? ignore?
getColor = (seriesIdx: number, valueIdx: number) => disp(colorByFieldRef.current?.values.get(valueIdx)).color!; getColor = (seriesIdx: number, valueIdx: number) => disp(colorByFieldRef.current?.values[valueIdx]).color!;
} else { } else {
const hasPerBarColor = frame0Ref.current!.fields.some((f) => { const hasPerBarColor = frame0Ref.current!.fields.some((f) => {
const fromThresholds = const fromThresholds =
@ -261,7 +261,7 @@ export const BarChartPanel = ({ data, options, fieldConfig, width, height, timeZ
getColor = (seriesIdx: number, valueIdx: number) => { getColor = (seriesIdx: number, valueIdx: number) => {
let field = frame0Ref.current!.fields[seriesIdx]; let field = frame0Ref.current!.fields[seriesIdx];
return field.display!(field.values.get(valueIdx)).color!; return field.display!(field.values[valueIdx]).color!;
}; };
} }
} }

View File

@ -109,7 +109,7 @@ describe('BarChart utils', () => {
valueSize: 10, valueSize: 10,
}, },
fullHighlight: false, fullHighlight: false,
rawValue: (seriesIdx: number, valueIdx: number) => frame.fields[seriesIdx].values.get(valueIdx), rawValue: (seriesIdx: number, valueIdx: number) => frame.fields[seriesIdx].values[valueIdx],
}; };
it.each([VizOrientation.Auto, VizOrientation.Horizontal, VizOrientation.Vertical])('orientation', (v) => { it.each([VizOrientation.Auto, VizOrientation.Horizontal, VizOrientation.Vertical])('orientation', (v) => {

View File

@ -97,7 +97,7 @@ function buildTableDataFrame(
url: '', url: '',
onClick: (e: DataLinkClickEvent) => { onClick: (e: DataLinkClickEvent) => {
const field: Field = e.origin.field; const field: Field = e.origin.field;
const value = field.values.get(e.origin.rowIndex); const value = field.values[e.origin.rowIndex];
onSymbolClick(value); onSymbolClick(value);
}, },
}, },

View File

@ -73,7 +73,7 @@ export const generateLabel = (feature: FeatureLike, idx: number): string | React
if (!first) { if (!first) {
first = k; first = k;
} }
props[k] = f.values.get(rowIndex); props[k] = f.values[rowIndex];
} }
} }
} }

View File

@ -45,7 +45,7 @@ export const DataHoverView = ({ data, rowIndex, columnIndex, sortOrder, mode, he
const linkLookup = new Set<string>(); const linkLookup = new Set<string>();
for (const f of orderedVisibleFields) { for (const f of orderedVisibleFields) {
const v = f.values.get(rowIndex); const v = f.values[rowIndex];
const disp = f.display ? f.display(v) : { text: `${v}`, numeric: +v }; const disp = f.display ? f.display(v) : { text: `${v}`, numeric: +v };
if (f.getLinks) { if (f.getLinks) {
f.getLinks({ calculatedValue: disp, valueRowIndex: rowIndex }).forEach((link) => { f.getLinks({ calculatedValue: disp, valueRowIndex: rowIndex }).forEach((link) => {

View File

@ -43,7 +43,7 @@ export function MarkersLegend(props: MarkersLegendProps) {
} }
const rowIndex = props.rowIndex as number; // eslint-disable-line const rowIndex = props.rowIndex as number; // eslint-disable-line
return colorField.values.get(rowIndex); return colorField.values[rowIndex];
}, [hoverEvent, colorField]); }, [hoverEvent, colorField]);
if (!styleConfig) { if (!styleConfig) {

Some files were not shown because too many files have changed in this diff Show More