mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Snapshots: Use the grafana datasource to render snapshot (#54870)
This commit is contained in:
parent
dbb33eaba9
commit
c49c238974
@ -7,8 +7,6 @@ import {
|
|||||||
DataQuery,
|
DataQuery,
|
||||||
PanelData,
|
PanelData,
|
||||||
DataTransformerConfig,
|
DataTransformerConfig,
|
||||||
getValueFormat,
|
|
||||||
formattedValueToString,
|
|
||||||
DataFrameJSON,
|
DataFrameJSON,
|
||||||
LoadingState,
|
LoadingState,
|
||||||
dataFrameToJSON,
|
dataFrameToJSON,
|
||||||
@ -16,6 +14,7 @@ import {
|
|||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
import { config } from '@grafana/runtime';
|
import { config } from '@grafana/runtime';
|
||||||
import { PanelModel } from 'app/features/dashboard/state';
|
import { PanelModel } from 'app/features/dashboard/state';
|
||||||
|
import { GrafanaQueryType } from 'app/plugins/datasource/grafana/types';
|
||||||
|
|
||||||
import { Randomize, randomizeData } from './randomizer';
|
import { Randomize, randomizeData } from './randomizer';
|
||||||
|
|
||||||
@ -74,8 +73,8 @@ export async function getDebugDashboard(panel: PanelModel, rand: Randomize, time
|
|||||||
withTransforms: false,
|
withTransforms: false,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
const dsref = panel.datasource;
|
||||||
const frames = randomizeData(getPanelDataFrames(data), rand);
|
const frames = randomizeData(getPanelDataFrames(data), rand);
|
||||||
const rawFrameContent = JSON.stringify(frames);
|
|
||||||
const grafanaVersion = `${config.buildInfo.version} (${config.buildInfo.commit})`;
|
const grafanaVersion = `${config.buildInfo.version} (${config.buildInfo.commit})`;
|
||||||
const queries = saveModel?.targets ?? [];
|
const queries = saveModel?.targets ?? [];
|
||||||
const html = `<table width="100%">
|
const html = `<table width="100%">
|
||||||
@ -84,15 +83,16 @@ export async function getDebugDashboard(panel: PanelModel, rand: Randomize, time
|
|||||||
<td >${info.panelType} @ ${saveModel.pluginVersion ?? grafanaVersion}</td>
|
<td >${info.panelType} @ ${saveModel.pluginVersion ?? grafanaVersion}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Queries (${queries.length})</th>
|
<th>Queries</th>
|
||||||
<td>${queries
|
<td>${queries
|
||||||
.map((t: DataQuery) => {
|
.map((t: DataQuery) => {
|
||||||
return `${t.refId}[${t.datasource?.type}]`;
|
const ds = t.datasource ?? dsref;
|
||||||
|
return `${t.refId}[${ds?.type}]`;
|
||||||
})
|
})
|
||||||
.join(', ')}</td>
|
.join(', ')}</td>
|
||||||
</tr>
|
</tr>
|
||||||
${getTransformsRow(saveModel)}
|
${getTransformsRow(saveModel)}
|
||||||
${getDataRow(data, rawFrameContent)}
|
${getDataRow(data, frames)}
|
||||||
${getAnnotationsRow(data)}
|
${getAnnotationsRow(data)}
|
||||||
<tr>
|
<tr>
|
||||||
<th>Grafana</th>
|
<th>Grafana</th>
|
||||||
@ -108,11 +108,11 @@ export async function getDebugDashboard(panel: PanelModel, rand: Randomize, time
|
|||||||
{
|
{
|
||||||
refId: 'A',
|
refId: 'A',
|
||||||
datasource: {
|
datasource: {
|
||||||
type: 'testdata',
|
type: 'grafana',
|
||||||
uid: '${testdata}',
|
uid: 'grafana',
|
||||||
},
|
},
|
||||||
rawFrameContent,
|
queryType: GrafanaQueryType.Snapshot,
|
||||||
scenarioId: 'raw_frame',
|
snapshot: frames,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
@ -137,8 +137,8 @@ export async function getDebugDashboard(panel: PanelModel, rand: Randomize, time
|
|||||||
type: 'table',
|
type: 'table',
|
||||||
title: 'Annotations',
|
title: 'Annotations',
|
||||||
datasource: {
|
datasource: {
|
||||||
type: 'testdata',
|
type: 'grafana',
|
||||||
uid: '${testdata}',
|
uid: 'grafana',
|
||||||
},
|
},
|
||||||
targets: [
|
targets: [
|
||||||
{
|
{
|
||||||
@ -174,19 +174,22 @@ function getTransformsRow(saveModel: any): string {
|
|||||||
</tr>`;
|
</tr>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDataRow(data: PanelData, raw: string): string {
|
function getDataRow(data: PanelData, frames: DataFrameJSON[]): string {
|
||||||
let frameCount = data.series.length ?? 0;
|
let frameCount = data.series.length ?? 0;
|
||||||
let fieldCount = 0;
|
let fieldCount = 0;
|
||||||
|
let rowCount = 0;
|
||||||
for (const frame of data.series) {
|
for (const frame of data.series) {
|
||||||
fieldCount += frame.fields.length;
|
fieldCount += frame.fields.length;
|
||||||
|
rowCount += frame.length;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
'<tr>' +
|
'<tr>' +
|
||||||
'<th>Data</th>' +
|
'<th>Data</th>' +
|
||||||
'<td>' +
|
'<td>' +
|
||||||
`${data.state !== LoadingState.Done ? data.state : ''} ` +
|
`${data.state !== LoadingState.Done ? data.state : ''} ` +
|
||||||
`${frameCount} frames, ${fieldCount} fields` +
|
`${frameCount} frames, ${fieldCount} fields, ` +
|
||||||
`(${formattedValueToString(getValueFormat('decbytes')(raw?.length))} JSON)` +
|
`${rowCount} rows ` +
|
||||||
|
// `(${formattedValueToString(getValueFormat('decbytes')(raw?.length))} JSON)` +
|
||||||
'</td>' +
|
'</td>' +
|
||||||
'</tr>'
|
'</tr>'
|
||||||
);
|
);
|
||||||
@ -211,8 +214,8 @@ const embeddedDataTemplate: any = {
|
|||||||
id: 2,
|
id: 2,
|
||||||
title: 'Reproduced with embedded data',
|
title: 'Reproduced with embedded data',
|
||||||
datasource: {
|
datasource: {
|
||||||
type: 'testdata',
|
type: 'grafana',
|
||||||
uid: '${testdata}',
|
uid: 'grafana',
|
||||||
},
|
},
|
||||||
gridPos: {
|
gridPos: {
|
||||||
h: 13,
|
h: 13,
|
||||||
@ -283,23 +286,4 @@ const embeddedDataTemplate: any = {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
schemaVersion: 37,
|
schemaVersion: 37,
|
||||||
templating: {
|
|
||||||
list: [
|
|
||||||
{
|
|
||||||
current: {
|
|
||||||
selected: true,
|
|
||||||
text: 'gdev-testdata',
|
|
||||||
value: 'gdev-testdata',
|
|
||||||
},
|
|
||||||
hide: 0,
|
|
||||||
includeAll: false,
|
|
||||||
multi: false,
|
|
||||||
name: 'testdata',
|
|
||||||
options: [],
|
|
||||||
query: 'testdata',
|
|
||||||
skipUrlSync: false,
|
|
||||||
type: 'datasource',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import pluralize from 'pluralize';
|
||||||
import React, { PureComponent } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -9,7 +10,7 @@ import {
|
|||||||
DataFrame,
|
DataFrame,
|
||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
import { config, getBackendSrv, getDataSourceSrv } from '@grafana/runtime';
|
import { config, getBackendSrv, getDataSourceSrv } from '@grafana/runtime';
|
||||||
import { InlineField, Select, Alert, Input, InlineFieldRow } from '@grafana/ui';
|
import { InlineField, Select, Alert, Input, InlineFieldRow, InlineLabel } from '@grafana/ui';
|
||||||
import { hasAlphaPanels } from 'app/core/config';
|
import { hasAlphaPanels } from 'app/core/config';
|
||||||
import { SearchQuery } from 'app/features/search/service';
|
import { SearchQuery } from 'app/features/search/service';
|
||||||
|
|
||||||
@ -344,6 +345,18 @@ export class QueryEditor extends PureComponent<Props, State> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderSnapshotQuery() {
|
||||||
|
const { query } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<InlineFieldRow>
|
||||||
|
<InlineField label="Snapshot" grow={true} labelWidth={labelWidth}>
|
||||||
|
<InlineLabel>{pluralize('frame', query.snapshot?.length ?? 0, true)}</InlineLabel>
|
||||||
|
</InlineField>
|
||||||
|
</InlineFieldRow>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
onSearchChange = (search: SearchQuery) => {
|
onSearchChange = (search: SearchQuery) => {
|
||||||
const { query, onChange, onRunQuery } = this.props;
|
const { query, onChange, onRunQuery } = this.props;
|
||||||
|
|
||||||
@ -362,6 +375,18 @@ export class QueryEditor extends PureComponent<Props, State> {
|
|||||||
|
|
||||||
const { queryType } = query;
|
const { queryType } = query;
|
||||||
|
|
||||||
|
// Only show "snapshot" when it already exists
|
||||||
|
let queryTypes = this.queryTypes;
|
||||||
|
if (queryType === GrafanaQueryType.Snapshot) {
|
||||||
|
queryTypes = [
|
||||||
|
...this.queryTypes,
|
||||||
|
{
|
||||||
|
label: 'Snapshot',
|
||||||
|
value: queryType,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{queryType === GrafanaQueryType.Search && (
|
{queryType === GrafanaQueryType.Search && (
|
||||||
@ -373,14 +398,15 @@ export class QueryEditor extends PureComponent<Props, State> {
|
|||||||
<InlineFieldRow>
|
<InlineFieldRow>
|
||||||
<InlineField label="Query type" grow={true} labelWidth={labelWidth}>
|
<InlineField label="Query type" grow={true} labelWidth={labelWidth}>
|
||||||
<Select
|
<Select
|
||||||
options={this.queryTypes}
|
options={queryTypes}
|
||||||
value={this.queryTypes.find((v) => v.value === queryType) || this.queryTypes[0]}
|
value={queryTypes.find((v) => v.value === queryType) || queryTypes[0]}
|
||||||
onChange={this.onQueryTypeChange}
|
onChange={this.onQueryTypeChange}
|
||||||
/>
|
/>
|
||||||
</InlineField>
|
</InlineField>
|
||||||
</InlineFieldRow>
|
</InlineFieldRow>
|
||||||
{queryType === GrafanaQueryType.LiveMeasurements && this.renderMeasurementsQuery()}
|
{queryType === GrafanaQueryType.LiveMeasurements && this.renderMeasurementsQuery()}
|
||||||
{queryType === GrafanaQueryType.List && this.renderListPublicFiles()}
|
{queryType === GrafanaQueryType.List && this.renderListPublicFiles()}
|
||||||
|
{queryType === GrafanaQueryType.Snapshot && this.renderSnapshotQuery()}
|
||||||
{queryType === GrafanaQueryType.Search && (
|
{queryType === GrafanaQueryType.Search && (
|
||||||
<SearchEditor value={query.search ?? {}} onChange={this.onSearchChange} />
|
<SearchEditor value={query.search ?? {}} onChange={this.onSearchChange} />
|
||||||
)}
|
)}
|
||||||
|
@ -14,6 +14,8 @@ import {
|
|||||||
MutableDataFrame,
|
MutableDataFrame,
|
||||||
parseLiveChannelAddress,
|
parseLiveChannelAddress,
|
||||||
toDataFrame,
|
toDataFrame,
|
||||||
|
dataFrameFromJSON,
|
||||||
|
LoadingState,
|
||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
import {
|
import {
|
||||||
DataSourceWithBackend,
|
DataSourceWithBackend,
|
||||||
@ -82,6 +84,15 @@ export class GrafanaDatasource extends DataSourceWithBackend<GrafanaQuery> {
|
|||||||
if (target.hide) {
|
if (target.hide) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (target.queryType === GrafanaQueryType.Snapshot) {
|
||||||
|
results.push(
|
||||||
|
of({
|
||||||
|
data: (target.snapshot ?? []).map((v) => dataFrameFromJSON(v)),
|
||||||
|
state: LoadingState.Done,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (target.queryType === GrafanaQueryType.LiveMeasurements) {
|
if (target.queryType === GrafanaQueryType.LiveMeasurements) {
|
||||||
let channel = templateSrv.replace(target.channel, request.scopedVars);
|
let channel = templateSrv.replace(target.channel, request.scopedVars);
|
||||||
const { filter } = target;
|
const { filter } = target;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { DataQuery } from '@grafana/data';
|
import { DataQuery, DataFrameJSON } from '@grafana/data';
|
||||||
import { LiveDataFilter } from '@grafana/runtime';
|
import { LiveDataFilter } from '@grafana/runtime';
|
||||||
import { SearchQuery } from 'app/features/search/service';
|
import { SearchQuery } from 'app/features/search/service';
|
||||||
|
|
||||||
@ -9,6 +9,7 @@ import { SearchQuery } from 'app/features/search/service';
|
|||||||
export enum GrafanaQueryType {
|
export enum GrafanaQueryType {
|
||||||
LiveMeasurements = 'measurements',
|
LiveMeasurements = 'measurements',
|
||||||
Annotations = 'annotations',
|
Annotations = 'annotations',
|
||||||
|
Snapshot = 'snapshot',
|
||||||
|
|
||||||
// backend
|
// backend
|
||||||
RandomWalk = 'randomWalk',
|
RandomWalk = 'randomWalk',
|
||||||
@ -24,6 +25,7 @@ export interface GrafanaQuery extends DataQuery {
|
|||||||
buffer?: number;
|
buffer?: number;
|
||||||
path?: string; // for list and read
|
path?: string; // for list and read
|
||||||
search?: SearchQuery;
|
search?: SearchQuery;
|
||||||
|
snapshot?: DataFrameJSON[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export const defaultQuery: GrafanaQuery = {
|
export const defaultQuery: GrafanaQuery = {
|
||||||
|
Loading…
Reference in New Issue
Block a user