Browse Source

Anomaly detector: option for disabling upper / lower bound hastic/hastic-server#701 (#350)

master
rozetko 5 years ago committed by GitHub
parent
commit
935e14bac5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 65
      src/panel/graph_panel/controllers/analytic_controller.ts
  2. 5
      src/panel/graph_panel/graph_ctrl.ts
  3. 21
      src/panel/graph_panel/models/analytic_units/anomaly_analytic_unit.ts
  4. 16
      src/panel/graph_panel/partials/analytic_unit.html

65
src/panel/graph_panel/controllers/analytic_controller.ts

@ -551,45 +551,46 @@ export class AnalyticController {
if(response === null) { if(response === null) {
return []; return [];
} }
const hsrSerie = {
let series: any[] = [{
...response.hsr, ...response.hsr,
color: ANALYTIC_UNIT_COLORS[0], color: ANALYTIC_UNIT_COLORS[0],
// TODO: render it separately from Metric series // TODO: render it separately from Metric series
overrides: [ overrides: [
{ alias: 'HSR', linewidth: 3, fill: 0 } { alias: 'HSR', linewidth: 3, fill: 0 }
] ]
}; }];
if(response.lowerBound !== undefined) {
if(response.lowerBound !== undefined && response.upperBound !== undefined) {
// TODO: looks bad // TODO: looks bad
return [ series.push({
{ target: '[AnomalyDetector]: lower bound',
target: '[AnomalyDetector]: lower bound', datapoints: response.lowerBound.datapoints,
datapoints: response.lowerBound.datapoints, color: ANALYTIC_UNIT_COLORS[1],
color: ANALYTIC_UNIT_COLORS[1], overrides: [{
overrides: [{ alias: '[AnomalyDetector]: lower bound',
alias: '[AnomalyDetector]: lower bound', linewidth: 1,
linewidth: 1, fill: 0,
fill: 0, legend: false
legend: false }]
}] });
}, }
{
target: '[AnomalyDetector]: upper bound', if(response.upperBound !== undefined) {
datapoints: response.upperBound.datapoints, series.push({
color: ANALYTIC_UNIT_COLORS[1], target: '[AnomalyDetector]: upper bound',
overrides: [{ datapoints: response.upperBound.datapoints,
alias: '[AnomalyDetector]: upper bound', color: ANALYTIC_UNIT_COLORS[1],
linewidth: 1, overrides: [{
fill: 0, alias: '[AnomalyDetector]: upper bound',
fillBelowTo: '[AnomalyDetector]: lower bound', linewidth: 1,
legend: false fill: response.lowerBound === undefined ? 1 : 0,
}] fillBelowTo: response.lowerBound === undefined ? '' : '[AnomalyDetector]: lower bound',
}, legend: false
hsrSerie }]
]; });
} }
return [hsrSerie];
return series;
} }
get inspectedAnalyticUnit(): AnalyticUnit | null { get inspectedAnalyticUnit(): AnalyticUnit | null {

5
src/panel/graph_panel/graph_ctrl.ts

@ -8,6 +8,7 @@ import { DataProcessor } from './data_processor';
import { MetricExpanded } from './models/metric'; import { MetricExpanded } from './models/metric';
import { DatasourceRequest } from './models/datasource'; import { DatasourceRequest } from './models/datasource';
import { AnalyticUnitId, AnalyticUnit, LabelingMode } from './models/analytic_units/analytic_unit'; import { AnalyticUnitId, AnalyticUnit, LabelingMode } from './models/analytic_units/analytic_unit';
import { BOUND_TYPES } from './models/analytic_units/anomaly_analytic_unit';
import { AnalyticService } from './services/analytic_service'; import { AnalyticService } from './services/analytic_service';
import { AnalyticController } from './controllers/analytic_controller'; import { AnalyticController } from './controllers/analytic_controller';
import { HasticPanelInfo } from './models/hastic_panel_info'; import { HasticPanelInfo } from './models/hastic_panel_info';
@ -809,6 +810,10 @@ class GraphCtrl extends MetricsPanelCtrl {
get renderError(): boolean { return this._renderError; } get renderError(): boolean { return this._renderError; }
set renderError(value: boolean) { this._renderError = value; } set renderError(value: boolean) { this._renderError = value; }
get boundTypes() {
return BOUND_TYPES;
}
} }
export { GraphCtrl, GraphCtrl as PanelCtrl }; export { GraphCtrl, GraphCtrl as PanelCtrl };

21
src/panel/graph_panel/models/analytic_units/anomaly_analytic_unit.ts

@ -8,6 +8,18 @@ type TimePeriod = {
unit: string unit: string
}; };
enum Bound {
NONE = 'NONE',
UPPER = 'UPPER',
LOWER = 'LOWER'
};
export const BOUND_TYPES = [
{ name: 'None', value: Bound.NONE },
{ name: 'Upper', value: Bound.UPPER },
{ name: 'Lower', value: Bound.LOWER }
];
const DEFAULTS = { const DEFAULTS = {
detectorType: DetectorType.ANOMALY, detectorType: DetectorType.ANOMALY,
type: 'ANOMALY', type: 'ANOMALY',
@ -17,7 +29,8 @@ const DEFAULTS = {
seasonalityPeriod: { seasonalityPeriod: {
value: 0, value: 0,
unit: 'seconds' unit: 'seconds'
} },
disableBound: Bound.NONE
}; };
const LABELING_MODES = [ const LABELING_MODES = [
@ -39,7 +52,8 @@ export class AnomalyAnalyticUnit extends AnalyticUnit {
alpha: this.alpha, alpha: this.alpha,
confidence: this.confidence, confidence: this.confidence,
seasonality: this.seasonality, seasonality: this.seasonality,
seasonalityPeriod: this.seasonalityPeriod seasonalityPeriod: this.seasonalityPeriod,
disableBound: this.disableBound
}; };
} }
@ -58,6 +72,9 @@ export class AnomalyAnalyticUnit extends AnalyticUnit {
set seasonalityPeriod(val: TimePeriod) { this._serverObject.seasonalityPeriod = val; } set seasonalityPeriod(val: TimePeriod) { this._serverObject.seasonalityPeriod = val; }
get seasonalityPeriod(): TimePeriod { return this._serverObject.seasonalityPeriod; } get seasonalityPeriod(): TimePeriod { return this._serverObject.seasonalityPeriod; }
set disableBound(val: Bound) { this._serverObject.disableBound = val; }
get disableBound(): Bound { return this._serverObject.disableBound; }
// TODO: merge seasonality and hasSeasonality // TODO: merge seasonality and hasSeasonality
set hasSeasonality(val: boolean) { set hasSeasonality(val: boolean) {
if(val) { if(val) {

16
src/panel/graph_panel/partials/analytic_unit.html

@ -146,3 +146,19 @@
<div class="gf-form-label gf-form-label--grow"></div> <div class="gf-form-label gf-form-label--grow"></div>
</div> </div>
</div> </div>
<div class="gf-form-inline" ng-if="analyticUnit.detectorType === 'anomaly'">
<div class="gf-form">
<label class="gf-form-label query-keyword width-8"> Disable bound </label>
<div class="gf-form-select-wrapper">
<select class="gf-form-input width-12"
ng-model="analyticUnit.disableBound"
ng-change="ctrl.onAnalyticUnitChange(analyticUnit)"
ng-options="bound.value as bound.name for bound in ctrl.boundTypes"
/>
</div>
</div>
<div class="gf-form gf-form--grow">
<div class="gf-form-label gf-form-label--grow"></div>
</div>
</div>

Loading…
Cancel
Save