You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
156 lines
4.5 KiB
156 lines
4.5 KiB
2 years ago
|
import { PanelOptions, Aggregation, Threshold, Icon, IconPosition, Condition } from 'types';
|
||
2 years ago
|
|
||
2 years ago
|
import { filterMetricListByAlias, getAggregatedValueFromSerie } from '../../utils';
|
||
2 years ago
|
|
||
|
import _ from 'lodash';
|
||
|
|
||
2 years ago
|
// Convert Grafana options into Chartwerk Bar options
|
||
|
export class BarOptions {
|
||
2 years ago
|
private thresholds: Array<{ value: number; color: string }> = [];
|
||
|
private icons: Array<{ src: string; position: string; size: number }> = [];
|
||
2 years ago
|
|
||
|
constructor(private grafanaSeriesList: any[], private grafanaOptions: PanelOptions) {
|
||
2 years ago
|
this._setThresholds();
|
||
2 years ago
|
this._setIcons();
|
||
2 years ago
|
}
|
||
|
|
||
2 years ago
|
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 {
|
||
2 years ago
|
const value = threshold.useMetric
|
||
|
? this.getLastValueFromMetrics(threshold.metricName, `Threshold ${idx + 1}`)
|
||
|
: threshold.value;
|
||
|
if (value === null || value === undefined) {
|
||
2 years ago
|
// TODO: may be throw an error
|
||
|
return;
|
||
|
}
|
||
|
this.thresholds.push({
|
||
|
value,
|
||
2 years ago
|
color: threshold.color,
|
||
2 years ago
|
});
|
||
|
}
|
||
|
|
||
2 years ago
|
private _setIcons(): void {
|
||
|
if (_.isEmpty(this.grafanaOptions.gauge.icons)) {
|
||
|
return;
|
||
|
}
|
||
|
for (let [idx, icon] of this.grafanaOptions.gauge.icons.entries()) {
|
||
|
this._setIcon(icon, idx);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private _setIcon(icon: Icon, idx: number): void {
|
||
|
if (!this._areIconConditionsFulfilled(icon, idx)) {
|
||
|
return;
|
||
|
}
|
||
|
this.icons.push({
|
||
|
src: icon.url,
|
||
|
size: icon.size,
|
||
|
position: this._getChartwerkIconPosition(icon.position),
|
||
|
});
|
||
|
}
|
||
|
|
||
|
private _areIconConditionsFulfilled(icon: Icon, iconIdx: number): boolean {
|
||
2 years ago
|
if (_.isEmpty(icon.metrics)) {
|
||
2 years ago
|
return true;
|
||
|
}
|
||
|
|
||
|
// check each condition and return false if something goes wrong
|
||
|
for (let [conditionIdx, metric] of icon.metrics.entries()) {
|
||
2 years ago
|
const value = this.getLastValueFromMetrics(metric, `Icon ${iconIdx + 1}, Condition ${conditionIdx + 1}`);
|
||
2 years ago
|
if (value === null || value === undefined) {
|
||
2 years ago
|
// TODO: may be throw an error
|
||
|
return false;
|
||
|
}
|
||
|
if (!this.checkIconCondition(value, icon.values[conditionIdx], icon.conditions[conditionIdx])) {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
private checkIconCondition(metricValue: number, inputValue: number, condition: Condition): boolean {
|
||
|
if (inputValue === undefined || inputValue === null) {
|
||
|
return true;
|
||
|
}
|
||
|
switch (condition) {
|
||
|
case Condition.EQUAL:
|
||
|
return metricValue === inputValue;
|
||
|
case Condition.GREATER:
|
||
|
return metricValue > inputValue;
|
||
|
case Condition.GREATER_OR_EQUAL:
|
||
|
return metricValue >= inputValue;
|
||
|
case Condition.LESS:
|
||
|
return metricValue < inputValue;
|
||
|
case Condition.LESS_OR_EQUAL:
|
||
|
return metricValue <= inputValue;
|
||
|
default:
|
||
|
throw new Error(`Unknown condition: ${condition}`);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private _getChartwerkIconPosition(position: IconPosition): string {
|
||
|
// TODO: use chartwerk types
|
||
|
switch (position) {
|
||
|
case IconPosition.MIDDLE:
|
||
|
return 'middle';
|
||
|
case IconPosition.UPPER_LEFT:
|
||
|
return 'left';
|
||
|
case IconPosition.UPPER_RIGHT:
|
||
|
return 'right';
|
||
|
default:
|
||
|
throw new Error(`Unknown Icon Position ${position}`);
|
||
|
}
|
||
|
}
|
||
|
|
||
2 years ago
|
getChartwerkOptions(): any {
|
||
2 years ago
|
return {
|
||
2 years ago
|
axis: {
|
||
|
x: {
|
||
|
format: 'custom',
|
||
|
valueFormatter: (value: any) => {
|
||
|
return 'L' + value;
|
||
|
},
|
||
|
},
|
||
|
y: {
|
||
|
format: 'custom',
|
||
|
range: [-100, 100],
|
||
|
valueFormatter: (value: any) => {
|
||
|
return value + '%';
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
stacked: false,
|
||
|
matching: false,
|
||
|
zoomEvents: {
|
||
|
scroll: { zoom: { isActive: false }, pan: { isActive: false } },
|
||
|
},
|
||
|
annotations: [
|
||
|
{ key: 'm-1', color: 'red' },
|
||
|
{ key: 'm-2', color: 'green' },
|
||
|
],
|
||
|
eventsCallbacks: {
|
||
|
zoomIn: (range: any) => {
|
||
|
console.log('range', range);
|
||
|
},
|
||
|
},
|
||
2 years ago
|
};
|
||
|
}
|
||
2 years ago
|
|
||
|
getLastValueFromMetrics(metricName: string | undefined, optionName: string): number | null {
|
||
2 years ago
|
// optionName -> helper in Error, mb use option path instead
|
||
2 years ago
|
const filteredSeries = filterMetricListByAlias(this.grafanaSeriesList, metricName, optionName);
|
||
2 years ago
|
const serie = filteredSeries[0];
|
||
|
// Last value for now
|
||
|
return getAggregatedValueFromSerie(serie, Aggregation.LAST);
|
||
|
}
|
||
2 years ago
|
}
|