Refactor: rename SeriesData to DataFrame (#17854)
This commit is contained in:
@@ -4,7 +4,7 @@ import { Table } from './Table';
|
|||||||
import { getTheme } from '../../themes';
|
import { getTheme } from '../../themes';
|
||||||
|
|
||||||
import { migratedTestTable, migratedTestStyles, simpleTable } from './examples';
|
import { migratedTestTable, migratedTestStyles, simpleTable } from './examples';
|
||||||
import { ScopedVars, SeriesData, GrafanaThemeType } from '../../types/index';
|
import { ScopedVars, DataFrame, GrafanaThemeType } from '../../types/index';
|
||||||
import { withFullSizeStory } from '../../utils/storybook/withFullSizeStory';
|
import { withFullSizeStory } from '../../utils/storybook/withFullSizeStory';
|
||||||
import { number, boolean } from '@storybook/addon-knobs';
|
import { number, boolean } from '@storybook/addon-knobs';
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@ export function columnIndexToLeter(column: number) {
|
|||||||
return String.fromCharCode(A + c2);
|
return String.fromCharCode(A + c2);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function makeDummyTable(columnCount: number, rowCount: number): SeriesData {
|
export function makeDummyTable(columnCount: number, rowCount: number): DataFrame {
|
||||||
return {
|
return {
|
||||||
fields: Array.from(new Array(columnCount), (x, i) => {
|
fields: Array.from(new Array(columnCount), (x, i) => {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import {
|
|||||||
} from 'react-virtualized';
|
} from 'react-virtualized';
|
||||||
import { Themeable } from '../../types/theme';
|
import { Themeable } from '../../types/theme';
|
||||||
|
|
||||||
import { sortSeriesData } from '../../utils/processSeriesData';
|
import { sortDataFrame } from '../../utils/processDataFrame';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
TableCellBuilder,
|
TableCellBuilder,
|
||||||
@@ -22,11 +22,11 @@ import {
|
|||||||
simpleCellBuilder,
|
simpleCellBuilder,
|
||||||
} from './TableCellBuilder';
|
} from './TableCellBuilder';
|
||||||
import { stringToJsRegex } from '@grafana/data';
|
import { stringToJsRegex } from '@grafana/data';
|
||||||
import { SeriesData } from '../../types/data';
|
import { DataFrame } from '../../types/data';
|
||||||
import { InterpolateFunction } from '../../types/panel';
|
import { InterpolateFunction } from '../../types/panel';
|
||||||
|
|
||||||
export interface Props extends Themeable {
|
export interface Props extends Themeable {
|
||||||
data: SeriesData;
|
data: DataFrame;
|
||||||
|
|
||||||
minColumnWidth: number;
|
minColumnWidth: number;
|
||||||
showHeader: boolean;
|
showHeader: boolean;
|
||||||
@@ -44,7 +44,7 @@ export interface Props extends Themeable {
|
|||||||
interface State {
|
interface State {
|
||||||
sortBy?: number;
|
sortBy?: number;
|
||||||
sortDirection?: SortDirectionType;
|
sortDirection?: SortDirectionType;
|
||||||
data: SeriesData;
|
data: DataFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ColumnRenderInfo {
|
interface ColumnRenderInfo {
|
||||||
@@ -115,7 +115,7 @@ export class Table extends Component<Props, State> {
|
|||||||
// Update the data when data or sort changes
|
// Update the data when data or sort changes
|
||||||
if (dataChanged || sortBy !== prevState.sortBy || sortDirection !== prevState.sortDirection) {
|
if (dataChanged || sortBy !== prevState.sortBy || sortDirection !== prevState.sortDirection) {
|
||||||
this.scrollToTop = true;
|
this.scrollToTop = true;
|
||||||
this.setState({ data: sortSeriesData(data, sortBy, sortDirection === 'DESC') });
|
this.setState({ data: sortDataFrame(data, sortBy, sortDirection === 'DESC') });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,7 +170,7 @@ export class Table extends Component<Props, State> {
|
|||||||
this.setState({ sortBy: sort, sortDirection: dir });
|
this.setState({ sortBy: sort, sortDirection: dir });
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Converts the grid coordinates to SeriesData coordinates */
|
/** Converts the grid coordinates to DataFrame coordinates */
|
||||||
getCellRef = (rowIndex: number, columnIndex: number): DataIndex => {
|
getCellRef = (rowIndex: number, columnIndex: number): DataIndex => {
|
||||||
const { showHeader, rotate } = this.props;
|
const { showHeader, rotate } = this.props;
|
||||||
const rowOffset = showHeader ? -1 : 0;
|
const rowOffset = showHeader ? -1 : 0;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import React from 'react';
|
|||||||
import { storiesOf } from '@storybook/react';
|
import { storiesOf } from '@storybook/react';
|
||||||
import TableInputCSV from './TableInputCSV';
|
import TableInputCSV from './TableInputCSV';
|
||||||
import { action } from '@storybook/addon-actions';
|
import { action } from '@storybook/addon-actions';
|
||||||
import { SeriesData } from '../../types/data';
|
import { DataFrame } from '../../types/data';
|
||||||
import { withCenteredStory } from '../../utils/storybook/withCenteredStory';
|
import { withCenteredStory } from '../../utils/storybook/withCenteredStory';
|
||||||
|
|
||||||
const TableInputStories = storiesOf('UI/Table/Input', module);
|
const TableInputStories = storiesOf('UI/Table/Input', module);
|
||||||
@@ -16,7 +16,7 @@ TableInputStories.add('default', () => {
|
|||||||
width={400}
|
width={400}
|
||||||
height={'90vh'}
|
height={'90vh'}
|
||||||
text={'a,b,c\n1,2,3'}
|
text={'a,b,c\n1,2,3'}
|
||||||
onSeriesParsed={(data: SeriesData[], text: string) => {
|
onSeriesParsed={(data: DataFrame[], text: string) => {
|
||||||
console.log('Data', data, text);
|
console.log('Data', data, text);
|
||||||
action('Data')(data, text);
|
action('Data')(data, text);
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import React from 'react';
|
|||||||
|
|
||||||
import renderer from 'react-test-renderer';
|
import renderer from 'react-test-renderer';
|
||||||
import TableInputCSV from './TableInputCSV';
|
import TableInputCSV from './TableInputCSV';
|
||||||
import { SeriesData } from '../../types/data';
|
import { DataFrame } from '../../types/data';
|
||||||
|
|
||||||
describe('TableInputCSV', () => {
|
describe('TableInputCSV', () => {
|
||||||
it('renders correctly', () => {
|
it('renders correctly', () => {
|
||||||
@@ -12,7 +12,7 @@ describe('TableInputCSV', () => {
|
|||||||
width={'100%'}
|
width={'100%'}
|
||||||
height={200}
|
height={200}
|
||||||
text={'a,b,c\n1,2,3'}
|
text={'a,b,c\n1,2,3'}
|
||||||
onSeriesParsed={(data: SeriesData[], text: string) => {
|
onSeriesParsed={(data: DataFrame[], text: string) => {
|
||||||
// console.log('Table:', table, 'from:', text);
|
// console.log('Table:', table, 'from:', text);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import debounce from 'lodash/debounce';
|
import debounce from 'lodash/debounce';
|
||||||
import { SeriesData } from '../../types/data';
|
import { DataFrame } from '../../types/data';
|
||||||
import { CSVConfig, readCSV } from '../../utils/csv';
|
import { CSVConfig, readCSV } from '../../utils/csv';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@@ -8,12 +8,12 @@ interface Props {
|
|||||||
text: string;
|
text: string;
|
||||||
width: string | number;
|
width: string | number;
|
||||||
height: string | number;
|
height: string | number;
|
||||||
onSeriesParsed: (data: SeriesData[], text: string) => void;
|
onSeriesParsed: (data: DataFrame[], text: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
text: string;
|
text: string;
|
||||||
data: SeriesData[];
|
data: DataFrame[];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { SeriesData } from '../../types/data';
|
import { DataFrame } from '../../types/data';
|
||||||
import { ColumnStyle } from './TableCellBuilder';
|
import { ColumnStyle } from './TableCellBuilder';
|
||||||
import { getColorDefinitionByName } from '../../utils/namedColorsPalette';
|
import { getColorDefinitionByName } from '../../utils/namedColorsPalette';
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@ export const migratedTestTable = {
|
|||||||
{ name: 'RangeMappingColored' },
|
{ name: 'RangeMappingColored' },
|
||||||
],
|
],
|
||||||
rows: [[1388556366666, 1230, 40, undefined, '', '', 'my.host.com', 'host1', ['value1', 'value2'], 1, 2, 1, 2]],
|
rows: [[1388556366666, 1230, 40, undefined, '', '', 'my.host.com', 'host1', ['value1', 'value2'], 1, 2, 1, 2]],
|
||||||
} as SeriesData;
|
} as DataFrame;
|
||||||
|
|
||||||
export const migratedTestStyles: ColumnStyle[] = [
|
export const migratedTestStyles: ColumnStyle[] = [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ export interface Labels {
|
|||||||
[key: string]: string;
|
[key: string]: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SeriesData extends QueryResultBase {
|
export interface DataFrame extends QueryResultBase {
|
||||||
name?: string;
|
name?: string;
|
||||||
fields: Field[];
|
fields: Field[];
|
||||||
rows: any[][];
|
rows: any[][];
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { ComponentType, ComponentClass } from 'react';
|
import { ComponentType, ComponentClass } from 'react';
|
||||||
import { TimeRange, RawTimeRange } from './time';
|
import { TimeRange, RawTimeRange } from './time';
|
||||||
import { PluginMeta, GrafanaPlugin } from './plugin';
|
import { PluginMeta, GrafanaPlugin } from './plugin';
|
||||||
import { TableData, TimeSeries, SeriesData, LoadingState } from './data';
|
import { TableData, TimeSeries, DataFrame, LoadingState } from './data';
|
||||||
import { PanelData } from './panel';
|
import { PanelData } from './panel';
|
||||||
import { LogRowModel } from './logs';
|
import { LogRowModel } from './logs';
|
||||||
|
|
||||||
@@ -284,11 +284,11 @@ export interface ExploreStartPageProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starting in v6.2 SeriesData can represent both TimeSeries and TableData
|
* Starting in v6.2 DataFrame can represent both TimeSeries and TableData
|
||||||
*/
|
*/
|
||||||
export type LegacyResponseData = TimeSeries | TableData | any;
|
export type LegacyResponseData = TimeSeries | TableData | any;
|
||||||
|
|
||||||
export type DataQueryResponseData = SeriesData | LegacyResponseData;
|
export type DataQueryResponseData = DataFrame | LegacyResponseData;
|
||||||
|
|
||||||
export type DataStreamObserver = (event: DataStreamState) => void;
|
export type DataStreamObserver = (event: DataStreamState) => void;
|
||||||
|
|
||||||
@@ -313,7 +313,7 @@ export interface DataStreamState {
|
|||||||
/**
|
/**
|
||||||
* Series data may not be known yet
|
* Series data may not be known yet
|
||||||
*/
|
*/
|
||||||
series?: SeriesData[];
|
series?: DataFrame[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Error in stream (but may still be running)
|
* Error in stream (but may still be running)
|
||||||
@@ -323,7 +323,7 @@ export interface DataStreamState {
|
|||||||
/**
|
/**
|
||||||
* Optionally return only the rows that changed in this event
|
* Optionally return only the rows that changed in this event
|
||||||
*/
|
*/
|
||||||
delta?: SeriesData[];
|
delta?: DataFrame[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop listening to this stream
|
* Stop listening to this stream
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { ComponentClass, ComponentType } from 'react';
|
import { ComponentClass, ComponentType } from 'react';
|
||||||
import { LoadingState, SeriesData } from './data';
|
import { LoadingState, DataFrame } from './data';
|
||||||
import { TimeRange } from './time';
|
import { TimeRange } from './time';
|
||||||
import { ScopedVars, DataQueryRequest, DataQueryError, LegacyResponseData } from './datasource';
|
import { ScopedVars, DataQueryRequest, DataQueryError, LegacyResponseData } from './datasource';
|
||||||
import { PluginMeta, GrafanaPlugin } from './plugin';
|
import { PluginMeta, GrafanaPlugin } from './plugin';
|
||||||
@@ -14,7 +14,7 @@ export interface PanelPluginMeta extends PluginMeta {
|
|||||||
|
|
||||||
export interface PanelData {
|
export interface PanelData {
|
||||||
state: LoadingState;
|
state: LoadingState;
|
||||||
series: SeriesData[];
|
series: DataFrame[];
|
||||||
request?: DataQueryRequest;
|
request?: DataQueryRequest;
|
||||||
error?: DataQueryError;
|
error?: DataQueryError;
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import defaults from 'lodash/defaults';
|
|||||||
import isNumber from 'lodash/isNumber';
|
import isNumber from 'lodash/isNumber';
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import { SeriesData, Field, FieldType } from '../types/index';
|
import { DataFrame, Field, FieldType } from '../types/index';
|
||||||
import { guessFieldTypeFromValue } from './processSeriesData';
|
import { guessFieldTypeFromValue } from './processDataFrame';
|
||||||
|
|
||||||
export enum CSVHeaderStyle {
|
export enum CSVHeaderStyle {
|
||||||
full,
|
full,
|
||||||
@@ -28,7 +28,7 @@ export interface CSVParseCallbacks {
|
|||||||
* This can return a modified table to force any
|
* This can return a modified table to force any
|
||||||
* Column configurations
|
* Column configurations
|
||||||
*/
|
*/
|
||||||
onHeader: (table: SeriesData) => void;
|
onHeader: (table: DataFrame) => void;
|
||||||
|
|
||||||
// Called after each row is read and
|
// Called after each row is read and
|
||||||
onRow: (row: any[]) => void;
|
onRow: (row: any[]) => void;
|
||||||
@@ -39,7 +39,7 @@ export interface CSVOptions {
|
|||||||
callback?: CSVParseCallbacks;
|
callback?: CSVParseCallbacks;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function readCSV(csv: string, options?: CSVOptions): SeriesData[] {
|
export function readCSV(csv: string, options?: CSVOptions): DataFrame[] {
|
||||||
return new CSVReader(options).readCSV(csv);
|
return new CSVReader(options).readCSV(csv);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,9 +56,9 @@ export class CSVReader {
|
|||||||
callback?: CSVParseCallbacks;
|
callback?: CSVParseCallbacks;
|
||||||
|
|
||||||
field: FieldParser[];
|
field: FieldParser[];
|
||||||
series: SeriesData;
|
series: DataFrame;
|
||||||
state: ParseState;
|
state: ParseState;
|
||||||
data: SeriesData[];
|
data: DataFrame[];
|
||||||
|
|
||||||
constructor(options?: CSVOptions) {
|
constructor(options?: CSVOptions) {
|
||||||
if (!options) {
|
if (!options) {
|
||||||
@@ -193,7 +193,7 @@ export class CSVReader {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
readCSV(text: string): SeriesData[] {
|
readCSV(text: string): DataFrame[] {
|
||||||
this.data = [this.series];
|
this.data = [this.series];
|
||||||
|
|
||||||
const papacfg = {
|
const papacfg = {
|
||||||
@@ -315,7 +315,7 @@ function getHeaderLine(key: string, fields: Field[], config: CSVConfig): string
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
export function toCSV(data: SeriesData[], config?: CSVConfig): string {
|
export function toCSV(data: DataFrame[], config?: CSVConfig): string {
|
||||||
if (!data) {
|
if (!data) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import {
|
|||||||
FieldType,
|
FieldType,
|
||||||
NullValueMode,
|
NullValueMode,
|
||||||
GrafanaTheme,
|
GrafanaTheme,
|
||||||
SeriesData,
|
DataFrame,
|
||||||
InterpolateFunction,
|
InterpolateFunction,
|
||||||
Field,
|
Field,
|
||||||
ScopedVars,
|
ScopedVars,
|
||||||
@@ -36,7 +36,7 @@ export const VAR_FIELD_NAME = '__field_name';
|
|||||||
export const VAR_CALC = '__calc';
|
export const VAR_CALC = '__calc';
|
||||||
export const VAR_CELL_PREFIX = '__cell_'; // consistent with existing table templates
|
export const VAR_CELL_PREFIX = '__cell_'; // consistent with existing table templates
|
||||||
|
|
||||||
function getTitleTemplate(title: string | undefined, stats: string[], data?: SeriesData[]): string {
|
function getTitleTemplate(title: string | undefined, stats: string[], data?: DataFrame[]): string {
|
||||||
// If the title exists, use it as a template variable
|
// If the title exists, use it as a template variable
|
||||||
if (title) {
|
if (title) {
|
||||||
return title;
|
return title;
|
||||||
@@ -72,7 +72,7 @@ export interface FieldDisplay {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface GetFieldDisplayValuesOptions {
|
export interface GetFieldDisplayValuesOptions {
|
||||||
data?: SeriesData[];
|
data?: DataFrame[];
|
||||||
fieldOptions: FieldDisplayOptions;
|
fieldOptions: FieldDisplayOptions;
|
||||||
replaceVariables: InterpolateFunction;
|
replaceVariables: InterpolateFunction;
|
||||||
sparkline?: boolean; // Calculate the sparkline
|
sparkline?: boolean; // Calculate the sparkline
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Libraries
|
// Libraries
|
||||||
import isNumber from 'lodash/isNumber';
|
import isNumber from 'lodash/isNumber';
|
||||||
|
|
||||||
import { SeriesData, NullValueMode } from '../types/index';
|
import { DataFrame, NullValueMode } from '../types/index';
|
||||||
|
|
||||||
export enum ReducerID {
|
export enum ReducerID {
|
||||||
sum = 'sum',
|
sum = 'sum',
|
||||||
@@ -29,7 +29,7 @@ export interface FieldCalcs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Internal function
|
// Internal function
|
||||||
type FieldReducer = (data: SeriesData, fieldIndex: number, ignoreNulls: boolean, nullAsZero: boolean) => FieldCalcs;
|
type FieldReducer = (data: DataFrame, fieldIndex: number, ignoreNulls: boolean, nullAsZero: boolean) => FieldCalcs;
|
||||||
|
|
||||||
export interface FieldReducerInfo {
|
export interface FieldReducerInfo {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -64,7 +64,7 @@ export function getFieldReducers(ids?: string[]): FieldReducerInfo[] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface ReduceFieldOptions {
|
interface ReduceFieldOptions {
|
||||||
series: SeriesData;
|
series: DataFrame;
|
||||||
fieldIndex: number;
|
fieldIndex: number;
|
||||||
reducers: string[]; // The stats to calculate
|
reducers: string[]; // The stats to calculate
|
||||||
nullValueMode?: NullValueMode;
|
nullValueMode?: NullValueMode;
|
||||||
@@ -222,7 +222,7 @@ function getById(id: string): FieldReducerInfo | undefined {
|
|||||||
return index[id];
|
return index[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
function doStandardCalcs(data: SeriesData, fieldIndex: number, ignoreNulls: boolean, nullAsZero: boolean): FieldCalcs {
|
function doStandardCalcs(data: DataFrame, fieldIndex: number, ignoreNulls: boolean, nullAsZero: boolean): FieldCalcs {
|
||||||
const calcs = {
|
const calcs = {
|
||||||
sum: 0,
|
sum: 0,
|
||||||
max: -Number.MAX_VALUE,
|
max: -Number.MAX_VALUE,
|
||||||
@@ -340,16 +340,16 @@ function doStandardCalcs(data: SeriesData, fieldIndex: number, ignoreNulls: bool
|
|||||||
return calcs;
|
return calcs;
|
||||||
}
|
}
|
||||||
|
|
||||||
function calculateFirst(data: SeriesData, fieldIndex: number, ignoreNulls: boolean, nullAsZero: boolean): FieldCalcs {
|
function calculateFirst(data: DataFrame, fieldIndex: number, ignoreNulls: boolean, nullAsZero: boolean): FieldCalcs {
|
||||||
return { first: data.rows[0][fieldIndex] };
|
return { first: data.rows[0][fieldIndex] };
|
||||||
}
|
}
|
||||||
|
|
||||||
function calculateLast(data: SeriesData, fieldIndex: number, ignoreNulls: boolean, nullAsZero: boolean): FieldCalcs {
|
function calculateLast(data: DataFrame, fieldIndex: number, ignoreNulls: boolean, nullAsZero: boolean): FieldCalcs {
|
||||||
return { last: data.rows[data.rows.length - 1][fieldIndex] };
|
return { last: data.rows[data.rows.length - 1][fieldIndex] };
|
||||||
}
|
}
|
||||||
|
|
||||||
function calculateChangeCount(
|
function calculateChangeCount(
|
||||||
data: SeriesData,
|
data: DataFrame,
|
||||||
fieldIndex: number,
|
fieldIndex: number,
|
||||||
ignoreNulls: boolean,
|
ignoreNulls: boolean,
|
||||||
nullAsZero: boolean
|
nullAsZero: boolean
|
||||||
@@ -378,7 +378,7 @@ function calculateChangeCount(
|
|||||||
}
|
}
|
||||||
|
|
||||||
function calculateDistinctCount(
|
function calculateDistinctCount(
|
||||||
data: SeriesData,
|
data: DataFrame,
|
||||||
fieldIndex: number,
|
fieldIndex: number,
|
||||||
ignoreNulls: boolean,
|
ignoreNulls: boolean,
|
||||||
nullAsZero: boolean
|
nullAsZero: boolean
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
// Types
|
// Types
|
||||||
import { NullValueMode, GraphSeriesValue, SeriesData } from '../types/index';
|
import { NullValueMode, GraphSeriesValue, DataFrame } from '../types/index';
|
||||||
|
|
||||||
export interface FlotPairsOptions {
|
export interface FlotPairsOptions {
|
||||||
series: SeriesData;
|
series: DataFrame;
|
||||||
xIndex: number;
|
xIndex: number;
|
||||||
yIndex: number;
|
yIndex: number;
|
||||||
nullValueMode?: NullValueMode;
|
nullValueMode?: NullValueMode;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
export * from './processSeriesData';
|
export * from './processDataFrame';
|
||||||
export * from './valueFormats/valueFormats';
|
export * from './valueFormats/valueFormats';
|
||||||
export * from './colors';
|
export * from './colors';
|
||||||
export * from './namedColorsPalette';
|
export * from './namedColorsPalette';
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { LogLevel } from '../types/logs';
|
import { LogLevel } from '../types/logs';
|
||||||
import { SeriesData, FieldType } from '../types/data';
|
import { DataFrame, FieldType } from '../types/data';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the log level of a log line.
|
* Returns the log level of a log line.
|
||||||
@@ -32,7 +32,7 @@ export function getLogLevelFromKey(key: string): LogLevel {
|
|||||||
return LogLevel.unknown;
|
return LogLevel.unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function addLogLevelToSeries(series: SeriesData, lineIndex: number): SeriesData {
|
export function addLogLevelToSeries(series: DataFrame, lineIndex: number): DataFrame {
|
||||||
return {
|
return {
|
||||||
...series, // Keeps Tags, RefID etc
|
...series, // Keeps Tags, RefID etc
|
||||||
fields: [...series.fields, { name: 'LogLevel', type: FieldType.string }],
|
fields: [...series.fields, { name: 'LogLevel', type: FieldType.string }],
|
||||||
|
|||||||
+17
-17
@@ -1,21 +1,21 @@
|
|||||||
import {
|
import {
|
||||||
isSeriesData,
|
isDataFrame,
|
||||||
toLegacyResponseData,
|
toLegacyResponseData,
|
||||||
isTableData,
|
isTableData,
|
||||||
toSeriesData,
|
toDataFrame,
|
||||||
guessFieldTypes,
|
guessFieldTypes,
|
||||||
guessFieldTypeFromValue,
|
guessFieldTypeFromValue,
|
||||||
} from './processSeriesData';
|
} from './processDataFrame';
|
||||||
import { FieldType, TimeSeries, SeriesData, TableData } from '../types/data';
|
import { FieldType, TimeSeries, DataFrame, TableData } from '../types/data';
|
||||||
import { dateTime } from './moment_wrapper';
|
import { dateTime } from './moment_wrapper';
|
||||||
|
|
||||||
describe('toSeriesData', () => {
|
describe('toDataFrame', () => {
|
||||||
it('converts timeseries to series', () => {
|
it('converts timeseries to series', () => {
|
||||||
const input1 = {
|
const input1 = {
|
||||||
target: 'Field Name',
|
target: 'Field Name',
|
||||||
datapoints: [[100, 1], [200, 2]],
|
datapoints: [[100, 1], [200, 2]],
|
||||||
};
|
};
|
||||||
let series = toSeriesData(input1);
|
let series = toDataFrame(input1);
|
||||||
expect(series.fields[0].name).toBe(input1.target);
|
expect(series.fields[0].name).toBe(input1.target);
|
||||||
expect(series.rows).toBe(input1.datapoints);
|
expect(series.rows).toBe(input1.datapoints);
|
||||||
|
|
||||||
@@ -25,16 +25,16 @@ describe('toSeriesData', () => {
|
|||||||
target: '',
|
target: '',
|
||||||
datapoints: [[100, 1], [200, 2]],
|
datapoints: [[100, 1], [200, 2]],
|
||||||
};
|
};
|
||||||
series = toSeriesData(input2);
|
series = toDataFrame(input2);
|
||||||
expect(series.fields[0].name).toEqual('Value');
|
expect(series.fields[0].name).toEqual('Value');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('keeps seriesData unchanged', () => {
|
it('keeps dataFrame unchanged', () => {
|
||||||
const input = {
|
const input = {
|
||||||
fields: [{ text: 'A' }, { text: 'B' }, { text: 'C' }],
|
fields: [{ text: 'A' }, { text: 'B' }, { text: 'C' }],
|
||||||
rows: [[100, 'A', 1], [200, 'B', 2], [300, 'C', 3]],
|
rows: [[100, 'A', 1], [200, 'B', 2], [300, 'C', 3]],
|
||||||
};
|
};
|
||||||
const series = toSeriesData(input);
|
const series = toDataFrame(input);
|
||||||
expect(series).toBe(input);
|
expect(series).toBe(input);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -77,12 +77,12 @@ describe('SerisData backwards compatibility', () => {
|
|||||||
target: 'Field Name',
|
target: 'Field Name',
|
||||||
datapoints: [[100, 1], [200, 2]],
|
datapoints: [[100, 1], [200, 2]],
|
||||||
};
|
};
|
||||||
const series = toSeriesData(timeseries);
|
const series = toDataFrame(timeseries);
|
||||||
expect(isSeriesData(timeseries)).toBeFalsy();
|
expect(isDataFrame(timeseries)).toBeFalsy();
|
||||||
expect(isSeriesData(series)).toBeTruthy();
|
expect(isDataFrame(series)).toBeTruthy();
|
||||||
|
|
||||||
const roundtrip = toLegacyResponseData(series) as TimeSeries;
|
const roundtrip = toLegacyResponseData(series) as TimeSeries;
|
||||||
expect(isSeriesData(roundtrip)).toBeFalsy();
|
expect(isDataFrame(roundtrip)).toBeFalsy();
|
||||||
expect(roundtrip.target).toBe(timeseries.target);
|
expect(roundtrip.target).toBe(timeseries.target);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -91,17 +91,17 @@ describe('SerisData backwards compatibility', () => {
|
|||||||
columns: [{ text: 'a', unit: 'ms' }, { text: 'b', unit: 'zz' }, { text: 'c', unit: 'yy' }],
|
columns: [{ text: 'a', unit: 'ms' }, { text: 'b', unit: 'zz' }, { text: 'c', unit: 'yy' }],
|
||||||
rows: [[100, 1, 'a'], [200, 2, 'a']],
|
rows: [[100, 1, 'a'], [200, 2, 'a']],
|
||||||
};
|
};
|
||||||
const series = toSeriesData(table);
|
const series = toDataFrame(table);
|
||||||
expect(isTableData(table)).toBeTruthy();
|
expect(isTableData(table)).toBeTruthy();
|
||||||
expect(isSeriesData(series)).toBeTruthy();
|
expect(isDataFrame(series)).toBeTruthy();
|
||||||
|
|
||||||
const roundtrip = toLegacyResponseData(series) as TimeSeries;
|
const roundtrip = toLegacyResponseData(series) as TimeSeries;
|
||||||
expect(isTableData(roundtrip)).toBeTruthy();
|
expect(isTableData(roundtrip)).toBeTruthy();
|
||||||
expect(roundtrip).toMatchObject(table);
|
expect(roundtrip).toMatchObject(table);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('converts SeriesData to TableData to series and back again', () => {
|
it('converts DataFrame to TableData to series and back again', () => {
|
||||||
const series: SeriesData = {
|
const series: DataFrame = {
|
||||||
refId: 'Z',
|
refId: 'Z',
|
||||||
meta: {
|
meta: {
|
||||||
somethign: 8,
|
somethign: 8,
|
||||||
+13
-13
@@ -4,10 +4,10 @@ import isString from 'lodash/isString';
|
|||||||
import isBoolean from 'lodash/isBoolean';
|
import isBoolean from 'lodash/isBoolean';
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import { SeriesData, Field, TimeSeries, FieldType, TableData, Column } from '../types/index';
|
import { DataFrame, Field, TimeSeries, FieldType, TableData, Column } from '../types/index';
|
||||||
import { isDateTime } from './moment_wrapper';
|
import { isDateTime } from './moment_wrapper';
|
||||||
|
|
||||||
function convertTableToSeriesData(table: TableData): SeriesData {
|
function convertTableToDataFrame(table: TableData): DataFrame {
|
||||||
return {
|
return {
|
||||||
// rename the 'text' to 'name' field
|
// rename the 'text' to 'name' field
|
||||||
fields: table.columns.map(c => {
|
fields: table.columns.map(c => {
|
||||||
@@ -23,7 +23,7 @@ function convertTableToSeriesData(table: TableData): SeriesData {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function convertTimeSeriesToSeriesData(timeSeries: TimeSeries): SeriesData {
|
function convertTimeSeriesToDataFrame(timeSeries: TimeSeries): DataFrame {
|
||||||
return {
|
return {
|
||||||
name: timeSeries.target,
|
name: timeSeries.target,
|
||||||
fields: [
|
fields: [
|
||||||
@@ -84,7 +84,7 @@ export function guessFieldTypeFromValue(v: any): FieldType {
|
|||||||
/**
|
/**
|
||||||
* Looks at the data to guess the column type. This ignores any existing setting
|
* Looks at the data to guess the column type. This ignores any existing setting
|
||||||
*/
|
*/
|
||||||
export function guessFieldTypeFromSeries(series: SeriesData, index: number): FieldType | undefined {
|
export function guessFieldTypeFromSeries(series: DataFrame, index: number): FieldType | undefined {
|
||||||
const column = series.fields[index];
|
const column = series.fields[index];
|
||||||
|
|
||||||
// 1. Use the column name to guess
|
// 1. Use the column name to guess
|
||||||
@@ -111,7 +111,7 @@ export function guessFieldTypeFromSeries(series: SeriesData, index: number): Fie
|
|||||||
* @returns a copy of the series with the best guess for each field type
|
* @returns a copy of the series with the best guess for each field type
|
||||||
* If the series already has field types defined, they will be used
|
* If the series already has field types defined, they will be used
|
||||||
*/
|
*/
|
||||||
export const guessFieldTypes = (series: SeriesData): SeriesData => {
|
export const guessFieldTypes = (series: DataFrame): DataFrame => {
|
||||||
for (let i = 0; i < series.fields.length; i++) {
|
for (let i = 0; i < series.fields.length; i++) {
|
||||||
if (!series.fields[i].type) {
|
if (!series.fields[i].type) {
|
||||||
// Somethign is missing a type return a modified copy
|
// Somethign is missing a type return a modified copy
|
||||||
@@ -134,26 +134,26 @@ export const guessFieldTypes = (series: SeriesData): SeriesData => {
|
|||||||
return series;
|
return series;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const isTableData = (data: any): data is SeriesData => data && data.hasOwnProperty('columns');
|
export const isTableData = (data: any): data is DataFrame => data && data.hasOwnProperty('columns');
|
||||||
|
|
||||||
export const isSeriesData = (data: any): data is SeriesData => data && data.hasOwnProperty('fields');
|
export const isDataFrame = (data: any): data is DataFrame => data && data.hasOwnProperty('fields');
|
||||||
|
|
||||||
export const toSeriesData = (data: any): SeriesData => {
|
export const toDataFrame = (data: any): DataFrame => {
|
||||||
if (data.hasOwnProperty('fields')) {
|
if (data.hasOwnProperty('fields')) {
|
||||||
return data as SeriesData;
|
return data as DataFrame;
|
||||||
}
|
}
|
||||||
if (data.hasOwnProperty('datapoints')) {
|
if (data.hasOwnProperty('datapoints')) {
|
||||||
return convertTimeSeriesToSeriesData(data);
|
return convertTimeSeriesToDataFrame(data);
|
||||||
}
|
}
|
||||||
if (data.hasOwnProperty('columns')) {
|
if (data.hasOwnProperty('columns')) {
|
||||||
return convertTableToSeriesData(data);
|
return convertTableToDataFrame(data);
|
||||||
}
|
}
|
||||||
// TODO, try to convert JSON/Array to seriesta?
|
// TODO, try to convert JSON/Array to seriesta?
|
||||||
console.warn('Can not convert', data);
|
console.warn('Can not convert', data);
|
||||||
throw new Error('Unsupported data format');
|
throw new Error('Unsupported data format');
|
||||||
};
|
};
|
||||||
|
|
||||||
export const toLegacyResponseData = (series: SeriesData): TimeSeries | TableData => {
|
export const toLegacyResponseData = (series: DataFrame): TimeSeries | TableData => {
|
||||||
const { fields, rows } = series;
|
const { fields, rows } = series;
|
||||||
|
|
||||||
if (fields.length === 2) {
|
if (fields.length === 2) {
|
||||||
@@ -182,7 +182,7 @@ export const toLegacyResponseData = (series: SeriesData): TimeSeries | TableData
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function sortSeriesData(data: SeriesData, sortIndex?: number, reverse = false): SeriesData {
|
export function sortDataFrame(data: DataFrame, sortIndex?: number, reverse = false): DataFrame {
|
||||||
if (isNumber(sortIndex)) {
|
if (isNumber(sortIndex)) {
|
||||||
const copy = {
|
const copy = {
|
||||||
...data,
|
...data,
|
||||||
@@ -6,7 +6,7 @@ import {
|
|||||||
TimeSeries,
|
TimeSeries,
|
||||||
Labels,
|
Labels,
|
||||||
LogLevel,
|
LogLevel,
|
||||||
SeriesData,
|
DataFrame,
|
||||||
findCommonLabels,
|
findCommonLabels,
|
||||||
findUniqueLabels,
|
findUniqueLabels,
|
||||||
getLogLevel,
|
getLogLevel,
|
||||||
@@ -250,15 +250,15 @@ export function makeSeriesForLogs(rows: LogRowModel[], intervalMs: number): Time
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function isLogsData(series: SeriesData) {
|
function isLogsData(series: DataFrame) {
|
||||||
return series.fields.some(f => f.type === FieldType.time) && series.fields.some(f => f.type === FieldType.string);
|
return series.fields.some(f => f.type === FieldType.time) && series.fields.some(f => f.type === FieldType.string);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function seriesDataToLogsModel(seriesData: SeriesData[], intervalMs: number): LogsModel {
|
export function dataFrameToLogsModel(dataFrame: DataFrame[], intervalMs: number): LogsModel {
|
||||||
const metricSeries: SeriesData[] = [];
|
const metricSeries: DataFrame[] = [];
|
||||||
const logSeries: SeriesData[] = [];
|
const logSeries: DataFrame[] = [];
|
||||||
|
|
||||||
for (const series of seriesData) {
|
for (const series of dataFrame) {
|
||||||
if (isLogsData(series)) {
|
if (isLogsData(series)) {
|
||||||
logSeries.push(series);
|
logSeries.push(series);
|
||||||
continue;
|
continue;
|
||||||
@@ -289,7 +289,7 @@ export function seriesDataToLogsModel(seriesData: SeriesData[], intervalMs: numb
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function logSeriesToLogsModel(logSeries: SeriesData[]): LogsModel {
|
export function logSeriesToLogsModel(logSeries: DataFrame[]): LogsModel {
|
||||||
if (logSeries.length === 0) {
|
if (logSeries.length === 0) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
@@ -355,7 +355,7 @@ export function logSeriesToLogsModel(logSeries: SeriesData[]): LogsModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function processLogSeriesRow(
|
export function processLogSeriesRow(
|
||||||
series: SeriesData,
|
series: DataFrame,
|
||||||
fieldCache: FieldCache,
|
fieldCache: FieldCache,
|
||||||
rowIndex: number,
|
rowIndex: number,
|
||||||
uniqueLabels: Labels
|
uniqueLabels: Labels
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { SeriesData, FieldType, LogsModel, LogsMetaKind, LogsDedupStrategy, LogLevel } from '@grafana/ui';
|
import { DataFrame, FieldType, LogsModel, LogsMetaKind, LogsDedupStrategy, LogLevel } from '@grafana/ui';
|
||||||
import {
|
import {
|
||||||
dedupLogRows,
|
dedupLogRows,
|
||||||
calculateFieldStats,
|
calculateFieldStats,
|
||||||
calculateLogsLabelStats,
|
calculateLogsLabelStats,
|
||||||
getParser,
|
getParser,
|
||||||
LogsParsers,
|
LogsParsers,
|
||||||
seriesDataToLogsModel,
|
dataFrameToLogsModel,
|
||||||
} from '../logs_model';
|
} from '../logs_model';
|
||||||
|
|
||||||
describe('dedupLogRows()', () => {
|
describe('dedupLogRows()', () => {
|
||||||
@@ -337,23 +337,23 @@ const emptyLogsModel = {
|
|||||||
series: [],
|
series: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('seriesDataToLogsModel', () => {
|
describe('dataFrameToLogsModel', () => {
|
||||||
it('given empty series should return empty logs model', () => {
|
it('given empty series should return empty logs model', () => {
|
||||||
expect(seriesDataToLogsModel([] as SeriesData[], 0)).toMatchObject(emptyLogsModel);
|
expect(dataFrameToLogsModel([] as DataFrame[], 0)).toMatchObject(emptyLogsModel);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('given series without correct series name should return empty logs model', () => {
|
it('given series without correct series name should return empty logs model', () => {
|
||||||
const series: SeriesData[] = [
|
const series: DataFrame[] = [
|
||||||
{
|
{
|
||||||
fields: [],
|
fields: [],
|
||||||
rows: [],
|
rows: [],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
expect(seriesDataToLogsModel(series, 0)).toMatchObject(emptyLogsModel);
|
expect(dataFrameToLogsModel(series, 0)).toMatchObject(emptyLogsModel);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('given series without a time field should return empty logs model', () => {
|
it('given series without a time field should return empty logs model', () => {
|
||||||
const series: SeriesData[] = [
|
const series: DataFrame[] = [
|
||||||
{
|
{
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
@@ -364,11 +364,11 @@ describe('seriesDataToLogsModel', () => {
|
|||||||
rows: [],
|
rows: [],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
expect(seriesDataToLogsModel(series, 0)).toMatchObject(emptyLogsModel);
|
expect(dataFrameToLogsModel(series, 0)).toMatchObject(emptyLogsModel);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('given series without a string field should return empty logs model', () => {
|
it('given series without a string field should return empty logs model', () => {
|
||||||
const series: SeriesData[] = [
|
const series: DataFrame[] = [
|
||||||
{
|
{
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
@@ -379,11 +379,11 @@ describe('seriesDataToLogsModel', () => {
|
|||||||
rows: [],
|
rows: [],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
expect(seriesDataToLogsModel(series, 0)).toMatchObject(emptyLogsModel);
|
expect(dataFrameToLogsModel(series, 0)).toMatchObject(emptyLogsModel);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('given one series should return expected logs model', () => {
|
it('given one series should return expected logs model', () => {
|
||||||
const series: SeriesData[] = [
|
const series: DataFrame[] = [
|
||||||
{
|
{
|
||||||
labels: {
|
labels: {
|
||||||
filename: '/var/log/grafana/grafana.log',
|
filename: '/var/log/grafana/grafana.log',
|
||||||
@@ -414,7 +414,7 @@ describe('seriesDataToLogsModel', () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
const logsModel = seriesDataToLogsModel(series, 0);
|
const logsModel = dataFrameToLogsModel(series, 0);
|
||||||
expect(logsModel.hasUniqueLabels).toBeFalsy();
|
expect(logsModel.hasUniqueLabels).toBeFalsy();
|
||||||
expect(logsModel.rows).toHaveLength(2);
|
expect(logsModel.rows).toHaveLength(2);
|
||||||
expect(logsModel.rows).toMatchObject([
|
expect(logsModel.rows).toMatchObject([
|
||||||
@@ -449,7 +449,7 @@ describe('seriesDataToLogsModel', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('given one series without labels should return expected logs model', () => {
|
it('given one series without labels should return expected logs model', () => {
|
||||||
const series: SeriesData[] = [
|
const series: DataFrame[] = [
|
||||||
{
|
{
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
@@ -468,7 +468,7 @@ describe('seriesDataToLogsModel', () => {
|
|||||||
rows: [['1970-01-01T00:00:01Z', 'WARN boooo', 'dbug']],
|
rows: [['1970-01-01T00:00:01Z', 'WARN boooo', 'dbug']],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
const logsModel = seriesDataToLogsModel(series, 0);
|
const logsModel = dataFrameToLogsModel(series, 0);
|
||||||
expect(logsModel.rows).toHaveLength(1);
|
expect(logsModel.rows).toHaveLength(1);
|
||||||
expect(logsModel.rows).toMatchObject([
|
expect(logsModel.rows).toMatchObject([
|
||||||
{
|
{
|
||||||
@@ -481,7 +481,7 @@ describe('seriesDataToLogsModel', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('given multiple series should return expected logs model', () => {
|
it('given multiple series should return expected logs model', () => {
|
||||||
const series: SeriesData[] = [
|
const series: DataFrame[] = [
|
||||||
{
|
{
|
||||||
labels: {
|
labels: {
|
||||||
foo: 'bar',
|
foo: 'bar',
|
||||||
@@ -520,7 +520,7 @@ describe('seriesDataToLogsModel', () => {
|
|||||||
rows: [['1970-01-01T00:00:00Z', 'INFO 1'], ['1970-01-01T00:00:02Z', 'INFO 2']],
|
rows: [['1970-01-01T00:00:00Z', 'INFO 1'], ['1970-01-01T00:00:02Z', 'INFO 2']],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
const logsModel = seriesDataToLogsModel(series, 0);
|
const logsModel = dataFrameToLogsModel(series, 0);
|
||||||
expect(logsModel.hasUniqueLabels).toBeTruthy();
|
expect(logsModel.hasUniqueLabels).toBeTruthy();
|
||||||
expect(logsModel.rows).toHaveLength(3);
|
expect(logsModel.rows).toHaveLength(3);
|
||||||
expect(logsModel.rows).toMatchObject([
|
expect(logsModel.rows).toMatchObject([
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import ErrorBoundary from 'app/core/components/ErrorBoundary/ErrorBoundary';
|
|||||||
import { getTimeSrv, TimeSrv } from '../services/TimeSrv';
|
import { getTimeSrv, TimeSrv } from '../services/TimeSrv';
|
||||||
import { applyPanelTimeOverrides, calculateInnerPanelHeight } from 'app/features/dashboard/utils/panel';
|
import { applyPanelTimeOverrides, calculateInnerPanelHeight } from 'app/features/dashboard/utils/panel';
|
||||||
import { profiler } from 'app/core/profiler';
|
import { profiler } from 'app/core/profiler';
|
||||||
import { getProcessedSeriesData } from '../state/PanelQueryState';
|
import { getProcessedDataFrame } from '../state/PanelQueryState';
|
||||||
import templateSrv from 'app/features/templating/template_srv';
|
import templateSrv from 'app/features/templating/template_srv';
|
||||||
import config from 'app/core/config';
|
import config from 'app/core/config';
|
||||||
|
|
||||||
@@ -71,7 +71,7 @@ export class PanelChrome extends PureComponent<Props, State> {
|
|||||||
this.setState({
|
this.setState({
|
||||||
data: {
|
data: {
|
||||||
state: LoadingState.Done,
|
state: LoadingState.Done,
|
||||||
series: getProcessedSeriesData(panel.snapshotData),
|
series: getProcessedDataFrame(panel.snapshotData),
|
||||||
},
|
},
|
||||||
isFirstLoad: false,
|
isFirstLoad: false,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { toDataQueryError, PanelQueryState, getProcessedSeriesData } from './PanelQueryState';
|
import { toDataQueryError, PanelQueryState, getProcessedDataFrame } from './PanelQueryState';
|
||||||
import { MockDataSourceApi } from 'test/mocks/datasource_srv';
|
import { MockDataSourceApi } from 'test/mocks/datasource_srv';
|
||||||
import { DataQueryResponse, LoadingState } from '@grafana/ui';
|
import { DataQueryResponse, LoadingState } from '@grafana/ui';
|
||||||
import { getQueryOptions } from 'test/helpers/getQueryOptions';
|
import { getQueryOptions } from 'test/helpers/getQueryOptions';
|
||||||
@@ -53,7 +53,7 @@ describe('PanelQueryState', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getProcessedSeriesData', () => {
|
describe('getProcessedDataFrame', () => {
|
||||||
it('converts timeseries to table skipping nulls', () => {
|
it('converts timeseries to table skipping nulls', () => {
|
||||||
const input1 = {
|
const input1 = {
|
||||||
target: 'Field Name',
|
target: 'Field Name',
|
||||||
@@ -64,7 +64,7 @@ describe('getProcessedSeriesData', () => {
|
|||||||
target: '',
|
target: '',
|
||||||
datapoints: [[100, 1], [200, 2]],
|
datapoints: [[100, 1], [200, 2]],
|
||||||
};
|
};
|
||||||
const data = getProcessedSeriesData([null, input1, input2, null, null]);
|
const data = getProcessedDataFrame([null, input1, input2, null, null]);
|
||||||
expect(data.length).toBe(2);
|
expect(data.length).toBe(2);
|
||||||
expect(data[0].fields[0].name).toBe(input1.target);
|
expect(data[0].fields[0].name).toBe(input1.target);
|
||||||
expect(data[0].rows).toBe(input1.datapoints);
|
expect(data[0].rows).toBe(input1.datapoints);
|
||||||
@@ -82,10 +82,10 @@ describe('getProcessedSeriesData', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('supports null values from query OK', () => {
|
it('supports null values from query OK', () => {
|
||||||
expect(getProcessedSeriesData([null, null, null, null])).toEqual([]);
|
expect(getProcessedDataFrame([null, null, null, null])).toEqual([]);
|
||||||
expect(getProcessedSeriesData(undefined)).toEqual([]);
|
expect(getProcessedDataFrame(undefined)).toEqual([]);
|
||||||
expect(getProcessedSeriesData((null as unknown) as any[])).toEqual([]);
|
expect(getProcessedDataFrame((null as unknown) as any[])).toEqual([]);
|
||||||
expect(getProcessedSeriesData([])).toEqual([]);
|
expect(getProcessedDataFrame([])).toEqual([]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import isEqual from 'lodash/isEqual';
|
|||||||
// Utils & Services
|
// Utils & Services
|
||||||
import { getBackendSrv } from 'app/core/services/backend_srv';
|
import { getBackendSrv } from 'app/core/services/backend_srv';
|
||||||
import * as dateMath from '@grafana/ui/src/utils/datemath';
|
import * as dateMath from '@grafana/ui/src/utils/datemath';
|
||||||
import { guessFieldTypes, toSeriesData, isSeriesData } from '@grafana/ui/src/utils';
|
import { guessFieldTypes, toDataFrame, isDataFrame } from '@grafana/ui/src/utils';
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import {
|
import {
|
||||||
@@ -17,7 +17,7 @@ import {
|
|||||||
DataQueryError,
|
DataQueryError,
|
||||||
DataStreamObserver,
|
DataStreamObserver,
|
||||||
DataStreamState,
|
DataStreamState,
|
||||||
SeriesData,
|
DataFrame,
|
||||||
DataQueryResponseData,
|
DataQueryResponseData,
|
||||||
} from '@grafana/ui';
|
} from '@grafana/ui';
|
||||||
|
|
||||||
@@ -131,7 +131,7 @@ export class PanelQueryState {
|
|||||||
this.response = {
|
this.response = {
|
||||||
state: LoadingState.Done,
|
state: LoadingState.Done,
|
||||||
request: this.request,
|
request: this.request,
|
||||||
series: this.sendSeries ? getProcessedSeriesData(resp.data) : [],
|
series: this.sendSeries ? getProcessedDataFrame(resp.data) : [],
|
||||||
legacy: this.sendLegacy ? translateToLegacyData(resp.data) : undefined,
|
legacy: this.sendLegacy ? translateToLegacyData(resp.data) : undefined,
|
||||||
};
|
};
|
||||||
resolve(this.validateStreamsAndGetPanelData());
|
resolve(this.validateStreamsAndGetPanelData());
|
||||||
@@ -182,7 +182,7 @@ export class PanelQueryState {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const series: SeriesData[] = [];
|
const series: DataFrame[] = [];
|
||||||
|
|
||||||
for (const stream of this.streams) {
|
for (const stream of this.streams) {
|
||||||
if (stream.series) {
|
if (stream.series) {
|
||||||
@@ -278,7 +278,7 @@ export class PanelQueryState {
|
|||||||
response.legacy = response.series.map(v => toLegacyResponseData(v));
|
response.legacy = response.series.map(v => toLegacyResponseData(v));
|
||||||
}
|
}
|
||||||
if (sendSeries && !response.series.length && response.legacy) {
|
if (sendSeries && !response.series.length && response.legacy) {
|
||||||
response.series = response.legacy.map(v => toSeriesData(v));
|
response.series = response.legacy.map(v => toDataFrame(v));
|
||||||
}
|
}
|
||||||
return this.validateStreamsAndGetPanelData();
|
return this.validateStreamsAndGetPanelData();
|
||||||
}
|
}
|
||||||
@@ -333,7 +333,7 @@ export function toDataQueryError(err: any): DataQueryError {
|
|||||||
|
|
||||||
function translateToLegacyData(data: DataQueryResponseData) {
|
function translateToLegacyData(data: DataQueryResponseData) {
|
||||||
return data.map(v => {
|
return data.map(v => {
|
||||||
if (isSeriesData(v)) {
|
if (isDataFrame(v)) {
|
||||||
return toLegacyResponseData(v);
|
return toLegacyResponseData(v);
|
||||||
}
|
}
|
||||||
return v;
|
return v;
|
||||||
@@ -345,15 +345,15 @@ function translateToLegacyData(data: DataQueryResponseData) {
|
|||||||
*
|
*
|
||||||
* This is also used by PanelChrome for snapshot support
|
* This is also used by PanelChrome for snapshot support
|
||||||
*/
|
*/
|
||||||
export function getProcessedSeriesData(results?: any[]): SeriesData[] {
|
export function getProcessedDataFrame(results?: any[]): DataFrame[] {
|
||||||
if (!results) {
|
if (!results) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const series: SeriesData[] = [];
|
const series: DataFrame[] = [];
|
||||||
for (const r of results) {
|
for (const r of results) {
|
||||||
if (r) {
|
if (r) {
|
||||||
series.push(guessFieldTypes(toSeriesData(r)));
|
series.push(guessFieldTypes(toDataFrame(r)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -213,7 +213,7 @@ export class Graph extends PureComponent<GraphProps, GraphState> {
|
|||||||
// This implementation is more or less a copy of GraphPanel's logic.
|
// This implementation is more or less a copy of GraphPanel's logic.
|
||||||
// TODO: we need to use Graph's panel controller or split it into smaller
|
// TODO: we need to use Graph's panel controller or split it into smaller
|
||||||
// controllers to remove code duplication. Right now we cant easily use that, since Explore
|
// controllers to remove code duplication. Right now we cant easily use that, since Explore
|
||||||
// is not using SeriesData for graph yet
|
// is not using DataFrame for graph yet
|
||||||
|
|
||||||
const exclusive = event.ctrlKey || event.metaKey || event.shiftKey;
|
const exclusive = event.ctrlKey || event.metaKey || event.shiftKey;
|
||||||
|
|
||||||
|
|||||||
@@ -197,7 +197,7 @@ function mapStateToProps(state: StoreState, { exploreId, index }: QueryRowProps)
|
|||||||
const query = queries[index];
|
const query = queries[index];
|
||||||
const datasourceStatus = datasourceError ? DataSourceStatus.Disconnected : DataSourceStatus.Connected;
|
const datasourceStatus = datasourceError ? DataSourceStatus.Disconnected : DataSourceStatus.Connected;
|
||||||
const error = queryErrors.filter(queryError => queryError.refId === query.refId)[0];
|
const error = queryErrors.filter(queryError => queryError.refId === query.refId)[0];
|
||||||
const series = graphResult ? graphResult : []; // TODO: use SeriesData
|
const series = graphResult ? graphResult : []; // TODO: use DataFrame
|
||||||
const queryResponse: PanelData = {
|
const queryResponse: PanelData = {
|
||||||
series,
|
series,
|
||||||
state: loadingState,
|
state: loadingState,
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import {
|
|||||||
LogLevel,
|
LogLevel,
|
||||||
TimeRange,
|
TimeRange,
|
||||||
DataQueryError,
|
DataQueryError,
|
||||||
SeriesData,
|
DataFrame,
|
||||||
LogsModel,
|
LogsModel,
|
||||||
TimeSeries,
|
TimeSeries,
|
||||||
DataQueryResponseData,
|
DataQueryResponseData,
|
||||||
@@ -239,7 +239,7 @@ export interface ProcessQueryResultsPayload {
|
|||||||
datasourceId: string;
|
datasourceId: string;
|
||||||
loadingState: LoadingState;
|
loadingState: LoadingState;
|
||||||
series?: DataQueryResponseData[];
|
series?: DataQueryResponseData[];
|
||||||
delta?: SeriesData[];
|
delta?: DataFrame[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RunQueriesBatchPayload {
|
export interface RunQueriesBatchPayload {
|
||||||
@@ -248,7 +248,7 @@ export interface RunQueriesBatchPayload {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface LimitMessageRatePayload {
|
export interface LimitMessageRatePayload {
|
||||||
series: SeriesData[];
|
series: DataFrame[];
|
||||||
exploreId: ExploreId;
|
exploreId: ExploreId;
|
||||||
datasourceId: string;
|
datasourceId: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,17 +8,17 @@ import {
|
|||||||
updateTimeRangeAction,
|
updateTimeRangeAction,
|
||||||
runQueriesAction,
|
runQueriesAction,
|
||||||
} from '../actionTypes';
|
} from '../actionTypes';
|
||||||
import { SeriesData, LoadingState } from '@grafana/ui';
|
import { DataFrame, LoadingState } from '@grafana/ui';
|
||||||
import { processQueryResultsEpic } from './processQueryResultsEpic';
|
import { processQueryResultsEpic } from './processQueryResultsEpic';
|
||||||
import TableModel from 'app/core/table_model';
|
import TableModel from 'app/core/table_model';
|
||||||
|
|
||||||
const testContext = () => {
|
const testContext = () => {
|
||||||
const serieA: SeriesData = {
|
const serieA: DataFrame = {
|
||||||
fields: [],
|
fields: [],
|
||||||
refId: 'A',
|
refId: 'A',
|
||||||
rows: [],
|
rows: [],
|
||||||
};
|
};
|
||||||
const serieB: SeriesData = {
|
const serieB: DataFrame = {
|
||||||
fields: [],
|
fields: [],
|
||||||
refId: 'B',
|
refId: 'B',
|
||||||
rows: [],
|
rows: [],
|
||||||
|
|||||||
@@ -14,10 +14,10 @@ import {
|
|||||||
clearQueriesAction,
|
clearQueriesAction,
|
||||||
stateSaveAction,
|
stateSaveAction,
|
||||||
} from '../actionTypes';
|
} from '../actionTypes';
|
||||||
import { LoadingState, DataQueryRequest, SeriesData, FieldType } from '@grafana/ui';
|
import { LoadingState, DataQueryRequest, DataFrame, FieldType } from '@grafana/ui';
|
||||||
|
|
||||||
const testContext = () => {
|
const testContext = () => {
|
||||||
const series: SeriesData[] = [
|
const series: DataFrame[] = [
|
||||||
{
|
{
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import {
|
|||||||
DataStreamState,
|
DataStreamState,
|
||||||
LoadingState,
|
LoadingState,
|
||||||
DataQueryResponse,
|
DataQueryResponse,
|
||||||
SeriesData,
|
DataFrame,
|
||||||
DataQueryResponseData,
|
DataQueryResponseData,
|
||||||
AbsoluteTimeRange,
|
AbsoluteTimeRange,
|
||||||
} from '@grafana/ui';
|
} from '@grafana/ui';
|
||||||
@@ -46,7 +46,7 @@ interface ProcessResponseConfig {
|
|||||||
now: number;
|
now: number;
|
||||||
loadingState: LoadingState;
|
loadingState: LoadingState;
|
||||||
series?: DataQueryResponseData[];
|
series?: DataQueryResponseData[];
|
||||||
delta?: SeriesData[];
|
delta?: DataFrame[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const processResponse = (config: ProcessResponseConfig) => {
|
const processResponse = (config: ProcessResponseConfig) => {
|
||||||
|
|||||||
@@ -3,17 +3,17 @@ import {
|
|||||||
TableData,
|
TableData,
|
||||||
isTableData,
|
isTableData,
|
||||||
LogsModel,
|
LogsModel,
|
||||||
toSeriesData,
|
toDataFrame,
|
||||||
guessFieldTypes,
|
guessFieldTypes,
|
||||||
DataQueryResponseData,
|
DataQueryResponseData,
|
||||||
TimeSeries,
|
TimeSeries,
|
||||||
} from '@grafana/ui';
|
} from '@grafana/ui';
|
||||||
|
|
||||||
import { ExploreItemState, ExploreMode } from 'app/types/explore';
|
import { ExploreItemState, ExploreMode } from 'app/types/explore';
|
||||||
import { getProcessedSeriesData } from 'app/features/dashboard/state/PanelQueryState';
|
import { getProcessedDataFrame } from 'app/features/dashboard/state/PanelQueryState';
|
||||||
import TableModel, { mergeTablesIntoModel } from 'app/core/table_model';
|
import TableModel, { mergeTablesIntoModel } from 'app/core/table_model';
|
||||||
import { sortLogsResult } from 'app/core/utils/explore';
|
import { sortLogsResult } from 'app/core/utils/explore';
|
||||||
import { seriesDataToLogsModel } from 'app/core/logs_model';
|
import { dataFrameToLogsModel } from 'app/core/logs_model';
|
||||||
import { default as TimeSeries2 } from 'app/core/time_series2';
|
import { default as TimeSeries2 } from 'app/core/time_series2';
|
||||||
import { DataProcessor } from 'app/plugins/panel/graph/data_processor';
|
import { DataProcessor } from 'app/plugins/panel/graph/data_processor';
|
||||||
|
|
||||||
@@ -77,8 +77,8 @@ export class ResultProcessor {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const graphInterval = this.state.queryIntervals.intervalMs;
|
const graphInterval = this.state.queryIntervals.intervalMs;
|
||||||
const seriesData = this.rawData.map(result => guessFieldTypes(toSeriesData(result)));
|
const dataFrame = this.rawData.map(result => guessFieldTypes(toDataFrame(result)));
|
||||||
const newResults = this.rawData ? seriesDataToLogsModel(seriesData, graphInterval) : null;
|
const newResults = this.rawData ? dataFrameToLogsModel(dataFrame, graphInterval) : null;
|
||||||
|
|
||||||
if (this.replacePreviousResults) {
|
if (this.replacePreviousResults) {
|
||||||
return newResults;
|
return newResults;
|
||||||
@@ -107,7 +107,7 @@ export class ResultProcessor {
|
|||||||
};
|
};
|
||||||
|
|
||||||
private makeTimeSeriesList = (rawData: any[]) => {
|
private makeTimeSeriesList = (rawData: any[]) => {
|
||||||
const dataList = getProcessedSeriesData(rawData);
|
const dataList = getProcessedDataFrame(rawData);
|
||||||
const dataProcessor = new DataProcessor({ xaxis: {}, aliasColors: [] }); // Hack before we use GraphSeriesXY instead
|
const dataProcessor = new DataProcessor({ xaxis: {}, aliasColors: [] }); // Hack before we use GraphSeriesXY instead
|
||||||
const timeSeries = dataProcessor.getSeriesList({ dataList });
|
const timeSeries = dataProcessor.getSeriesList({ dataList });
|
||||||
|
|
||||||
|
|||||||
@@ -8,14 +8,14 @@ import { applyPanelTimeOverrides, getResolution } from 'app/features/dashboard/u
|
|||||||
import { ContextSrv } from 'app/core/services/context_srv';
|
import { ContextSrv } from 'app/core/services/context_srv';
|
||||||
import {
|
import {
|
||||||
toLegacyResponseData,
|
toLegacyResponseData,
|
||||||
isSeriesData,
|
isDataFrame,
|
||||||
LegacyResponseData,
|
LegacyResponseData,
|
||||||
TimeRange,
|
TimeRange,
|
||||||
DataSourceApi,
|
DataSourceApi,
|
||||||
PanelData,
|
PanelData,
|
||||||
LoadingState,
|
LoadingState,
|
||||||
DataQueryResponse,
|
DataQueryResponse,
|
||||||
SeriesData,
|
DataFrame,
|
||||||
} from '@grafana/ui';
|
} from '@grafana/ui';
|
||||||
import { Unsubscribable } from 'rxjs';
|
import { Unsubscribable } from 'rxjs';
|
||||||
import { PanelModel } from 'app/features/dashboard/state';
|
import { PanelModel } from 'app/features/dashboard/state';
|
||||||
@@ -150,7 +150,7 @@ class MetricsPanelCtrl extends PanelCtrl {
|
|||||||
// The result should already be processed, but just in case
|
// The result should already be processed, but just in case
|
||||||
if (!data.legacy) {
|
if (!data.legacy) {
|
||||||
data.legacy = data.series.map(v => {
|
data.legacy = data.series.map(v => {
|
||||||
if (isSeriesData(v)) {
|
if (isDataFrame(v)) {
|
||||||
return toLegacyResponseData(v);
|
return toLegacyResponseData(v);
|
||||||
}
|
}
|
||||||
return v;
|
return v;
|
||||||
@@ -163,7 +163,7 @@ class MetricsPanelCtrl extends PanelCtrl {
|
|||||||
data: data.legacy,
|
data: data.legacy,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.handleSeriesData(data.series);
|
this.handleDataFrame(data.series);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -222,14 +222,14 @@ class MetricsPanelCtrl extends PanelCtrl {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleSeriesData(data: SeriesData[]) {
|
handleDataFrame(data: DataFrame[]) {
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
|
|
||||||
if (this.dashboard && this.dashboard.snapshot) {
|
if (this.dashboard && this.dashboard.snapshot) {
|
||||||
this.panel.snapshotData = data;
|
this.panel.snapshotData = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Subclasses that asked for SeriesData will override
|
// Subclasses that asked for DataFrame will override
|
||||||
}
|
}
|
||||||
|
|
||||||
handleQueryResult(result: DataQueryResponse) {
|
handleQueryResult(result: DataQueryResponse) {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import _ from 'lodash';
|
|||||||
import flatten from 'app/core/utils/flatten';
|
import flatten from 'app/core/utils/flatten';
|
||||||
import * as queryDef from './query_def';
|
import * as queryDef from './query_def';
|
||||||
import TableModel from 'app/core/table_model';
|
import TableModel from 'app/core/table_model';
|
||||||
import { SeriesData, DataQueryResponse, toSeriesData, FieldType } from '@grafana/ui';
|
import { DataFrame, DataQueryResponse, toDataFrame, FieldType } from '@grafana/ui';
|
||||||
|
|
||||||
export class ElasticResponse {
|
export class ElasticResponse {
|
||||||
constructor(private targets, private response) {
|
constructor(private targets, private response) {
|
||||||
@@ -414,7 +414,7 @@ export class ElasticResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getLogs(logMessageField?: string, logLevelField?: string): DataQueryResponse {
|
getLogs(logMessageField?: string, logLevelField?: string): DataQueryResponse {
|
||||||
const seriesData: SeriesData[] = [];
|
const dataFrame: DataFrame[] = [];
|
||||||
const docs: any[] = [];
|
const docs: any[] = [];
|
||||||
|
|
||||||
for (let n = 0; n < this.response.responses.length; n++) {
|
for (let n = 0; n < this.response.responses.length; n++) {
|
||||||
@@ -462,7 +462,7 @@ export class ElasticResponse {
|
|||||||
|
|
||||||
if (docs.length > 0) {
|
if (docs.length > 0) {
|
||||||
propNames = propNames.sort();
|
propNames = propNames.sort();
|
||||||
const series: SeriesData = {
|
const series: DataFrame = {
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: this.targets[0].timeField,
|
name: this.targets[0].timeField,
|
||||||
@@ -527,7 +527,7 @@ export class ElasticResponse {
|
|||||||
series.rows.push(row);
|
series.rows.push(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
seriesData.push(series);
|
dataFrame.push(series);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response.aggregations) {
|
if (response.aggregations) {
|
||||||
@@ -541,13 +541,13 @@ export class ElasticResponse {
|
|||||||
this.nameSeries(tmpSeriesList, target);
|
this.nameSeries(tmpSeriesList, target);
|
||||||
|
|
||||||
for (let y = 0; y < tmpSeriesList.length; y++) {
|
for (let y = 0; y < tmpSeriesList.length; y++) {
|
||||||
const series = toSeriesData(tmpSeriesList[y]);
|
const series = toDataFrame(tmpSeriesList[y]);
|
||||||
series.labels = {};
|
series.labels = {};
|
||||||
seriesData.push(series);
|
dataFrame.push(series);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return { data: seriesData };
|
return { data: dataFrame };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-5
@@ -80,15 +80,15 @@ export default class ResponseParser {
|
|||||||
return id.substring(startIndex, endIndex);
|
return id.substring(startIndex, endIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static convertDataToPoints(timeSeriesData) {
|
static convertDataToPoints(timeDataFrame) {
|
||||||
const dataPoints: any[] = [];
|
const dataPoints: any[] = [];
|
||||||
|
|
||||||
for (let k = 0; k < timeSeriesData.length; k++) {
|
for (let k = 0; k < timeDataFrame.length; k++) {
|
||||||
const epoch = ResponseParser.dateTimeToEpoch(timeSeriesData[k].timeStamp);
|
const epoch = ResponseParser.dateTimeToEpoch(timeDataFrame[k].timeStamp);
|
||||||
const aggKey = ResponseParser.getKeyForAggregationField(timeSeriesData[k]);
|
const aggKey = ResponseParser.getKeyForAggregationField(timeDataFrame[k]);
|
||||||
|
|
||||||
if (aggKey) {
|
if (aggKey) {
|
||||||
dataPoints.push([timeSeriesData[k][aggKey], epoch]);
|
dataPoints.push([timeDataFrame[k][aggKey], epoch]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import './editor/editor_component';
|
|||||||
|
|
||||||
import { TemplateSrv } from 'app/features/templating/template_srv';
|
import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||||
import { auto } from 'angular';
|
import { auto } from 'angular';
|
||||||
import { SeriesData } from '@grafana/ui';
|
import { DataFrame } from '@grafana/ui';
|
||||||
|
|
||||||
export interface ResultFormat {
|
export interface ResultFormat {
|
||||||
text: string;
|
text: string;
|
||||||
@@ -125,7 +125,7 @@ export class AzureMonitorQueryCtrl extends QueryCtrl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onDataReceived(dataList: SeriesData[]) {
|
onDataReceived(dataList: DataFrame[]) {
|
||||||
this.lastQueryError = undefined;
|
this.lastQueryError = undefined;
|
||||||
this.lastQuery = '';
|
this.lastQuery = '';
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import React, { PureComponent } from 'react';
|
|||||||
// Types
|
// Types
|
||||||
import { InputOptions } from './types';
|
import { InputOptions } from './types';
|
||||||
|
|
||||||
import { DataSourcePluginOptionsEditorProps, DataSourceSettings, SeriesData, TableInputCSV, toCSV } from '@grafana/ui';
|
import { DataSourcePluginOptionsEditorProps, DataSourceSettings, DataFrame, TableInputCSV, toCSV } from '@grafana/ui';
|
||||||
|
|
||||||
type InputSettings = DataSourceSettings<InputOptions>;
|
type InputSettings = DataSourceSettings<InputOptions>;
|
||||||
|
|
||||||
@@ -27,7 +27,7 @@ export class InputConfigEditor extends PureComponent<Props, State> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onSeriesParsed = (data: SeriesData[], text: string) => {
|
onSeriesParsed = (data: DataFrame[], text: string) => {
|
||||||
const { options, onOptionsChange } = this.props;
|
const { options, onOptionsChange } = this.props;
|
||||||
if (!data) {
|
if (!data) {
|
||||||
data = [
|
data = [
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import InputDatasource, { describeSeriesData } from './InputDatasource';
|
import InputDatasource, { describeDataFrame } from './InputDatasource';
|
||||||
import { InputQuery, InputOptions } from './types';
|
import { InputQuery, InputOptions } from './types';
|
||||||
import { readCSV, DataSourceInstanceSettings, PluginMeta } from '@grafana/ui';
|
import { readCSV, DataSourceInstanceSettings, PluginMeta } from '@grafana/ui';
|
||||||
import { getQueryOptions } from 'test/helpers/getQueryOptions';
|
import { getQueryOptions } from 'test/helpers/getQueryOptions';
|
||||||
@@ -32,11 +32,11 @@ describe('InputDatasource', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('SeriesData descriptions', () => {
|
test('DataFrame descriptions', () => {
|
||||||
expect(describeSeriesData([])).toEqual('');
|
expect(describeDataFrame([])).toEqual('');
|
||||||
expect(describeSeriesData(null)).toEqual('');
|
expect(describeDataFrame(null)).toEqual('');
|
||||||
expect(
|
expect(
|
||||||
describeSeriesData([
|
describeDataFrame([
|
||||||
{
|
{
|
||||||
name: 'x',
|
name: 'x',
|
||||||
fields: [{ name: 'a' }],
|
fields: [{ name: 'a' }],
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Types
|
// Types
|
||||||
import {
|
import {
|
||||||
DataQueryRequest,
|
DataQueryRequest,
|
||||||
SeriesData,
|
DataFrame,
|
||||||
DataQueryResponse,
|
DataQueryResponse,
|
||||||
DataSourceApi,
|
DataSourceApi,
|
||||||
DataSourceInstanceSettings,
|
DataSourceInstanceSettings,
|
||||||
@@ -10,7 +10,7 @@ import {
|
|||||||
import { InputQuery, InputOptions } from './types';
|
import { InputQuery, InputOptions } from './types';
|
||||||
|
|
||||||
export class InputDatasource extends DataSourceApi<InputQuery, InputOptions> {
|
export class InputDatasource extends DataSourceApi<InputQuery, InputOptions> {
|
||||||
data: SeriesData[];
|
data: DataFrame[];
|
||||||
|
|
||||||
constructor(instanceSettings: DataSourceInstanceSettings<InputOptions>) {
|
constructor(instanceSettings: DataSourceInstanceSettings<InputOptions>) {
|
||||||
super(instanceSettings);
|
super(instanceSettings);
|
||||||
@@ -23,9 +23,9 @@ export class InputDatasource extends DataSourceApi<InputQuery, InputOptions> {
|
|||||||
*/
|
*/
|
||||||
getQueryDisplayText(query: InputQuery): string {
|
getQueryDisplayText(query: InputQuery): string {
|
||||||
if (query.data) {
|
if (query.data) {
|
||||||
return 'Panel Data: ' + describeSeriesData(query.data);
|
return 'Panel Data: ' + describeDataFrame(query.data);
|
||||||
}
|
}
|
||||||
return `Shared Data From: ${this.name} (${describeSeriesData(this.data)})`;
|
return `Shared Data From: ${this.name} (${describeDataFrame(this.data)})`;
|
||||||
}
|
}
|
||||||
|
|
||||||
metricFindQuery(query: string, options?: any): Promise<MetricFindValue[]> {
|
metricFindQuery(query: string, options?: any): Promise<MetricFindValue[]> {
|
||||||
@@ -44,7 +44,7 @@ export class InputDatasource extends DataSourceApi<InputQuery, InputOptions> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
query(options: DataQueryRequest<InputQuery>): Promise<DataQueryResponse> {
|
query(options: DataQueryRequest<InputQuery>): Promise<DataQueryResponse> {
|
||||||
const results: SeriesData[] = [];
|
const results: DataFrame[] = [];
|
||||||
for (const query of options.targets) {
|
for (const query of options.targets) {
|
||||||
if (query.hide) {
|
if (query.hide) {
|
||||||
continue;
|
continue;
|
||||||
@@ -83,7 +83,7 @@ export class InputDatasource extends DataSourceApi<InputQuery, InputOptions> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function describeSeriesData(data: SeriesData[]): string {
|
export function describeDataFrame(data: DataFrame[]): string {
|
||||||
if (!data || !data.length) {
|
if (!data || !data.length) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
import React, { PureComponent } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import { InputDatasource, describeSeriesData } from './InputDatasource';
|
import { InputDatasource, describeDataFrame } from './InputDatasource';
|
||||||
import { InputQuery, InputOptions } from './types';
|
import { InputQuery, InputOptions } from './types';
|
||||||
|
|
||||||
import { FormLabel, Select, QueryEditorProps, SelectOptionItem, SeriesData, TableInputCSV, toCSV } from '@grafana/ui';
|
import { FormLabel, Select, QueryEditorProps, SelectOptionItem, DataFrame, TableInputCSV, toCSV } from '@grafana/ui';
|
||||||
|
|
||||||
type Props = QueryEditorProps<InputDatasource, InputQuery, InputOptions>;
|
type Props = QueryEditorProps<InputDatasource, InputQuery, InputOptions>;
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ export class InputQueryEditor extends PureComponent<Props, State> {
|
|||||||
|
|
||||||
onSourceChange = (item: SelectOptionItem<string>) => {
|
onSourceChange = (item: SelectOptionItem<string>) => {
|
||||||
const { datasource, query, onChange, onRunQuery } = this.props;
|
const { datasource, query, onChange, onRunQuery } = this.props;
|
||||||
let data: SeriesData[] | undefined = undefined;
|
let data: DataFrame[] | undefined = undefined;
|
||||||
if (item.value === 'panel') {
|
if (item.value === 'panel') {
|
||||||
if (query.data) {
|
if (query.data) {
|
||||||
return;
|
return;
|
||||||
@@ -51,7 +51,7 @@ export class InputQueryEditor extends PureComponent<Props, State> {
|
|||||||
onRunQuery();
|
onRunQuery();
|
||||||
};
|
};
|
||||||
|
|
||||||
onSeriesParsed = (data: SeriesData[], text: string) => {
|
onSeriesParsed = (data: DataFrame[], text: string) => {
|
||||||
const { query, onChange, onRunQuery } = this.props;
|
const { query, onChange, onRunQuery } = this.props;
|
||||||
this.setState({ text });
|
this.setState({ text });
|
||||||
if (!data) {
|
if (!data) {
|
||||||
@@ -80,10 +80,10 @@ export class InputQueryEditor extends PureComponent<Props, State> {
|
|||||||
|
|
||||||
<div className="btn btn-link">
|
<div className="btn btn-link">
|
||||||
{query.data ? (
|
{query.data ? (
|
||||||
describeSeriesData(query.data)
|
describeDataFrame(query.data)
|
||||||
) : (
|
) : (
|
||||||
<a href={`datasources/edit/${id}/`}>
|
<a href={`datasources/edit/${id}/`}>
|
||||||
{name}: {describeSeriesData(datasource.data)}
|
{name}: {describeDataFrame(datasource.data)}
|
||||||
<i className="fa fa-pencil-square-o" />
|
<i className="fa fa-pencil-square-o" />
|
||||||
</a>
|
</a>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { DataQuery, SeriesData, DataSourceJsonData } from '@grafana/ui/src/types';
|
import { DataQuery, DataFrame, DataSourceJsonData } from '@grafana/ui/src/types';
|
||||||
|
|
||||||
export interface InputQuery extends DataQuery {
|
export interface InputQuery extends DataQuery {
|
||||||
// Data saved in the panel
|
// Data saved in the panel
|
||||||
data?: SeriesData[];
|
data?: DataFrame[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface InputOptions extends DataSourceJsonData {
|
export interface InputOptions extends DataSourceJsonData {
|
||||||
// Saved in the datasource and download with bootData
|
// Saved in the datasource and download with bootData
|
||||||
data?: SeriesData[];
|
data?: DataFrame[];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import LokiDatasource from './datasource';
|
import LokiDatasource from './datasource';
|
||||||
import { LokiQuery } from './types';
|
import { LokiQuery } from './types';
|
||||||
import { getQueryOptions } from 'test/helpers/getQueryOptions';
|
import { getQueryOptions } from 'test/helpers/getQueryOptions';
|
||||||
import { SeriesData, DataSourceApi } from '@grafana/ui';
|
import { DataFrame, DataSourceApi } from '@grafana/ui';
|
||||||
import { BackendSrv } from 'app/core/services/backend_srv';
|
import { BackendSrv } from 'app/core/services/backend_srv';
|
||||||
import { TemplateSrv } from 'app/features/templating/template_srv';
|
import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||||
|
|
||||||
@@ -66,10 +66,10 @@ describe('LokiDatasource', () => {
|
|||||||
|
|
||||||
const res = await ds.query(options);
|
const res = await ds.query(options);
|
||||||
|
|
||||||
const seriesData = res.data[0] as SeriesData;
|
const dataFrame = res.data[0] as DataFrame;
|
||||||
expect(seriesData.rows[0][1]).toBe('hello');
|
expect(dataFrame.rows[0][1]).toBe('hello');
|
||||||
expect(seriesData.meta.limit).toBe(20);
|
expect(dataFrame.meta.limit).toBe(20);
|
||||||
expect(seriesData.meta.searchWords).toEqual(['(?i)foo']);
|
expect(dataFrame.meta.searchWords).toEqual(['(?i)foo']);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,14 +8,14 @@ import { catchError, map } from 'rxjs/operators';
|
|||||||
import * as dateMath from '@grafana/ui/src/utils/datemath';
|
import * as dateMath from '@grafana/ui/src/utils/datemath';
|
||||||
import { addLabelToSelector } from 'app/plugins/datasource/prometheus/add_label_to_query';
|
import { addLabelToSelector } from 'app/plugins/datasource/prometheus/add_label_to_query';
|
||||||
import LanguageProvider from './language_provider';
|
import LanguageProvider from './language_provider';
|
||||||
import { logStreamToSeriesData } from './result_transformer';
|
import { logStreamToDataFrame } from './result_transformer';
|
||||||
import { formatQuery, parseQuery, getHighlighterExpressionsFromQuery } from './query_utils';
|
import { formatQuery, parseQuery, getHighlighterExpressionsFromQuery } from './query_utils';
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import {
|
import {
|
||||||
PluginMeta,
|
PluginMeta,
|
||||||
DataQueryRequest,
|
DataQueryRequest,
|
||||||
SeriesData,
|
DataFrame,
|
||||||
DataSourceApi,
|
DataSourceApi,
|
||||||
DataSourceInstanceSettings,
|
DataSourceInstanceSettings,
|
||||||
DataQueryError,
|
DataQueryError,
|
||||||
@@ -147,25 +147,25 @@ export class LokiDatasource extends DataSourceApi<LokiQuery, LokiOptions> {
|
|||||||
return error;
|
return error;
|
||||||
};
|
};
|
||||||
|
|
||||||
processResult = (data: any, target: any): SeriesData[] => {
|
processResult = (data: any, target: any): DataFrame[] => {
|
||||||
const series: SeriesData[] = [];
|
const series: DataFrame[] = [];
|
||||||
|
|
||||||
if (Object.keys(data).length === 0) {
|
if (Object.keys(data).length === 0) {
|
||||||
return series;
|
return series;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!data.streams) {
|
if (!data.streams) {
|
||||||
return [{ ...logStreamToSeriesData(data), refId: target.refId }];
|
return [{ ...logStreamToDataFrame(data), refId: target.refId }];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const stream of data.streams || []) {
|
for (const stream of data.streams || []) {
|
||||||
const seriesData = logStreamToSeriesData(stream);
|
const dataFrame = logStreamToDataFrame(stream);
|
||||||
seriesData.refId = target.refId;
|
dataFrame.refId = target.refId;
|
||||||
seriesData.meta = {
|
dataFrame.meta = {
|
||||||
searchWords: getHighlighterExpressionsFromQuery(formatQuery(target.query, target.regexp)),
|
searchWords: getHighlighterExpressionsFromQuery(formatQuery(target.query, target.regexp)),
|
||||||
limit: this.maxLines,
|
limit: this.maxLines,
|
||||||
};
|
};
|
||||||
series.push(seriesData);
|
series.push(dataFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
return series;
|
return series;
|
||||||
@@ -233,7 +233,7 @@ export class LokiDatasource extends DataSourceApi<LokiQuery, LokiOptions> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return Promise.all(queries).then((results: any[]) => {
|
return Promise.all(queries).then((results: any[]) => {
|
||||||
let series: SeriesData[] = [];
|
let series: DataFrame[] = [];
|
||||||
|
|
||||||
for (let i = 0; i < results.length; i++) {
|
for (let i = 0; i < results.length; i++) {
|
||||||
const result = results[i];
|
const result = results[i];
|
||||||
@@ -328,14 +328,14 @@ export class LokiDatasource extends DataSourceApi<LokiQuery, LokiOptions> {
|
|||||||
(options && options.limit) || 10,
|
(options && options.limit) || 10,
|
||||||
(options && options.direction) || 'BACKWARD'
|
(options && options.direction) || 'BACKWARD'
|
||||||
);
|
);
|
||||||
const series: SeriesData[] = [];
|
const series: DataFrame[] = [];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await this._request('/api/prom/query', target);
|
const result = await this._request('/api/prom/query', target);
|
||||||
if (result.data) {
|
if (result.data) {
|
||||||
for (const stream of result.data.streams || []) {
|
for (const stream of result.data.streams || []) {
|
||||||
const seriesData = logStreamToSeriesData(stream);
|
const dataFrame = logStreamToDataFrame(stream);
|
||||||
series.push(seriesData);
|
series.push(dataFrame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (options && options.direction === 'FORWARD') {
|
if (options && options.direction === 'FORWARD') {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { logStreamToSeriesData } from './result_transformer';
|
import { logStreamToDataFrame } from './result_transformer';
|
||||||
|
|
||||||
describe('convert loki response to SeriesData', () => {
|
describe('convert loki response to DataFrame', () => {
|
||||||
const streams = [
|
const streams = [
|
||||||
{
|
{
|
||||||
labels: '{foo="bar"}',
|
labels: '{foo="bar"}',
|
||||||
@@ -22,7 +22,7 @@ describe('convert loki response to SeriesData', () => {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
it('converts streams to series', () => {
|
it('converts streams to series', () => {
|
||||||
const data = streams.map(stream => logStreamToSeriesData(stream));
|
const data = streams.map(stream => logStreamToDataFrame(stream));
|
||||||
|
|
||||||
expect(data.length).toBe(2);
|
expect(data.length).toBe(2);
|
||||||
expect(data[0].labels['foo']).toEqual('bar');
|
expect(data[0].labels['foo']).toEqual('bar');
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { LokiLogsStream } from './types';
|
import { LokiLogsStream } from './types';
|
||||||
import { SeriesData, parseLabels, FieldType, Labels } from '@grafana/ui';
|
import { DataFrame, parseLabels, FieldType, Labels } from '@grafana/ui';
|
||||||
|
|
||||||
export function logStreamToSeriesData(stream: LokiLogsStream): SeriesData {
|
export function logStreamToDataFrame(stream: LokiLogsStream): DataFrame {
|
||||||
let labels: Labels = stream.parsedLabels;
|
let labels: Labels = stream.parsedLabels;
|
||||||
if (!labels && stream.labels) {
|
if (!labels && stream.labels) {
|
||||||
labels = parseLabels(stream.labels);
|
labels = parseLabels(stream.labels);
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import BracesPlugin from 'app/features/explore/slate-plugins/braces';
|
|||||||
import QueryField, { TypeaheadInput, QueryFieldState } from 'app/features/explore/QueryField';
|
import QueryField, { TypeaheadInput, QueryFieldState } from 'app/features/explore/QueryField';
|
||||||
import { PromQuery, PromContext, PromOptions } from '../types';
|
import { PromQuery, PromContext, PromOptions } from '../types';
|
||||||
import { CancelablePromise, makePromiseCancelable } from 'app/core/utils/CancelablePromise';
|
import { CancelablePromise, makePromiseCancelable } from 'app/core/utils/CancelablePromise';
|
||||||
import { ExploreQueryFieldProps, DataSourceStatus, QueryHint, isSeriesData, toLegacyResponseData } from '@grafana/ui';
|
import { ExploreQueryFieldProps, DataSourceStatus, QueryHint, isDataFrame, toLegacyResponseData } from '@grafana/ui';
|
||||||
import { PrometheusDatasource } from '../datasource';
|
import { PrometheusDatasource } from '../datasource';
|
||||||
|
|
||||||
const HISTOGRAM_GROUP = '__histograms__';
|
const HISTOGRAM_GROUP = '__histograms__';
|
||||||
@@ -181,7 +181,7 @@ class PromQueryField extends React.PureComponent<PromQueryFieldProps, PromQueryF
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = isSeriesData(queryResponse.series[0])
|
const result = isDataFrame(queryResponse.series[0])
|
||||||
? queryResponse.series.map(toLegacyResponseData)
|
? queryResponse.series.map(toLegacyResponseData)
|
||||||
: queryResponse.series;
|
: queryResponse.series;
|
||||||
const hints = datasource.getQueryHints(query, result);
|
const hints = datasource.getQueryHints(query, result);
|
||||||
|
|||||||
+6
-6
@@ -2,7 +2,7 @@ import defaults from 'lodash/defaults';
|
|||||||
import {
|
import {
|
||||||
DataQueryRequest,
|
DataQueryRequest,
|
||||||
FieldType,
|
FieldType,
|
||||||
SeriesData,
|
DataFrame,
|
||||||
DataQueryResponse,
|
DataQueryResponse,
|
||||||
DataQueryError,
|
DataQueryError,
|
||||||
DataStreamObserver,
|
DataStreamObserver,
|
||||||
@@ -171,14 +171,14 @@ export class SignalWorker extends StreamWorker {
|
|||||||
return row;
|
return row;
|
||||||
};
|
};
|
||||||
|
|
||||||
initBuffer(refId: string): SeriesData {
|
initBuffer(refId: string): DataFrame {
|
||||||
const { speed, buffer } = this.query;
|
const { speed, buffer } = this.query;
|
||||||
const data = {
|
const data = {
|
||||||
fields: [{ name: 'Time', type: FieldType.time }, { name: 'Value', type: FieldType.number }],
|
fields: [{ name: 'Time', type: FieldType.time }, { name: 'Value', type: FieldType.number }],
|
||||||
rows: [],
|
rows: [],
|
||||||
refId,
|
refId,
|
||||||
name: 'Signal ' + refId,
|
name: 'Signal ' + refId,
|
||||||
} as SeriesData;
|
} as DataFrame;
|
||||||
|
|
||||||
for (let i = 0; i < this.bands; i++) {
|
for (let i = 0; i < this.bands; i++) {
|
||||||
const suffix = this.bands > 1 ? ` ${i + 1}` : '';
|
const suffix = this.bands > 1 ? ` ${i + 1}` : '';
|
||||||
@@ -260,7 +260,7 @@ export class FetchWorker extends StreamWorker {
|
|||||||
return this.reader.read().then(this.processChunk);
|
return this.reader.read().then(this.processChunk);
|
||||||
};
|
};
|
||||||
|
|
||||||
onHeader = (series: SeriesData) => {
|
onHeader = (series: DataFrame) => {
|
||||||
series.refId = this.refId;
|
series.refId = this.refId;
|
||||||
this.stream.series = [series];
|
this.stream.series = [series];
|
||||||
};
|
};
|
||||||
@@ -323,14 +323,14 @@ export class LogsWorker extends StreamWorker {
|
|||||||
return [time, '[' + this.getRandomLogLevel() + '] ' + this.getRandomLine()];
|
return [time, '[' + this.getRandomLogLevel() + '] ' + this.getRandomLine()];
|
||||||
};
|
};
|
||||||
|
|
||||||
initBuffer(refId: string): SeriesData {
|
initBuffer(refId: string): DataFrame {
|
||||||
const { speed, buffer } = this.query;
|
const { speed, buffer } = this.query;
|
||||||
const data = {
|
const data = {
|
||||||
fields: [{ name: 'Time', type: FieldType.time }, { name: 'Line', type: FieldType.string }],
|
fields: [{ name: 'Time', type: FieldType.time }, { name: 'Line', type: FieldType.string }],
|
||||||
rows: [],
|
rows: [],
|
||||||
refId,
|
refId,
|
||||||
name: 'Logs ' + refId,
|
name: 'Logs ' + refId,
|
||||||
} as SeriesData;
|
} as DataFrame;
|
||||||
|
|
||||||
const request = this.stream.request;
|
const request = this.stream.request;
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { TimeRange, colors, getColorFromHexRgbOrName, FieldCache, FieldType, Field, SeriesData } from '@grafana/ui';
|
import { TimeRange, colors, getColorFromHexRgbOrName, FieldCache, FieldType, Field, DataFrame } from '@grafana/ui';
|
||||||
import TimeSeries from 'app/core/time_series2';
|
import TimeSeries from 'app/core/time_series2';
|
||||||
import config from 'app/core/config';
|
import config from 'app/core/config';
|
||||||
|
|
||||||
type Options = {
|
type Options = {
|
||||||
dataList: SeriesData[];
|
dataList: DataFrame[];
|
||||||
range?: TimeRange;
|
range?: TimeRange;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ import { DataProcessor } from './data_processor';
|
|||||||
import { axesEditorComponent } from './axes_editor';
|
import { axesEditorComponent } from './axes_editor';
|
||||||
import config from 'app/core/config';
|
import config from 'app/core/config';
|
||||||
import TimeSeries from 'app/core/time_series2';
|
import TimeSeries from 'app/core/time_series2';
|
||||||
import { getColorFromHexRgbOrName, LegacyResponseData, SeriesData, DataLink, VariableSuggestion } from '@grafana/ui';
|
import { getColorFromHexRgbOrName, LegacyResponseData, DataFrame, DataLink, VariableSuggestion } from '@grafana/ui';
|
||||||
import { getProcessedSeriesData } from 'app/features/dashboard/state/PanelQueryState';
|
import { getProcessedDataFrame } from 'app/features/dashboard/state/PanelQueryState';
|
||||||
import { PanelQueryRunnerFormat } from 'app/features/dashboard/state/PanelQueryRunner';
|
import { PanelQueryRunnerFormat } from 'app/features/dashboard/state/PanelQueryRunner';
|
||||||
import { GraphContextMenuCtrl } from './GraphContextMenuCtrl';
|
import { GraphContextMenuCtrl } from './GraphContextMenuCtrl';
|
||||||
import { getDataLinksVariableSuggestions } from 'app/features/panel/panellinks/link_srv';
|
import { getDataLinksVariableSuggestions } from 'app/features/panel/panellinks/link_srv';
|
||||||
@@ -26,7 +26,7 @@ class GraphCtrl extends MetricsPanelCtrl {
|
|||||||
renderError: boolean;
|
renderError: boolean;
|
||||||
hiddenSeries: any = {};
|
hiddenSeries: any = {};
|
||||||
seriesList: TimeSeries[] = [];
|
seriesList: TimeSeries[] = [];
|
||||||
dataList: SeriesData[] = [];
|
dataList: DataFrame[] = [];
|
||||||
annotations: any = [];
|
annotations: any = [];
|
||||||
alertState: any;
|
alertState: any;
|
||||||
|
|
||||||
@@ -209,12 +209,12 @@ class GraphCtrl extends MetricsPanelCtrl {
|
|||||||
|
|
||||||
// This should only be called from the snapshot callback
|
// This should only be called from the snapshot callback
|
||||||
onDataReceived(dataList: LegacyResponseData[]) {
|
onDataReceived(dataList: LegacyResponseData[]) {
|
||||||
this.handleSeriesData(getProcessedSeriesData(dataList));
|
this.handleDataFrame(getProcessedDataFrame(dataList));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Directly support SeriesData skipping event callbacks
|
// Directly support DataFrame skipping event callbacks
|
||||||
handleSeriesData(data: SeriesData[]) {
|
handleDataFrame(data: DataFrame[]) {
|
||||||
super.handleSeriesData(data);
|
super.handleDataFrame(data);
|
||||||
|
|
||||||
this.dataList = data;
|
this.dataList = data;
|
||||||
this.seriesList = this.processor.getSeriesList({
|
this.seriesList = this.processor.getSeriesList({
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { DataProcessor } from '../data_processor';
|
import { DataProcessor } from '../data_processor';
|
||||||
import { getProcessedSeriesData } from 'app/features/dashboard/state/PanelQueryState';
|
import { getProcessedDataFrame } from 'app/features/dashboard/state/PanelQueryState';
|
||||||
|
|
||||||
describe('Graph DataProcessor', () => {
|
describe('Graph DataProcessor', () => {
|
||||||
const panel: any = {
|
const panel: any = {
|
||||||
@@ -11,7 +11,7 @@ describe('Graph DataProcessor', () => {
|
|||||||
|
|
||||||
describe('getTimeSeries from LegacyResponseData', () => {
|
describe('getTimeSeries from LegacyResponseData', () => {
|
||||||
// Try each type of data
|
// Try each type of data
|
||||||
const dataList = getProcessedSeriesData([
|
const dataList = getProcessedDataFrame([
|
||||||
{
|
{
|
||||||
alias: 'First (time_series)',
|
alias: 'First (time_series)',
|
||||||
datapoints: [[1, 1001], [2, 1002], [3, 1003]],
|
datapoints: [[1, 1001], [2, 1002], [3, 1003]],
|
||||||
|
|||||||
@@ -319,19 +319,19 @@ export class HeatmapCtrl extends MetricsPanelCtrl {
|
|||||||
this.render();
|
this.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
seriesHandler(seriesData: any) {
|
seriesHandler(dataFrame: any) {
|
||||||
if (seriesData.datapoints === undefined) {
|
if (dataFrame.datapoints === undefined) {
|
||||||
throw new Error('Heatmap error: data should be a time series');
|
throw new Error('Heatmap error: data should be a time series');
|
||||||
}
|
}
|
||||||
|
|
||||||
const series = new TimeSeries({
|
const series = new TimeSeries({
|
||||||
datapoints: seriesData.datapoints,
|
datapoints: dataFrame.datapoints,
|
||||||
alias: seriesData.target,
|
alias: dataFrame.target,
|
||||||
});
|
});
|
||||||
|
|
||||||
series.flotpairs = series.getFlotPairs(this.panel.nullPointMode);
|
series.flotpairs = series.getFlotPairs(this.panel.nullPointMode);
|
||||||
|
|
||||||
const datapoints = seriesData.datapoints || [];
|
const datapoints = dataFrame.datapoints || [];
|
||||||
if (datapoints && datapoints.length > 0) {
|
if (datapoints && datapoints.length > 0) {
|
||||||
const last = datapoints[datapoints.length - 1][1];
|
const last = datapoints[datapoints.length - 1][1];
|
||||||
const from = this.range.from;
|
const from = this.range.from;
|
||||||
|
|||||||
@@ -140,10 +140,10 @@ class SingleStatCtrl extends MetricsPanelCtrl {
|
|||||||
this.render();
|
this.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
seriesHandler(seriesData: any) {
|
seriesHandler(dataFrame: any) {
|
||||||
const series = new TimeSeries({
|
const series = new TimeSeries({
|
||||||
datapoints: seriesData.datapoints || [],
|
datapoints: dataFrame.datapoints || [],
|
||||||
alias: seriesData.target,
|
alias: dataFrame.target,
|
||||||
});
|
});
|
||||||
|
|
||||||
series.flotpairs = series.getFlotPairs(this.panel.nullPointMode);
|
series.flotpairs = series.getFlotPairs(this.panel.nullPointMode);
|
||||||
|
|||||||
Reference in New Issue
Block a user