import { Aggregation } from './types'; import { DataProcessor } from './grafana/data_processor'; import { PanelData, TimeRange, getValueFormat } from '@grafana/data'; import TimeSeries from 'grafana/app/core/time_series2'; import * as _ from 'lodash'; export function formatValue(value: number, options: { unit?: string; decimals?: number }): string { const suffix = getValueFormat(options.unit)(0)?.suffix || ''; const decimals = _.isNumber(options.decimals) ? options.decimals : 2; return `${value.toFixed(decimals)} ${suffix}`; } export function getGrafanaSeriesList(grafanaData: PanelData, timeRange: TimeRange): TimeSeries[] { const processor = new DataProcessor({}); return processor.getSeriesList({ dataList: grafanaData.series, range: timeRange, }); } export function getLastMetricValue( grafanaSeriesList: TimeSeries[], metricName: string | undefined, optionName: string ): number | null { if (metricName === undefined) { return null; } // optionName -> helper in Error, mb use option path instead const filteredSeries = filterMetricListByAlias(grafanaSeriesList, metricName, optionName); const serie = filteredSeries[0]; // Last value for now return getAggregatedValueFromSerie(serie, Aggregation.LAST); } export function filterMetricListByAlias(list: any[], alias: string | undefined, option: string): any[] { const filteredSeries = _.filter(list, (serie) => serie.alias === alias); if (filteredSeries.length === 0) { throw new Error(`${option}: Can't find metric for ${alias} name.`); } if (filteredSeries.length > 1) { throw new Error(`${option}: Get ${filteredSeries.length} metrics for ${alias} name. Please choose one.`); } return filteredSeries; } export function getAggregatedValueFromSerie( serie: any, aggregation = Aggregation.LAST, valueIdx: 0 | 1 = 0 ): number | null { // series types { datapoints: [number, number][]} // valueIdx === 0 for Grafana series, valueIdx === 1 for Chartwerk series if (serie === undefined) { return null; } if (serie.datapoints.length === 0) { return null; } switch (aggregation) { case Aggregation.LAST: const lastRow = _.last(serie.datapoints as Array<[number, number]>); // @ts-ignore return !_.isEmpty(lastRow) ? lastRow[valueIdx] : null; default: throw new Error(`Unknown aggregation type: ${aggregation}`); } } export function isNumber(value: string): boolean { return !isNaN(parseFloat(value)) && isFinite(value as unknown as number); }