2020-10-01 12:58:06 +02:00
|
|
|
import {
|
2021-01-15 16:20:20 +01:00
|
|
|
ArrayDataFrame,
|
2020-10-01 12:58:06 +02:00
|
|
|
ArrayVector,
|
|
|
|
|
DataFrame,
|
2021-01-15 16:20:20 +01:00
|
|
|
DataLink,
|
|
|
|
|
DataTopic,
|
2020-10-01 12:58:06 +02:00
|
|
|
Field,
|
|
|
|
|
FieldType,
|
|
|
|
|
formatLabels,
|
2021-01-15 16:20:20 +01:00
|
|
|
getDisplayProcessor,
|
2020-11-05 11:37:21 +01:00
|
|
|
Labels,
|
2020-10-01 12:58:06 +02:00
|
|
|
MutableField,
|
|
|
|
|
ScopedVars,
|
|
|
|
|
TIME_SERIES_TIME_FIELD_NAME,
|
|
|
|
|
TIME_SERIES_VALUE_FIELD_NAME,
|
|
|
|
|
} from '@grafana/data';
|
2021-01-15 16:20:20 +01:00
|
|
|
import { FetchResponse, getDataSourceSrv, getTemplateSrv } from '@grafana/runtime';
|
|
|
|
|
import { descending, deviation } from 'd3';
|
2020-10-01 12:58:06 +02:00
|
|
|
import {
|
2021-01-15 16:20:20 +01:00
|
|
|
ExemplarTraceIdDestination,
|
|
|
|
|
isExemplarData,
|
2020-10-01 12:58:06 +02:00
|
|
|
isMatrixData,
|
|
|
|
|
MatrixOrVectorResult,
|
|
|
|
|
PromDataSuccessResponse,
|
|
|
|
|
PromMetric,
|
|
|
|
|
PromQuery,
|
|
|
|
|
PromQueryRequest,
|
|
|
|
|
PromValue,
|
|
|
|
|
TransformOptions,
|
|
|
|
|
} from './types';
|
|
|
|
|
|
2020-10-21 11:21:39 +03:00
|
|
|
const POSITIVE_INFINITY_SAMPLE_VALUE = '+Inf';
|
|
|
|
|
const NEGATIVE_INFINITY_SAMPLE_VALUE = '-Inf';
|
|
|
|
|
|
2021-01-15 16:20:20 +01:00
|
|
|
interface TimeAndValue {
|
|
|
|
|
[TIME_SERIES_TIME_FIELD_NAME]: number;
|
|
|
|
|
[TIME_SERIES_VALUE_FIELD_NAME]: number;
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-01 12:58:06 +02:00
|
|
|
export function transform(
|
|
|
|
|
response: FetchResponse<PromDataSuccessResponse>,
|
|
|
|
|
transformOptions: {
|
|
|
|
|
query: PromQueryRequest;
|
2021-01-15 16:20:20 +01:00
|
|
|
exemplarTraceIdDestinations?: ExemplarTraceIdDestination[];
|
2020-10-01 12:58:06 +02:00
|
|
|
target: PromQuery;
|
|
|
|
|
responseListLength: number;
|
|
|
|
|
scopedVars?: ScopedVars;
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
// Create options object from transformOptions
|
|
|
|
|
const options: TransformOptions = {
|
|
|
|
|
format: transformOptions.target.format,
|
|
|
|
|
step: transformOptions.query.step,
|
|
|
|
|
legendFormat: transformOptions.target.legendFormat,
|
|
|
|
|
start: transformOptions.query.start,
|
|
|
|
|
end: transformOptions.query.end,
|
|
|
|
|
query: transformOptions.query.expr,
|
|
|
|
|
responseListLength: transformOptions.responseListLength,
|
|
|
|
|
scopedVars: transformOptions.scopedVars,
|
|
|
|
|
refId: transformOptions.target.refId,
|
|
|
|
|
valueWithRefId: transformOptions.target.valueWithRefId,
|
|
|
|
|
meta: {
|
2021-04-07 13:38:47 +02:00
|
|
|
// Fix for showing of Prometheus results in Explore table
|
|
|
|
|
preferredVisualisationType: transformOptions.query.instant ? 'table' : 'graph',
|
2020-10-01 12:58:06 +02:00
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
const prometheusResult = response.data.data;
|
|
|
|
|
|
2021-01-15 16:20:20 +01:00
|
|
|
if (isExemplarData(prometheusResult)) {
|
|
|
|
|
const events: TimeAndValue[] = [];
|
2021-01-20 07:59:48 +01:00
|
|
|
prometheusResult.forEach((exemplarData) => {
|
|
|
|
|
const data = exemplarData.exemplars.map((exemplar) => {
|
2021-01-15 16:20:20 +01:00
|
|
|
return {
|
2021-02-12 14:47:47 +01:00
|
|
|
[TIME_SERIES_TIME_FIELD_NAME]: exemplar.timestamp * 1000,
|
2021-02-04 20:00:30 +01:00
|
|
|
[TIME_SERIES_VALUE_FIELD_NAME]: exemplar.value,
|
|
|
|
|
...exemplar.labels,
|
2021-01-15 16:20:20 +01:00
|
|
|
...exemplarData.seriesLabels,
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
events.push(...data);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Grouping exemplars by step
|
|
|
|
|
const sampledExemplars = sampleExemplars(events, options);
|
|
|
|
|
|
|
|
|
|
const dataFrame = new ArrayDataFrame(sampledExemplars);
|
|
|
|
|
dataFrame.meta = { dataTopic: DataTopic.Annotations };
|
|
|
|
|
|
|
|
|
|
// Add data links if configured
|
|
|
|
|
if (transformOptions.exemplarTraceIdDestinations?.length) {
|
|
|
|
|
for (const exemplarTraceIdDestination of transformOptions.exemplarTraceIdDestinations) {
|
2021-01-20 07:59:48 +01:00
|
|
|
const traceIDField = dataFrame.fields.find((field) => field.name === exemplarTraceIdDestination!.name);
|
2021-01-15 16:20:20 +01:00
|
|
|
if (traceIDField) {
|
|
|
|
|
const links = getDataLinks(exemplarTraceIdDestination);
|
|
|
|
|
traceIDField.config.links = traceIDField.config.links?.length
|
|
|
|
|
? [...traceIDField.config.links, ...links]
|
|
|
|
|
: links;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return [dataFrame];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!prometheusResult?.result) {
|
2018-08-08 16:50:30 +02:00
|
|
|
return [];
|
2018-03-12 17:13:05 +03:00
|
|
|
}
|
|
|
|
|
|
2020-10-01 12:58:06 +02:00
|
|
|
// Return early if result type is scalar
|
|
|
|
|
if (prometheusResult.resultType === 'scalar') {
|
|
|
|
|
return [
|
|
|
|
|
{
|
|
|
|
|
meta: options.meta,
|
|
|
|
|
refId: options.refId,
|
|
|
|
|
length: 1,
|
2020-11-05 11:37:21 +01:00
|
|
|
fields: [getTimeField([prometheusResult.result]), getValueField({ data: [prometheusResult.result] })],
|
2020-10-01 12:58:06 +02:00
|
|
|
},
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Return early again if the format is table, this needs special transformation.
|
|
|
|
|
if (options.format === 'table') {
|
|
|
|
|
const tableData = transformMetricDataToTable(prometheusResult.result, options);
|
|
|
|
|
return [tableData];
|
|
|
|
|
}
|
2018-03-12 17:13:05 +03:00
|
|
|
|
2020-10-01 12:58:06 +02:00
|
|
|
// Process matrix and vector results to DataFrame
|
|
|
|
|
const dataFrame: DataFrame[] = [];
|
|
|
|
|
prometheusResult.result.forEach((data: MatrixOrVectorResult) => dataFrame.push(transformToDataFrame(data, options)));
|
2018-07-05 16:12:03 +03:00
|
|
|
|
2020-10-01 12:58:06 +02:00
|
|
|
// When format is heatmap use the already created data frames and transform it more
|
|
|
|
|
if (options.format === 'heatmap') {
|
|
|
|
|
dataFrame.sort(sortSeriesByLabel);
|
|
|
|
|
const seriesList = transformToHistogramOverTime(dataFrame);
|
|
|
|
|
return seriesList;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Return matrix or vector result as DataFrame[]
|
|
|
|
|
return dataFrame;
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-15 16:20:20 +01:00
|
|
|
function getDataLinks(options: ExemplarTraceIdDestination): DataLink[] {
|
|
|
|
|
const dataLinks: DataLink[] = [];
|
|
|
|
|
|
|
|
|
|
if (options.datasourceUid) {
|
|
|
|
|
const dataSourceSrv = getDataSourceSrv();
|
|
|
|
|
const dsSettings = dataSourceSrv.getInstanceSettings(options.datasourceUid);
|
|
|
|
|
|
|
|
|
|
dataLinks.push({
|
|
|
|
|
title: `Query with ${dsSettings?.name}`,
|
|
|
|
|
url: '',
|
|
|
|
|
internal: {
|
2021-05-10 19:54:02 +02:00
|
|
|
query: { query: '${__value.raw}', queryType: 'traceId' },
|
2021-01-15 16:20:20 +01:00
|
|
|
datasourceUid: options.datasourceUid,
|
|
|
|
|
datasourceName: dsSettings?.name ?? 'Data source not found',
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (options.url) {
|
|
|
|
|
dataLinks.push({
|
2021-02-10 18:02:48 +01:00
|
|
|
title: `Go to ${options.url}`,
|
2021-01-15 16:20:20 +01:00
|
|
|
url: options.url,
|
2021-02-10 18:02:48 +01:00
|
|
|
targetBlank: true,
|
2021-01-15 16:20:20 +01:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
return dataLinks;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Reduce the density of the exemplars by making sure that the highest value exemplar is included
|
|
|
|
|
* and then only the ones that are 2 times the standard deviation of the all the values.
|
|
|
|
|
* This makes sure not to show too many dots near each other.
|
|
|
|
|
*/
|
|
|
|
|
function sampleExemplars(events: TimeAndValue[], options: TransformOptions) {
|
|
|
|
|
const step = options.step || 15;
|
|
|
|
|
const bucketedExemplars: { [ts: string]: TimeAndValue[] } = {};
|
|
|
|
|
const values: number[] = [];
|
|
|
|
|
for (const exemplar of events) {
|
|
|
|
|
// Align exemplar timestamp to nearest step second
|
|
|
|
|
const alignedTs = String(Math.floor(exemplar[TIME_SERIES_TIME_FIELD_NAME] / 1000 / step) * step * 1000);
|
|
|
|
|
if (!bucketedExemplars[alignedTs]) {
|
|
|
|
|
// New bucket found
|
|
|
|
|
bucketedExemplars[alignedTs] = [];
|
|
|
|
|
}
|
|
|
|
|
bucketedExemplars[alignedTs].push(exemplar);
|
|
|
|
|
values.push(exemplar[TIME_SERIES_VALUE_FIELD_NAME]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Getting exemplars from each bucket
|
|
|
|
|
const standardDeviation = deviation(values);
|
|
|
|
|
const sampledBuckets = Object.keys(bucketedExemplars).sort();
|
|
|
|
|
const sampledExemplars = [];
|
|
|
|
|
for (const ts of sampledBuckets) {
|
|
|
|
|
const exemplarsInBucket = bucketedExemplars[ts];
|
|
|
|
|
if (exemplarsInBucket.length === 1) {
|
|
|
|
|
sampledExemplars.push(exemplarsInBucket[0]);
|
|
|
|
|
} else {
|
|
|
|
|
// Choose which values to sample
|
2021-01-20 07:59:48 +01:00
|
|
|
const bucketValues = exemplarsInBucket.map((ex) => ex[TIME_SERIES_VALUE_FIELD_NAME]).sort(descending);
|
2021-01-15 16:20:20 +01:00
|
|
|
const sampledBucketValues = bucketValues.reduce((acc: number[], curr) => {
|
|
|
|
|
if (acc.length === 0) {
|
|
|
|
|
// First value is max and is always added
|
|
|
|
|
acc.push(curr);
|
|
|
|
|
} else {
|
|
|
|
|
// Then take values only when at least 2 standard deviation distance to previously taken value
|
|
|
|
|
const prev = acc[acc.length - 1];
|
|
|
|
|
if (standardDeviation && prev - curr >= 2 * standardDeviation) {
|
|
|
|
|
acc.push(curr);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return acc;
|
|
|
|
|
}, []);
|
|
|
|
|
// Find the exemplars for the sampled values
|
|
|
|
|
sampledExemplars.push(
|
2021-01-20 07:59:48 +01:00
|
|
|
...sampledBucketValues.map(
|
|
|
|
|
(value) => exemplarsInBucket.find((ex) => ex[TIME_SERIES_VALUE_FIELD_NAME] === value)!
|
|
|
|
|
)
|
2021-01-15 16:20:20 +01:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return sampledExemplars;
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-01 12:58:06 +02:00
|
|
|
/**
|
|
|
|
|
* Transforms matrix and vector result from Prometheus result to DataFrame
|
|
|
|
|
*/
|
|
|
|
|
function transformToDataFrame(data: MatrixOrVectorResult, options: TransformOptions): DataFrame {
|
2020-11-05 11:37:21 +01:00
|
|
|
const { name, labels } = createLabelInfo(data.metric, options);
|
2020-10-01 12:58:06 +02:00
|
|
|
|
|
|
|
|
const fields: Field[] = [];
|
|
|
|
|
|
|
|
|
|
if (isMatrixData(data)) {
|
|
|
|
|
const stepMs = options.step ? options.step * 1000 : NaN;
|
|
|
|
|
let baseTimestamp = options.start * 1000;
|
|
|
|
|
const dps: PromValue[] = [];
|
2018-07-05 16:12:03 +03:00
|
|
|
|
2020-10-01 12:58:06 +02:00
|
|
|
for (const value of data.values) {
|
2020-10-21 11:21:39 +03:00
|
|
|
let dpValue: number | null = parseSampleValue(value[1]);
|
2020-07-06 21:16:27 +02:00
|
|
|
|
2020-10-01 12:58:06 +02:00
|
|
|
if (isNaN(dpValue)) {
|
2018-09-03 11:00:46 +02:00
|
|
|
dpValue = null;
|
2018-03-12 17:13:05 +03:00
|
|
|
}
|
|
|
|
|
|
2020-10-01 12:58:06 +02:00
|
|
|
const timestamp = value[0] * 1000;
|
2018-03-12 17:13:05 +03:00
|
|
|
for (let t = baseTimestamp; t < timestamp; t += stepMs) {
|
2020-10-01 12:58:06 +02:00
|
|
|
dps.push([t, null]);
|
2018-03-12 17:13:05 +03:00
|
|
|
}
|
|
|
|
|
baseTimestamp = timestamp + stepMs;
|
2020-10-01 12:58:06 +02:00
|
|
|
dps.push([timestamp, dpValue]);
|
2018-03-12 17:13:05 +03:00
|
|
|
}
|
|
|
|
|
|
2020-10-01 12:58:06 +02:00
|
|
|
const endTimestamp = options.end * 1000;
|
2018-03-12 17:13:05 +03:00
|
|
|
for (let t = baseTimestamp; t <= endTimestamp; t += stepMs) {
|
2020-10-01 12:58:06 +02:00
|
|
|
dps.push([t, null]);
|
2018-03-12 17:13:05 +03:00
|
|
|
}
|
2020-10-01 12:58:06 +02:00
|
|
|
fields.push(getTimeField(dps, true));
|
2020-12-01 10:36:38 +01:00
|
|
|
fields.push(getValueField({ data: dps, parseValue: false, labels, displayNameFromDS: name }));
|
2020-10-01 12:58:06 +02:00
|
|
|
} else {
|
|
|
|
|
fields.push(getTimeField([data.value]));
|
2020-12-01 10:36:38 +01:00
|
|
|
fields.push(getValueField({ data: [data.value], labels, displayNameFromDS: name }));
|
2020-10-01 12:58:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
meta: options.meta,
|
|
|
|
|
refId: options.refId,
|
|
|
|
|
length: fields[0].values.length,
|
|
|
|
|
fields,
|
|
|
|
|
name,
|
|
|
|
|
};
|
|
|
|
|
}
|
2018-03-12 17:13:05 +03:00
|
|
|
|
2020-10-01 12:58:06 +02:00
|
|
|
function transformMetricDataToTable(md: MatrixOrVectorResult[], options: TransformOptions): DataFrame {
|
|
|
|
|
if (!md || md.length === 0) {
|
2018-08-08 16:50:30 +02:00
|
|
|
return {
|
2020-04-30 12:41:03 +02:00
|
|
|
meta: options.meta,
|
2020-10-01 12:58:06 +02:00
|
|
|
refId: options.refId,
|
|
|
|
|
length: 0,
|
|
|
|
|
fields: [],
|
2018-08-08 16:50:30 +02:00
|
|
|
};
|
2018-03-12 17:13:05 +03:00
|
|
|
}
|
|
|
|
|
|
2020-10-01 12:58:06 +02:00
|
|
|
const valueText = options.responseListLength > 1 || options.valueWithRefId ? `Value #${options.refId}` : 'Value';
|
|
|
|
|
|
|
|
|
|
const timeField = getTimeField([]);
|
|
|
|
|
const metricFields = Object.keys(md.reduce((acc, series) => ({ ...acc, ...series.metric }), {}))
|
|
|
|
|
.sort()
|
2021-01-20 07:59:48 +01:00
|
|
|
.map((label) => {
|
2021-02-02 16:48:31 +01:00
|
|
|
// Labels have string field type, otherwise table tries to figure out the type which can result in unexpected results
|
|
|
|
|
// Only "le" label has a number field type
|
|
|
|
|
const numberField = label === 'le';
|
2020-10-01 12:58:06 +02:00
|
|
|
return {
|
|
|
|
|
name: label,
|
|
|
|
|
config: { filterable: true },
|
2021-02-02 16:48:31 +01:00
|
|
|
type: numberField ? FieldType.number : FieldType.string,
|
2020-10-01 12:58:06 +02:00
|
|
|
values: new ArrayVector(),
|
|
|
|
|
};
|
2018-03-12 17:13:05 +03:00
|
|
|
});
|
2020-11-05 11:37:21 +01:00
|
|
|
const valueField = getValueField({ data: [], valueName: valueText });
|
2020-10-01 12:58:06 +02:00
|
|
|
|
2021-01-20 07:59:48 +01:00
|
|
|
md.forEach((d) => {
|
2020-10-01 12:58:06 +02:00
|
|
|
if (isMatrixData(d)) {
|
2021-01-20 07:59:48 +01:00
|
|
|
d.values.forEach((val) => {
|
2020-10-01 12:58:06 +02:00
|
|
|
timeField.values.add(val[0] * 1000);
|
2021-01-20 07:59:48 +01:00
|
|
|
metricFields.forEach((metricField) => metricField.values.add(getLabelValue(d.metric, metricField.name)));
|
2020-10-21 11:21:39 +03:00
|
|
|
valueField.values.add(parseSampleValue(val[1]));
|
2020-10-01 12:58:06 +02:00
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
timeField.values.add(d.value[0] * 1000);
|
2021-01-20 07:59:48 +01:00
|
|
|
metricFields.forEach((metricField) => metricField.values.add(getLabelValue(d.metric, metricField.name)));
|
2020-10-21 11:21:39 +03:00
|
|
|
valueField.values.add(parseSampleValue(d.value[1]));
|
2020-10-01 12:58:06 +02:00
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
meta: options.meta,
|
|
|
|
|
refId: options.refId,
|
|
|
|
|
length: timeField.values.length,
|
|
|
|
|
fields: [timeField, ...metricFields, valueField],
|
|
|
|
|
};
|
|
|
|
|
}
|
2018-03-12 17:13:05 +03:00
|
|
|
|
2020-10-01 12:58:06 +02:00
|
|
|
function getLabelValue(metric: PromMetric, label: string): string | number {
|
|
|
|
|
if (metric.hasOwnProperty(label)) {
|
|
|
|
|
if (label === 'le') {
|
2020-10-21 11:21:39 +03:00
|
|
|
return parseSampleValue(metric[label]);
|
2020-10-01 12:58:06 +02:00
|
|
|
}
|
|
|
|
|
return metric[label];
|
|
|
|
|
}
|
|
|
|
|
return '';
|
|
|
|
|
}
|
2018-03-12 17:13:05 +03:00
|
|
|
|
2020-10-01 12:58:06 +02:00
|
|
|
function getTimeField(data: PromValue[], isMs = false): MutableField {
|
|
|
|
|
return {
|
|
|
|
|
name: TIME_SERIES_TIME_FIELD_NAME,
|
|
|
|
|
type: FieldType.time,
|
|
|
|
|
config: {},
|
2021-01-20 07:59:48 +01:00
|
|
|
values: new ArrayVector<number>(data.map((val) => (isMs ? val[0] : val[0] * 1000))),
|
2020-10-01 12:58:06 +02:00
|
|
|
};
|
|
|
|
|
}
|
2020-11-05 11:37:21 +01:00
|
|
|
type ValueFieldOptions = {
|
|
|
|
|
data: PromValue[];
|
|
|
|
|
valueName?: string;
|
|
|
|
|
parseValue?: boolean;
|
|
|
|
|
labels?: Labels;
|
2020-12-01 10:36:38 +01:00
|
|
|
displayNameFromDS?: string;
|
2020-11-05 11:37:21 +01:00
|
|
|
};
|
2018-03-12 17:13:05 +03:00
|
|
|
|
2020-11-05 11:37:21 +01:00
|
|
|
function getValueField({
|
|
|
|
|
data,
|
|
|
|
|
valueName = TIME_SERIES_VALUE_FIELD_NAME,
|
|
|
|
|
parseValue = true,
|
|
|
|
|
labels,
|
2020-12-01 10:36:38 +01:00
|
|
|
displayNameFromDS,
|
2020-11-05 11:37:21 +01:00
|
|
|
}: ValueFieldOptions): MutableField {
|
2020-10-01 12:58:06 +02:00
|
|
|
return {
|
|
|
|
|
name: valueName,
|
|
|
|
|
type: FieldType.number,
|
2021-01-15 16:20:20 +01:00
|
|
|
display: getDisplayProcessor(),
|
2020-11-05 11:37:21 +01:00
|
|
|
config: {
|
2020-12-01 10:36:38 +01:00
|
|
|
displayNameFromDS,
|
2020-11-05 11:37:21 +01:00
|
|
|
},
|
|
|
|
|
labels,
|
2021-01-20 07:59:48 +01:00
|
|
|
values: new ArrayVector<number | null>(data.map((val) => (parseValue ? parseSampleValue(val[1]) : val[1]))),
|
2020-10-01 12:58:06 +02:00
|
|
|
};
|
|
|
|
|
}
|
2018-03-12 17:13:05 +03:00
|
|
|
|
2020-10-01 12:58:06 +02:00
|
|
|
function createLabelInfo(labels: { [key: string]: string }, options: TransformOptions) {
|
|
|
|
|
if (options?.legendFormat) {
|
2020-10-01 18:51:23 +01:00
|
|
|
const title = renderTemplate(getTemplateSrv().replace(options.legendFormat, options?.scopedVars), labels);
|
2020-10-01 12:58:06 +02:00
|
|
|
return { name: title, labels };
|
2018-03-12 17:13:05 +03:00
|
|
|
}
|
|
|
|
|
|
2020-10-01 12:58:06 +02:00
|
|
|
const { __name__, ...labelsWithoutName } = labels;
|
|
|
|
|
const labelPart = formatLabels(labelsWithoutName);
|
2021-01-22 18:03:37 +01:00
|
|
|
let title = `${__name__ ?? ''}${labelPart}`;
|
|
|
|
|
|
|
|
|
|
if (!title) {
|
|
|
|
|
title = options.query;
|
|
|
|
|
}
|
Field: getFieldTitle as field / series display identity and use it in all field name matchers & field / series name displays (#24024)
* common title handling
* show labels
* update comment
* Update changelog for v7.0.0-beta1 (#24007)
Co-Authored-By: Marcus Efraimsson <marcus.efraimsson@gmail.com>
Co-Authored-By: Andrej Ocenas <mr.ocenas@gmail.com>
Co-Authored-By: Hugo Häggmark <hugo.haggmark@grafana.com>
Co-authored-by: Tobias Skarhed <1438972+tskarhed@users.noreply.github.com>
* verify-repo-update: Fix Dockerfile.deb (#24030)
Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
* CircleCI: Upgrade build pipeline tool (#24021)
* CircleCI: Upgrade build pipeline tool
* Devenv: ignore enterprise (#24037)
* Add header icon to Add data source page (#24033)
* latest.json: Update testing version (#24038)
Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
* Fix login page redirected from password reset (#24032)
* Storybook: Rewrite stories to CSF (#23989)
* ColorPicker to CSF format
* Convert stories to CSF
* Do not export ClipboardButton
* Update ConfirmButton
* Remove unused imports
* Fix feedback
* changelog enterprise 7.0.0-beta1 (#24039)
* CircleCI: Bump grafana/build-container revision (#24043)
Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
* Changelog: Updates changelog with more feature details (#24040)
* Changelog: Updates changelog with more feature details
* spell fix
* spell fix
* Updates
* Readme update
* Updates
* Select: fixes so component loses focus on selecting value or pressing outside of input. (#24008)
* changed the value container to a class component to get it to work with focus (maybe something with context?).
* added e2e tests to verify that the select focus is working as it should.
* fixed according to feedback.
* updated snapshot.
* Devenv: add remote renderer to grafana (#24050)
* NewPanelEditor: minor UI twekas (#24042)
* Forward ref for tabs, use html props
* Inspect: add inspect label to drawer title
* Add tooltips to sidebar pane tabs, copy changes
* Remove unused import
* Place tooltips over tabs
* Inspector: dont show transformations select if there is only one data frame
* Review
* Changelog: Add a breaking change (#24051)
Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
* CircleCI: Unpin grafana/docs-base (#24054)
Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
* Search: close overlay on Esc press (#24003)
* Search: Close on Esc
* Search: Increase bottom padding for the last item in section
* Search: Move closing search to keybindingsSrv
* Search: Fix folder view
* Search: Do not move folders if already in folder
* Docs: Adds deprecation notice to changelog and docs for scripted dashboards (#24060)
* Update CHANGELOG.md (#24047)
Fix typo
Co-authored-by: Daniel Lee <dan.limerick@gmail.com>
* Documentation: Alternative Team Sync Wording (#23960)
* Alternative wording for team sync docs
Signed-off-by: Joe Elliott <number101010@gmail.com>
* Update docs/sources/auth/team-sync.md
Co-Authored-By: Diana Payton <52059945+oddlittlebird@users.noreply.github.com>
Co-authored-by: Diana Payton <52059945+oddlittlebird@users.noreply.github.com>
* Fix misspell issues (#23905)
* Fix misspell issues
See,
$ golangci-lint run --timeout 10m --disable-all -E misspell ./...
Signed-off-by: Mario Trangoni <mjtrangoni@gmail.com>
* Fix codespell issues
See,
$ codespell -S './.git*' -L 'uint,thru,pres,unknwon,serie,referer,uptodate,durationm'
Signed-off-by: Mario Trangoni <mjtrangoni@gmail.com>
* ci please?
* non-empty commit - ci?
* Trigger build
Co-authored-by: bergquist <carl.bergquist@gmail.com>
Co-authored-by: Kyle Brandt <kyle@grafana.com>
* fix compile error
* better series display
* better display
* now with prometheus and loki
* a few more tests
* Improvements and tests
* thinking
* More advanced and smart default title generation
* Another fix
* Progress but dam this will be hard
* Reverting the time series Value field name change
* revert revert going in circles
* add a field state object
* Use state title when converting back to legacy format
* Improved the join (series to columsn) transformer
* Got tests running again
* Rewrite of seriesToColums that simplifies and fixing tests
* Fixed the tricky problem of multiple time field when not used in join
* Prometheus: Restoring prometheus formatting
* Graphite: Disable Grafana's series naming
* fixed imports
* Fixed tests and made rename transform change title instead
* Fixing more tests
* fix more tests
* fixed import issue
* Fixed more circular dependencies
* Renamed to getFieldTitle
* More rename
* Review feedback
* Fix for showing field title in calculate field transformer
* fieldOverride: Make it clear that state title after applying defaults & overrides
* Fixed ts issue
* Update packages/grafana-ui/src/components/TransformersUI/OrganizeFieldsTransformerEditor.tsx
Co-authored-by: Marcus Efraimsson <marcus.efraimsson@gmail.com>
Co-authored-by: Andrej Ocenas <mr.ocenas@gmail.com>
Co-authored-by: Hugo Häggmark <hugo.haggmark@grafana.com>
Co-authored-by: Tobias Skarhed <1438972+tskarhed@users.noreply.github.com>
Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com>
Co-authored-by: Leonard Gram <leo@xlson.com>
Co-authored-by: Ivana Huckova <30407135+ivanahuckova@users.noreply.github.com>
Co-authored-by: Alexander Zobnin <alexanderzobnin@gmail.com>
Co-authored-by: Torkel Ödegaard <torkel@grafana.com>
Co-authored-by: Marcus Andersson <marcus.andersson@grafana.com>
Co-authored-by: Dominik Prokop <dominik.prokop@grafana.com>
Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com>
Co-authored-by: Richard Hartmann <RichiH@users.noreply.github.com>
Co-authored-by: Daniel Lee <dan.limerick@gmail.com>
Co-authored-by: Joe Elliott <joe.elliott@grafana.com>
Co-authored-by: Diana Payton <52059945+oddlittlebird@users.noreply.github.com>
Co-authored-by: Mario Trangoni <mario@mariotrangoni.de>
Co-authored-by: bergquist <carl.bergquist@gmail.com>
Co-authored-by: Kyle Brandt <kyle@grafana.com>
2020-05-07 01:42:03 -07:00
|
|
|
|
2020-10-01 12:58:06 +02:00
|
|
|
return { name: title, labels: labelsWithoutName };
|
|
|
|
|
}
|
Field: getFieldTitle as field / series display identity and use it in all field name matchers & field / series name displays (#24024)
* common title handling
* show labels
* update comment
* Update changelog for v7.0.0-beta1 (#24007)
Co-Authored-By: Marcus Efraimsson <marcus.efraimsson@gmail.com>
Co-Authored-By: Andrej Ocenas <mr.ocenas@gmail.com>
Co-Authored-By: Hugo Häggmark <hugo.haggmark@grafana.com>
Co-authored-by: Tobias Skarhed <1438972+tskarhed@users.noreply.github.com>
* verify-repo-update: Fix Dockerfile.deb (#24030)
Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
* CircleCI: Upgrade build pipeline tool (#24021)
* CircleCI: Upgrade build pipeline tool
* Devenv: ignore enterprise (#24037)
* Add header icon to Add data source page (#24033)
* latest.json: Update testing version (#24038)
Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
* Fix login page redirected from password reset (#24032)
* Storybook: Rewrite stories to CSF (#23989)
* ColorPicker to CSF format
* Convert stories to CSF
* Do not export ClipboardButton
* Update ConfirmButton
* Remove unused imports
* Fix feedback
* changelog enterprise 7.0.0-beta1 (#24039)
* CircleCI: Bump grafana/build-container revision (#24043)
Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
* Changelog: Updates changelog with more feature details (#24040)
* Changelog: Updates changelog with more feature details
* spell fix
* spell fix
* Updates
* Readme update
* Updates
* Select: fixes so component loses focus on selecting value or pressing outside of input. (#24008)
* changed the value container to a class component to get it to work with focus (maybe something with context?).
* added e2e tests to verify that the select focus is working as it should.
* fixed according to feedback.
* updated snapshot.
* Devenv: add remote renderer to grafana (#24050)
* NewPanelEditor: minor UI twekas (#24042)
* Forward ref for tabs, use html props
* Inspect: add inspect label to drawer title
* Add tooltips to sidebar pane tabs, copy changes
* Remove unused import
* Place tooltips over tabs
* Inspector: dont show transformations select if there is only one data frame
* Review
* Changelog: Add a breaking change (#24051)
Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
* CircleCI: Unpin grafana/docs-base (#24054)
Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
* Search: close overlay on Esc press (#24003)
* Search: Close on Esc
* Search: Increase bottom padding for the last item in section
* Search: Move closing search to keybindingsSrv
* Search: Fix folder view
* Search: Do not move folders if already in folder
* Docs: Adds deprecation notice to changelog and docs for scripted dashboards (#24060)
* Update CHANGELOG.md (#24047)
Fix typo
Co-authored-by: Daniel Lee <dan.limerick@gmail.com>
* Documentation: Alternative Team Sync Wording (#23960)
* Alternative wording for team sync docs
Signed-off-by: Joe Elliott <number101010@gmail.com>
* Update docs/sources/auth/team-sync.md
Co-Authored-By: Diana Payton <52059945+oddlittlebird@users.noreply.github.com>
Co-authored-by: Diana Payton <52059945+oddlittlebird@users.noreply.github.com>
* Fix misspell issues (#23905)
* Fix misspell issues
See,
$ golangci-lint run --timeout 10m --disable-all -E misspell ./...
Signed-off-by: Mario Trangoni <mjtrangoni@gmail.com>
* Fix codespell issues
See,
$ codespell -S './.git*' -L 'uint,thru,pres,unknwon,serie,referer,uptodate,durationm'
Signed-off-by: Mario Trangoni <mjtrangoni@gmail.com>
* ci please?
* non-empty commit - ci?
* Trigger build
Co-authored-by: bergquist <carl.bergquist@gmail.com>
Co-authored-by: Kyle Brandt <kyle@grafana.com>
* fix compile error
* better series display
* better display
* now with prometheus and loki
* a few more tests
* Improvements and tests
* thinking
* More advanced and smart default title generation
* Another fix
* Progress but dam this will be hard
* Reverting the time series Value field name change
* revert revert going in circles
* add a field state object
* Use state title when converting back to legacy format
* Improved the join (series to columsn) transformer
* Got tests running again
* Rewrite of seriesToColums that simplifies and fixing tests
* Fixed the tricky problem of multiple time field when not used in join
* Prometheus: Restoring prometheus formatting
* Graphite: Disable Grafana's series naming
* fixed imports
* Fixed tests and made rename transform change title instead
* Fixing more tests
* fix more tests
* fixed import issue
* Fixed more circular dependencies
* Renamed to getFieldTitle
* More rename
* Review feedback
* Fix for showing field title in calculate field transformer
* fieldOverride: Make it clear that state title after applying defaults & overrides
* Fixed ts issue
* Update packages/grafana-ui/src/components/TransformersUI/OrganizeFieldsTransformerEditor.tsx
Co-authored-by: Marcus Efraimsson <marcus.efraimsson@gmail.com>
Co-authored-by: Andrej Ocenas <mr.ocenas@gmail.com>
Co-authored-by: Hugo Häggmark <hugo.haggmark@grafana.com>
Co-authored-by: Tobias Skarhed <1438972+tskarhed@users.noreply.github.com>
Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com>
Co-authored-by: Leonard Gram <leo@xlson.com>
Co-authored-by: Ivana Huckova <30407135+ivanahuckova@users.noreply.github.com>
Co-authored-by: Alexander Zobnin <alexanderzobnin@gmail.com>
Co-authored-by: Torkel Ödegaard <torkel@grafana.com>
Co-authored-by: Marcus Andersson <marcus.andersson@grafana.com>
Co-authored-by: Dominik Prokop <dominik.prokop@grafana.com>
Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com>
Co-authored-by: Richard Hartmann <RichiH@users.noreply.github.com>
Co-authored-by: Daniel Lee <dan.limerick@gmail.com>
Co-authored-by: Joe Elliott <joe.elliott@grafana.com>
Co-authored-by: Diana Payton <52059945+oddlittlebird@users.noreply.github.com>
Co-authored-by: Mario Trangoni <mario@mariotrangoni.de>
Co-authored-by: bergquist <carl.bergquist@gmail.com>
Co-authored-by: Kyle Brandt <kyle@grafana.com>
2020-05-07 01:42:03 -07:00
|
|
|
|
2020-10-01 12:58:06 +02:00
|
|
|
export function getOriginalMetricName(labelData: { [key: string]: string }) {
|
|
|
|
|
const metricName = labelData.__name__ || '';
|
|
|
|
|
delete labelData.__name__;
|
|
|
|
|
const labelPart = Object.entries(labelData)
|
2021-01-20 07:59:48 +01:00
|
|
|
.map((label) => `${label[0]}="${label[1]}"`)
|
2020-10-01 12:58:06 +02:00
|
|
|
.join(',');
|
|
|
|
|
return `${metricName}{${labelPart}}`;
|
|
|
|
|
}
|
Field: getFieldTitle as field / series display identity and use it in all field name matchers & field / series name displays (#24024)
* common title handling
* show labels
* update comment
* Update changelog for v7.0.0-beta1 (#24007)
Co-Authored-By: Marcus Efraimsson <marcus.efraimsson@gmail.com>
Co-Authored-By: Andrej Ocenas <mr.ocenas@gmail.com>
Co-Authored-By: Hugo Häggmark <hugo.haggmark@grafana.com>
Co-authored-by: Tobias Skarhed <1438972+tskarhed@users.noreply.github.com>
* verify-repo-update: Fix Dockerfile.deb (#24030)
Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
* CircleCI: Upgrade build pipeline tool (#24021)
* CircleCI: Upgrade build pipeline tool
* Devenv: ignore enterprise (#24037)
* Add header icon to Add data source page (#24033)
* latest.json: Update testing version (#24038)
Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
* Fix login page redirected from password reset (#24032)
* Storybook: Rewrite stories to CSF (#23989)
* ColorPicker to CSF format
* Convert stories to CSF
* Do not export ClipboardButton
* Update ConfirmButton
* Remove unused imports
* Fix feedback
* changelog enterprise 7.0.0-beta1 (#24039)
* CircleCI: Bump grafana/build-container revision (#24043)
Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
* Changelog: Updates changelog with more feature details (#24040)
* Changelog: Updates changelog with more feature details
* spell fix
* spell fix
* Updates
* Readme update
* Updates
* Select: fixes so component loses focus on selecting value or pressing outside of input. (#24008)
* changed the value container to a class component to get it to work with focus (maybe something with context?).
* added e2e tests to verify that the select focus is working as it should.
* fixed according to feedback.
* updated snapshot.
* Devenv: add remote renderer to grafana (#24050)
* NewPanelEditor: minor UI twekas (#24042)
* Forward ref for tabs, use html props
* Inspect: add inspect label to drawer title
* Add tooltips to sidebar pane tabs, copy changes
* Remove unused import
* Place tooltips over tabs
* Inspector: dont show transformations select if there is only one data frame
* Review
* Changelog: Add a breaking change (#24051)
Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
* CircleCI: Unpin grafana/docs-base (#24054)
Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
* Search: close overlay on Esc press (#24003)
* Search: Close on Esc
* Search: Increase bottom padding for the last item in section
* Search: Move closing search to keybindingsSrv
* Search: Fix folder view
* Search: Do not move folders if already in folder
* Docs: Adds deprecation notice to changelog and docs for scripted dashboards (#24060)
* Update CHANGELOG.md (#24047)
Fix typo
Co-authored-by: Daniel Lee <dan.limerick@gmail.com>
* Documentation: Alternative Team Sync Wording (#23960)
* Alternative wording for team sync docs
Signed-off-by: Joe Elliott <number101010@gmail.com>
* Update docs/sources/auth/team-sync.md
Co-Authored-By: Diana Payton <52059945+oddlittlebird@users.noreply.github.com>
Co-authored-by: Diana Payton <52059945+oddlittlebird@users.noreply.github.com>
* Fix misspell issues (#23905)
* Fix misspell issues
See,
$ golangci-lint run --timeout 10m --disable-all -E misspell ./...
Signed-off-by: Mario Trangoni <mjtrangoni@gmail.com>
* Fix codespell issues
See,
$ codespell -S './.git*' -L 'uint,thru,pres,unknwon,serie,referer,uptodate,durationm'
Signed-off-by: Mario Trangoni <mjtrangoni@gmail.com>
* ci please?
* non-empty commit - ci?
* Trigger build
Co-authored-by: bergquist <carl.bergquist@gmail.com>
Co-authored-by: Kyle Brandt <kyle@grafana.com>
* fix compile error
* better series display
* better display
* now with prometheus and loki
* a few more tests
* Improvements and tests
* thinking
* More advanced and smart default title generation
* Another fix
* Progress but dam this will be hard
* Reverting the time series Value field name change
* revert revert going in circles
* add a field state object
* Use state title when converting back to legacy format
* Improved the join (series to columsn) transformer
* Got tests running again
* Rewrite of seriesToColums that simplifies and fixing tests
* Fixed the tricky problem of multiple time field when not used in join
* Prometheus: Restoring prometheus formatting
* Graphite: Disable Grafana's series naming
* fixed imports
* Fixed tests and made rename transform change title instead
* Fixing more tests
* fix more tests
* fixed import issue
* Fixed more circular dependencies
* Renamed to getFieldTitle
* More rename
* Review feedback
* Fix for showing field title in calculate field transformer
* fieldOverride: Make it clear that state title after applying defaults & overrides
* Fixed ts issue
* Update packages/grafana-ui/src/components/TransformersUI/OrganizeFieldsTransformerEditor.tsx
Co-authored-by: Marcus Efraimsson <marcus.efraimsson@gmail.com>
Co-authored-by: Andrej Ocenas <mr.ocenas@gmail.com>
Co-authored-by: Hugo Häggmark <hugo.haggmark@grafana.com>
Co-authored-by: Tobias Skarhed <1438972+tskarhed@users.noreply.github.com>
Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com>
Co-authored-by: Leonard Gram <leo@xlson.com>
Co-authored-by: Ivana Huckova <30407135+ivanahuckova@users.noreply.github.com>
Co-authored-by: Alexander Zobnin <alexanderzobnin@gmail.com>
Co-authored-by: Torkel Ödegaard <torkel@grafana.com>
Co-authored-by: Marcus Andersson <marcus.andersson@grafana.com>
Co-authored-by: Dominik Prokop <dominik.prokop@grafana.com>
Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com>
Co-authored-by: Richard Hartmann <RichiH@users.noreply.github.com>
Co-authored-by: Daniel Lee <dan.limerick@gmail.com>
Co-authored-by: Joe Elliott <joe.elliott@grafana.com>
Co-authored-by: Diana Payton <52059945+oddlittlebird@users.noreply.github.com>
Co-authored-by: Mario Trangoni <mario@mariotrangoni.de>
Co-authored-by: bergquist <carl.bergquist@gmail.com>
Co-authored-by: Kyle Brandt <kyle@grafana.com>
2020-05-07 01:42:03 -07:00
|
|
|
|
2020-10-01 12:58:06 +02:00
|
|
|
export function renderTemplate(aliasPattern: string, aliasData: { [key: string]: string }) {
|
|
|
|
|
const aliasRegex = /\{\{\s*(.+?)\s*\}\}/g;
|
|
|
|
|
return aliasPattern.replace(aliasRegex, (_match, g1) => {
|
|
|
|
|
if (aliasData[g1]) {
|
|
|
|
|
return aliasData[g1];
|
2018-05-01 13:27:25 +02:00
|
|
|
}
|
2020-10-01 12:58:06 +02:00
|
|
|
return '';
|
|
|
|
|
});
|
|
|
|
|
}
|
Field: getFieldTitle as field / series display identity and use it in all field name matchers & field / series name displays (#24024)
* common title handling
* show labels
* update comment
* Update changelog for v7.0.0-beta1 (#24007)
Co-Authored-By: Marcus Efraimsson <marcus.efraimsson@gmail.com>
Co-Authored-By: Andrej Ocenas <mr.ocenas@gmail.com>
Co-Authored-By: Hugo Häggmark <hugo.haggmark@grafana.com>
Co-authored-by: Tobias Skarhed <1438972+tskarhed@users.noreply.github.com>
* verify-repo-update: Fix Dockerfile.deb (#24030)
Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
* CircleCI: Upgrade build pipeline tool (#24021)
* CircleCI: Upgrade build pipeline tool
* Devenv: ignore enterprise (#24037)
* Add header icon to Add data source page (#24033)
* latest.json: Update testing version (#24038)
Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
* Fix login page redirected from password reset (#24032)
* Storybook: Rewrite stories to CSF (#23989)
* ColorPicker to CSF format
* Convert stories to CSF
* Do not export ClipboardButton
* Update ConfirmButton
* Remove unused imports
* Fix feedback
* changelog enterprise 7.0.0-beta1 (#24039)
* CircleCI: Bump grafana/build-container revision (#24043)
Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
* Changelog: Updates changelog with more feature details (#24040)
* Changelog: Updates changelog with more feature details
* spell fix
* spell fix
* Updates
* Readme update
* Updates
* Select: fixes so component loses focus on selecting value or pressing outside of input. (#24008)
* changed the value container to a class component to get it to work with focus (maybe something with context?).
* added e2e tests to verify that the select focus is working as it should.
* fixed according to feedback.
* updated snapshot.
* Devenv: add remote renderer to grafana (#24050)
* NewPanelEditor: minor UI twekas (#24042)
* Forward ref for tabs, use html props
* Inspect: add inspect label to drawer title
* Add tooltips to sidebar pane tabs, copy changes
* Remove unused import
* Place tooltips over tabs
* Inspector: dont show transformations select if there is only one data frame
* Review
* Changelog: Add a breaking change (#24051)
Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
* CircleCI: Unpin grafana/docs-base (#24054)
Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
* Search: close overlay on Esc press (#24003)
* Search: Close on Esc
* Search: Increase bottom padding for the last item in section
* Search: Move closing search to keybindingsSrv
* Search: Fix folder view
* Search: Do not move folders if already in folder
* Docs: Adds deprecation notice to changelog and docs for scripted dashboards (#24060)
* Update CHANGELOG.md (#24047)
Fix typo
Co-authored-by: Daniel Lee <dan.limerick@gmail.com>
* Documentation: Alternative Team Sync Wording (#23960)
* Alternative wording for team sync docs
Signed-off-by: Joe Elliott <number101010@gmail.com>
* Update docs/sources/auth/team-sync.md
Co-Authored-By: Diana Payton <52059945+oddlittlebird@users.noreply.github.com>
Co-authored-by: Diana Payton <52059945+oddlittlebird@users.noreply.github.com>
* Fix misspell issues (#23905)
* Fix misspell issues
See,
$ golangci-lint run --timeout 10m --disable-all -E misspell ./...
Signed-off-by: Mario Trangoni <mjtrangoni@gmail.com>
* Fix codespell issues
See,
$ codespell -S './.git*' -L 'uint,thru,pres,unknwon,serie,referer,uptodate,durationm'
Signed-off-by: Mario Trangoni <mjtrangoni@gmail.com>
* ci please?
* non-empty commit - ci?
* Trigger build
Co-authored-by: bergquist <carl.bergquist@gmail.com>
Co-authored-by: Kyle Brandt <kyle@grafana.com>
* fix compile error
* better series display
* better display
* now with prometheus and loki
* a few more tests
* Improvements and tests
* thinking
* More advanced and smart default title generation
* Another fix
* Progress but dam this will be hard
* Reverting the time series Value field name change
* revert revert going in circles
* add a field state object
* Use state title when converting back to legacy format
* Improved the join (series to columsn) transformer
* Got tests running again
* Rewrite of seriesToColums that simplifies and fixing tests
* Fixed the tricky problem of multiple time field when not used in join
* Prometheus: Restoring prometheus formatting
* Graphite: Disable Grafana's series naming
* fixed imports
* Fixed tests and made rename transform change title instead
* Fixing more tests
* fix more tests
* fixed import issue
* Fixed more circular dependencies
* Renamed to getFieldTitle
* More rename
* Review feedback
* Fix for showing field title in calculate field transformer
* fieldOverride: Make it clear that state title after applying defaults & overrides
* Fixed ts issue
* Update packages/grafana-ui/src/components/TransformersUI/OrganizeFieldsTransformerEditor.tsx
Co-authored-by: Marcus Efraimsson <marcus.efraimsson@gmail.com>
Co-authored-by: Andrej Ocenas <mr.ocenas@gmail.com>
Co-authored-by: Hugo Häggmark <hugo.haggmark@grafana.com>
Co-authored-by: Tobias Skarhed <1438972+tskarhed@users.noreply.github.com>
Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com>
Co-authored-by: Leonard Gram <leo@xlson.com>
Co-authored-by: Ivana Huckova <30407135+ivanahuckova@users.noreply.github.com>
Co-authored-by: Alexander Zobnin <alexanderzobnin@gmail.com>
Co-authored-by: Torkel Ödegaard <torkel@grafana.com>
Co-authored-by: Marcus Andersson <marcus.andersson@grafana.com>
Co-authored-by: Dominik Prokop <dominik.prokop@grafana.com>
Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com>
Co-authored-by: Richard Hartmann <RichiH@users.noreply.github.com>
Co-authored-by: Daniel Lee <dan.limerick@gmail.com>
Co-authored-by: Joe Elliott <joe.elliott@grafana.com>
Co-authored-by: Diana Payton <52059945+oddlittlebird@users.noreply.github.com>
Co-authored-by: Mario Trangoni <mario@mariotrangoni.de>
Co-authored-by: bergquist <carl.bergquist@gmail.com>
Co-authored-by: Kyle Brandt <kyle@grafana.com>
2020-05-07 01:42:03 -07:00
|
|
|
|
2020-10-01 12:58:06 +02:00
|
|
|
function transformToHistogramOverTime(seriesList: DataFrame[]) {
|
|
|
|
|
/* t1 = timestamp1, t2 = timestamp2 etc.
|
2018-03-12 17:13:05 +03:00
|
|
|
t1 t2 t3 t1 t2 t3
|
|
|
|
|
le10 10 10 0 => 10 10 0
|
|
|
|
|
le20 20 10 30 => 10 0 30
|
|
|
|
|
le30 30 10 35 => 10 0 5
|
|
|
|
|
*/
|
2020-10-01 12:58:06 +02:00
|
|
|
for (let i = seriesList.length - 1; i > 0; i--) {
|
2021-01-20 07:59:48 +01:00
|
|
|
const topSeries = seriesList[i].fields.find((s) => s.name === TIME_SERIES_VALUE_FIELD_NAME);
|
|
|
|
|
const bottomSeries = seriesList[i - 1].fields.find((s) => s.name === TIME_SERIES_VALUE_FIELD_NAME);
|
2020-10-01 12:58:06 +02:00
|
|
|
if (!topSeries || !bottomSeries) {
|
|
|
|
|
throw new Error('Prometheus heatmap transform error: data should be a time series');
|
2018-03-12 17:13:05 +03:00
|
|
|
}
|
|
|
|
|
|
2020-10-01 12:58:06 +02:00
|
|
|
for (let j = 0; j < topSeries.values.length; j++) {
|
|
|
|
|
const bottomPoint = bottomSeries.values.get(j) || [0];
|
|
|
|
|
topSeries.values.toArray()[j] -= bottomPoint;
|
|
|
|
|
}
|
2018-03-12 17:13:05 +03:00
|
|
|
}
|
2020-10-01 12:58:06 +02:00
|
|
|
|
|
|
|
|
return seriesList;
|
2018-03-12 17:13:05 +03:00
|
|
|
}
|
|
|
|
|
|
2020-10-01 12:58:06 +02:00
|
|
|
function sortSeriesByLabel(s1: DataFrame, s2: DataFrame): number {
|
2018-03-12 17:13:05 +03:00
|
|
|
let le1, le2;
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
// fail if not integer. might happen with bad queries
|
2020-10-21 11:21:39 +03:00
|
|
|
le1 = parseSampleValue(s1.name ?? '');
|
|
|
|
|
le2 = parseSampleValue(s2.name ?? '');
|
2018-03-12 17:13:05 +03:00
|
|
|
} catch (err) {
|
2020-07-10 15:07:04 +01:00
|
|
|
console.error(err);
|
2018-03-12 17:13:05 +03:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (le1 > le2) {
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (le1 < le2) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-21 11:21:39 +03:00
|
|
|
function parseSampleValue(value: string): number {
|
|
|
|
|
switch (value) {
|
|
|
|
|
case POSITIVE_INFINITY_SAMPLE_VALUE:
|
|
|
|
|
return Number.POSITIVE_INFINITY;
|
|
|
|
|
case NEGATIVE_INFINITY_SAMPLE_VALUE:
|
|
|
|
|
return Number.NEGATIVE_INFINITY;
|
|
|
|
|
default:
|
|
|
|
|
return parseFloat(value);
|
2018-03-12 17:13:05 +03:00
|
|
|
}
|
|
|
|
|
}
|