diff --git a/src/models/options.ts b/src/models/options.ts index 4b071b9..a07daaa 100644 --- a/src/models/options.ts +++ b/src/models/options.ts @@ -1,4 +1,5 @@ -import { PanelOptions, Aggregation } from 'types'; +import _ from 'lodash'; +import { PanelOptions, Aggregation, Threshold } from 'types'; import { filterMetricListByAlias, getAggregatedValueFromSerie } from '../utils'; @@ -6,64 +7,82 @@ import { filterMetricListByAlias, getAggregatedValueFromSerie } from '../utils'; export class Options { private minValue: number | undefined; private maxValue: number | undefined; + private thresholds: { value: number, color: string }[] = []; constructor(private grafanaSeriesList: any[], private grafanaOptions: PanelOptions) { this._setMin(); this._setMax(); + this._setThresholds(); } - private _setMin(): any { - if (!this.grafanaOptions.gauge.min.metricName) { + private _setMin(): void { + if (!this.grafanaOptions.gauge.min.useMetric) { this.minValue = this.grafanaOptions.gauge.min.value; return; } - const filteredSeries = filterMetricListByAlias( - this.grafanaSeriesList, - this.grafanaOptions.gauge.min.metricName, - 'Min' - ); - const serie = filteredSeries[0]; - // Last value for now - const aggregatedValue = getAggregatedValueFromSerie(serie, Aggregation.LAST); + const aggregatedValue = this.getLastValueFromMetrics(this.grafanaOptions.gauge.min.metricName, 'Min'); this.minValue = aggregatedValue ? aggregatedValue : undefined; } - private _setMax(): any { - if (!this.grafanaOptions.gauge.max.metricName) { + private _setMax(): void { + if (!this.grafanaOptions.gauge.max.useMetric) { this.maxValue = this.grafanaOptions.gauge.max.value; return; } - const filteredSeries = filterMetricListByAlias( - this.grafanaSeriesList, - this.grafanaOptions.gauge.max.metricName, - 'Max' - ); - const serie = filteredSeries[0]; - // Last value for now - const aggregatedValue = getAggregatedValueFromSerie(serie, Aggregation.LAST); + const aggregatedValue = this.getLastValueFromMetrics(this.grafanaOptions.gauge.max.metricName, 'Max'); this.maxValue = aggregatedValue ? aggregatedValue : undefined; } + private _setThresholds(): void { + if (_.isEmpty(this.grafanaOptions.gauge.thresholds.thresholds)) { + return; + } + for (let [idx, threshold] of this.grafanaOptions.gauge.thresholds.thresholds.entries()) { + this._setThreshold(threshold, idx); + } + } + + private _setThreshold(threshold: Threshold, idx: number): void { + const value = threshold.useMetric ? this.getLastValueFromMetrics(threshold.metricName, `Threshold ${idx}`) : threshold.value; + if(value === null || value === undefined) { + // TODO: may be throw an error + return; + } + this.thresholds.push({ + value, + color: threshold.color + }); + } + + private _valueFormatter(value: number): string { + const decimals = this.grafanaOptions.gauge.decimals || 2; + return `${value.toFixed(decimals)} ${this.grafanaOptions.gauge.unit}`; + } + getChartwerkOptions(): any { console.log('opt', this.maxValue, this.minValue); return { maxValue: this.maxValue, minValue: this.minValue, - valueFormatter: (val: any) => val.toFixed(2), - defaultColor: 'green', + valueFormatter: (val: number) => this._valueFormatter(val), + defaultColor: this.grafanaOptions.gauge.thresholds.defaultColor, + valueArcBackgroundColor: this.grafanaOptions.gauge.thresholds.arcBackground, reversed: this.grafanaOptions.gauge.reversed, - stops: [ - { - color: 'green', - value: 100, - }, - { - color: 'orange', - value: 140, - }, - ], + stops: this.thresholds, + valueFontSize: this.grafanaOptions.gauge.valueSize, // @ts-ignore icons: [{ src: 'https://cityhost.ua/upload_img/blog5ef308ea5529c_trash2-01.jpg', position: 'middle', size: 30 }], }; } + + getLastValueFromMetrics(metricName: string | undefined, optionName: string): number | null { + const filteredSeries = filterMetricListByAlias( + this.grafanaSeriesList, + metricName, + optionName + ); + const serie = filteredSeries[0]; + // Last value for now + return getAggregatedValueFromSerie(serie, Aggregation.LAST); + } } diff --git a/src/module.ts b/src/module.ts index af79332..f73279f 100644 --- a/src/module.ts +++ b/src/module.ts @@ -87,7 +87,7 @@ export const plugin = new PanelPlugin(Panel).setPanelOptions((buil showIf: (config) => config.visualizationType === Pod.GAUGE, }) .addSliderInput({ - path: 'gauge.size', + path: 'gauge.valueSize', defaultValue: 20, name: 'Size (px)', settings: { diff --git a/src/types.ts b/src/types.ts index 923853c..88dfaec 100644 --- a/src/types.ts +++ b/src/types.ts @@ -4,7 +4,15 @@ export interface PanelOptions { min: ExtremumOptions; max: ExtremumOptions; value: ExtremumOptions; + valueSize: number; reversed: boolean; + decimals?: number; + unit?: string; + thresholds: { + arcBackground: string; + defaultColor: string; + thresholds: Threshold[]; + } }; } @@ -35,3 +43,10 @@ export enum Aggregation { MAX = 'max', LAST = 'last', } + +export type Threshold = { + useMetric: boolean; + value: number; + metricName: string; + color: string; +}