|
|
|
@ -1,124 +1,17 @@
|
|
|
|
|
import { PanelOptions, Aggregation, Threshold, Icon, IconPosition, Condition } from 'types'; |
|
|
|
|
import { AbsoluteTimeRange } from '@grafana/data'; |
|
|
|
|
|
|
|
|
|
import { filterMetricListByAlias, getAggregatedValueFromSerie } from '../../utils'; |
|
|
|
|
|
|
|
|
|
import _ from 'lodash'; |
|
|
|
|
|
|
|
|
|
// Convert Grafana options into Chartwerk Bar options
|
|
|
|
|
export class BarOptions { |
|
|
|
|
private thresholds: Array<{ value: number; color: string }> = []; |
|
|
|
|
private icons: Array<{ src: string; position: string; size: number }> = []; |
|
|
|
|
|
|
|
|
|
constructor(private grafanaSeriesList: any[], private grafanaOptions: PanelOptions) { |
|
|
|
|
this._setThresholds(); |
|
|
|
|
this._setIcons(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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 + 1}`) |
|
|
|
|
: threshold.value; |
|
|
|
|
if (value === null || value === undefined) { |
|
|
|
|
// TODO: may be throw an error
|
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
this.thresholds.push({ |
|
|
|
|
value, |
|
|
|
|
color: threshold.color, |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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 { |
|
|
|
|
if (_.isEmpty(icon.metrics)) { |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// check each condition and return false if something goes wrong
|
|
|
|
|
for (let [conditionIdx, metric] of icon.metrics.entries()) { |
|
|
|
|
const value = this.getLastValueFromMetrics(metric, `Icon ${iconIdx + 1}, Condition ${conditionIdx + 1}`); |
|
|
|
|
if (value === null || value === undefined) { |
|
|
|
|
// 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}`); |
|
|
|
|
} |
|
|
|
|
constructor(private grafanaSeriesList: any[], private changeTimeRange: (timeRange: AbsoluteTimeRange) => void) { |
|
|
|
|
console.log(this.grafanaSeriesList) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
getChartwerkOptions(): any { |
|
|
|
|
return { |
|
|
|
|
axis: { |
|
|
|
|
x: { |
|
|
|
|
format: 'custom', |
|
|
|
|
valueFormatter: (value: any) => { |
|
|
|
|
return 'L' + value; |
|
|
|
|
}, |
|
|
|
|
format: 'time', |
|
|
|
|
}, |
|
|
|
|
y: { |
|
|
|
|
format: 'custom', |
|
|
|
@ -132,6 +25,7 @@ export class BarOptions {
|
|
|
|
|
matching: false, |
|
|
|
|
zoomEvents: { |
|
|
|
|
scroll: { zoom: { isActive: false }, pan: { isActive: false } }, |
|
|
|
|
mouse: { doubleClick: { isActive: false } }, |
|
|
|
|
}, |
|
|
|
|
annotations: [ |
|
|
|
|
{ key: 'm-1', color: 'red' }, |
|
|
|
@ -139,17 +33,9 @@ export class BarOptions {
|
|
|
|
|
], |
|
|
|
|
eventsCallbacks: { |
|
|
|
|
zoomIn: (range: any) => { |
|
|
|
|
console.log('range', range); |
|
|
|
|
}, |
|
|
|
|
this.changeTimeRange({ from: range[0][0], to: range[0][1] }); |
|
|
|
|
} |
|
|
|
|
}, |
|
|
|
|
}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
getLastValueFromMetrics(metricName: string | undefined, optionName: string): number | null { |
|
|
|
|
// optionName -> helper in Error, mb use option path instead
|
|
|
|
|
const filteredSeries = filterMetricListByAlias(this.grafanaSeriesList, metricName, optionName); |
|
|
|
|
const serie = filteredSeries[0]; |
|
|
|
|
// Last value for now
|
|
|
|
|
return getAggregatedValueFromSerie(serie, Aggregation.LAST); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|