Browse Source

renaming anomalyType to analyticUnit

master
Alexey Velikiy 6 years ago
parent
commit
7cc7a2f5c1
  1. 14763
      dist/module.js
  2. 85
      dist/partials/tab_analytics.html
  3. 155
      src/controllers/analytic_controller.ts
  4. 37
      src/graph_renderer.ts
  5. 4
      src/graph_tooltip.ts
  6. 69
      src/model/analytic_unit.ts
  7. 68
      src/module.ts
  8. 85
      src/partials/tab_analytics.html
  9. 18
      src/services/analytic_service.ts

14763
dist/module.js vendored

File diff suppressed because one or more lines are too long

85
dist/partials/tab_analytics.html vendored

@ -1,18 +1,18 @@
<h5> Anomaly Types </h5>
<h5> Analytic Units </h5>
<div class="editor-row">
<div class="gf-form" ng-repeat="anomalyType in ctrl.anomalyController.anomalyTypes">
<div class="gf-form" ng-repeat="analyticUnit in ctrl.analyticsController.analyticUnits">
<label class="gf-form-label width-4"> Name </label>
<input
type="text" class="gf-form-input max-width-15"
ng-model="anomalyType.name"
ng-model="analyticUnit.name"
ng-disabled="true"
>
<label class="gf-form-label width-8"> Pattern type </label>
<label class="gf-form-label width-8"> Type </label>
<div class="gf-form-select-wrapper">
<select class="gf-form-input width-12"
ng-model="anomalyType.pattern"
ng-model="analyticUnit.pattern"
ng-options="pattern as pattern for pattern in ctrl.patterns"
ng-disabled="true"
/>
@ -30,21 +30,21 @@
<label class="gf-form-label width-6"> Color </label>
<span class="gf-form-label">
<color-picker
color="anomalyType.color"
onChange="ctrl.onAnomalyColorChange.bind(ctrl, anomalyType.key)"
color="analyticUnit.color"
onChange="ctrl.onAnomalyColorChange.bind(ctrl, analyticUnit.key)"
/>
</span>
<label class="gf-form-label" ng-style="anomalyType.status === 'learning' && { 'cursor': 'not-allowed' }">
<label class="gf-form-label" ng-style="analyticUnit.status === 'learning' && { 'cursor': 'not-allowed' }">
<a class="pointer" tabindex="1"
ng-click="ctrl.onToggleAnomalyTypeLabelingMode(anomalyType.key)"
ng-disabled="anomalyType.status === 'learning'"
ng-click="ctrl.onToggleLabelingMode(analyticUnit.key)"
ng-disabled="analyticUnit.status === 'learning'"
>
<i class="fa fa-bar-chart" ng-if="!anomalyType.saving"></i>
<i class="fa fa-spinner fa-spin" ng-if="anomalyType.saving"></i>
<b ng-if="anomalyType.selected && !anomalyType.deleteMode && !anomalyType.saving"> labeling </b>
<b ng-if="anomalyType.selected && anomalyType.deleteMode && !anomalyType.saving"> deleting </b>
<b ng-if="anomalyType.saving" ng-disabled="true"> saving... </b>
<i class="fa fa-bar-chart" ng-if="!analyticUnit.saving"></i>
<i class="fa fa-spinner fa-spin" ng-if="analyticUnit.saving"></i>
<b ng-if="analyticUnit.selected && !analyticUnit.deleteMode && !analyticUnit.saving"> labeling </b>
<b ng-if="analyticUnit.selected && analyticUnit.deleteMode && !analyticUnit.saving"> deleting </b>
<b ng-if="analyticUnit.saving" ng-disabled="true"> saving... </b>
</a>
</label>
@ -53,35 +53,35 @@
<label
class="gf-form-label text-center"
style="width: 4rem"
ng-if="anomalyType.alertEnabled === undefined"
ng-if="analyticUnit.alertEnabled === undefined"
bs-tooltip="'Alarting status isn`t available. Wait please.'"
>
<i class="fa fa-spinner fa-spin"></i>
</label>
<gf-form-switch
ng-if="anomalyType.alertEnabled !== undefined"
on-change="ctrl.onAnomalyAlertChange(anomalyType)"
checked="anomalyType.alertEnabled"
ng-if="analyticUnit.alertEnabled !== undefined"
on-change="ctrl.onAnomalyAlertChange(analyticUnit)"
checked="analyticUnit.alertEnabled"
style="height: 36px;"
/>
<label class="gf-form-label">
<a
ng-if="anomalyType.visible"
ng-disabled="anomalyType.selected"
ng-if="analyticUnit.visible"
ng-disabled="analyticUnit.selected"
bs-tooltip="'Hide. It`s visible now.'"
ng-click="ctrl.onAnomalyToggleVisibility(anomalyType.key)"
ng-click="ctrl.onToggleVisibility(analyticUnit.key)"
class="pointer"
>
<i class="fa fa-eye"></i>
</a>
<a
ng-if="!anomalyType.visible"
ng-disabled="anomalyType.selected"
ng-if="!analyticUnit.visible"
ng-disabled="analyticUnit.selected"
bs-tooltip="'Show. It`s hidden now.'"
ng-click="ctrl.onAnomalyToggleVisibility(anomalyType.key)"
ng-click="ctrl.onToggleVisibility(analyticUnit.key)"
class="pointer"
>
<i class="fa fa-eye-slash"></i>
@ -90,16 +90,16 @@
<label class="gf-form-label">
<a
ng-if="!anomalyType.selected"
ng-click="ctrl.onAnomalyRemove(anomalyType.key)"
ng-if="!analyticUnit.selected"
ng-click="ctrl.onRemove(analyticUnit.key)"
class="pointer"
>
<i class="fa fa-trash"></i>
</a>
<a
ng-if="anomalyType.selected"
ng-click="ctrl.onAnomalyCancelLabeling(anomalyType.key)"
ng-if="analyticUnit.selected"
ng-click="ctrl.onCancelLabeling(analyticUnit.key)"
class="pointer"
>
<i class="fa fa-ban"></i>
@ -107,43 +107,42 @@
</label>
<label>
<i ng-if="anomalyType.status === 'learning'" class="grafana-tip fa fa-leanpub ng-scope" bs-tooltip="'Learning'"></i>
<i ng-if="anomalyType.status === 'pending'" class="grafana-tip fa fa-list-ul ng-scope" bs-tooltip="'Pending'"></i>
<i ng-if="anomalyType.status === 'failed'" class="grafana-tip fa fa-exclamation-circle ng-scope" bs-tooltip="'Error: ' + anomalyType.error"></i>
<i ng-if="analyticUnit.status === 'learning'" class="grafana-tip fa fa-leanpub ng-scope" bs-tooltip="'Learning'"></i>
<i ng-if="analyticUnit.status === 'pending'" class="grafana-tip fa fa-list-ul ng-scope" bs-tooltip="'Pending'"></i>
<i ng-if="analyticUnit.status === 'failed'" class="grafana-tip fa fa-exclamation-circle ng-scope" bs-tooltip="'Error: ' + analyticUnit.error"></i>
</label>
</div>
</div>
<div class="editor-row" ng-if="ctrl.anomalyController.creatingAnomalyType">
<div class="editor-row" ng-if="ctrl.analyticsController.creatingNew">
<div class="gf-form">
<label class="gf-form-label width-4"> Name </label>
<input
type="text" class="gf-form-input max-width-15"
ng-model="ctrl.anomalyController.newAnomalyType.name"
ng-change="ctrl.onAnomalyNameChange()"
ng-model="ctrl.analyticsController.newAnalyticUnit.name"
>
<label class="gf-form-label width-8"> Pattern type </label>
<label class="gf-form-label width-8"> Type </label>
<div class="gf-form-select-wrapper">
<select class="gf-form-input width-12"
ng-model="ctrl.anomalyController.newAnomalyType.pattern"
ng-model="ctrl.analyticsController.newAnalyticUnit.pattern"
ng-options="pattern as pattern disable when (pattern !== 'General' && pattern !== 'Drops' && pattern !== 'Peaks') for pattern in ctrl.patterns"
/>
</div>
<label class="gf-form-label">
<a class="pointer" tabindex="1" ng-click="ctrl.saveAnomalyType()">
<b ng-if="!ctrl.anomalyController.savingAnomalyType"> create </b>
<b ng-if="ctrl.anomalyController.savingAnomalyType" ng-disabled="true"> saving... </b>
<a class="pointer" tabindex="1" ng-click="ctrl.saveNew()">
<b ng-if="!ctrl.analyticsController.saving"> create </b>
<b ng-if="ctrl.analyticsController.saving" ng-disabled="true"> saving... </b>
</a>
</label>
</div>
</div>
<div class="gf-form-button-row" ng-if="!ctrl.anomalyController.creatingAnomalyType">
<button class="btn btn-inverse" ng-click="ctrl.createNewAnomalyType()">
<div class="gf-form-button-row" ng-if="!ctrl.analyticsController.creatingAnalyticUnit">
<button class="btn btn-inverse" ng-click="ctrl.createNew()">
<i class="fa fa-plus"></i>
Add an Anomaly Type
Add Analytic Unit
</button>
</div>

155
src/controllers/anomaly_controller.ts → src/controllers/analytic_controller.ts

@ -1,9 +1,9 @@
import { AnomalyService } from '../services/anomaly_service'
import { AnalyticService } from '../services/analytic_service'
import {
AnomalyKey, AnomalyType,
AnomalyTypesSet, AnomalySegment, AnomalySegmentsSearcher, AnomalySermentPair
} from '../model/anomaly';
AnalyticUnitKey, AnalyticUnit,
AnalyticUnitsSet, AnalyticSegment, AnalyticSegmentsSearcher, AnalyticSegmentPair
} from '../model/analytic_unit';
import { MetricExpanded } from '../model/metric';
import { DatasourceRequest } from '../model/datasource';
import { Segment, SegmentKey } from '../model/segment';
@ -13,45 +13,46 @@ import { Emitter } from 'grafana/app/core/utils/emitter'
import _ from 'lodash';
export const REGION_FILL_ALPHA = 0.7;
export const REGION_STROKE_ALPHA = 0.9;
export const REGION_DELETE_COLOR_LIGHT = '#d1d1d1';
export const REGION_DELETE_COLOR_DARK = 'white';
export class AnomalyController {
export class AnalyticController {
private _anomalyTypesSet: AnomalyTypesSet;
private _selectedAnomalyKey: AnomalyKey = null;
private _analyticUnitsSet: AnalyticUnitsSet;
private _selectedAnalyticUnitKey: AnalyticUnitKey = null;
private _labelingDataAddedSegments: SegmentsSet<AnomalySegment>;
private _labelingDataDeletedSegments: SegmentsSet<AnomalySegment>;
private _newAnomalyType: AnomalyType = null;
private _creatingNewAnomalyType: boolean = false;
private _savingNewAnomalyType: boolean = false;
private _labelingDataAddedSegments: SegmentsSet<AnalyticSegment>;
private _labelingDataDeletedSegments: SegmentsSet<AnalyticSegment>;
private _newAnalyticUnitType: AnalyticUnit = null;
private _creatingNewAnalyticType: boolean = false;
private _savingNewAnalyticUnit: boolean = false;
private _tempIdCounted = -1;
private _graphLocked = false;
private _statusRunners: Set<AnomalyKey> = new Set<AnomalyKey>();
private _statusRunners: Set<AnalyticUnitKey> = new Set<AnalyticUnitKey>();
constructor(private _panelObject: any, private _anomalyService: AnomalyService, private _emitter: Emitter) {
constructor(private _panelObject: any, private _analyticService: AnalyticService, private _emitter: Emitter) {
if(_panelObject.anomalyTypes === undefined) {
_panelObject.anomalyTypes = [];
}
this._labelingDataAddedSegments = new SegmentArray<AnomalySegment>();
this._labelingDataDeletedSegments = new SegmentArray<AnomalySegment>();
this._anomalyTypesSet = new AnomalyTypesSet(this._panelObject.anomalyTypes);
this.anomalyTypes.forEach(a => this.runAnomalyTypeAlertEnabledWaiter(a));
this._labelingDataAddedSegments = new SegmentArray<AnalyticSegment>();
this._labelingDataDeletedSegments = new SegmentArray<AnalyticSegment>();
this._analyticUnitsSet = new AnalyticUnitsSet(this._panelObject.anomalyTypes);
this.analyticUnits.forEach(a => this.runEnabledWaiter(a));
}
getAnomalySegmentsSearcher(): AnomalySegmentsSearcher {
return this._anomalySegmentsSearcher.bind(this);
getSegmentsSearcher(): AnalyticSegmentsSearcher {
return this._segmentsSearcher.bind(this);
}
private _anomalySegmentsSearcher(point: number, rangeDist: number): AnomalySermentPair[] {
var result: AnomalySermentPair[] = [];
this._anomalyTypesSet.anomalyTypes.forEach(at => {
private _segmentsSearcher(point: number, rangeDist: number): AnalyticSegmentPair[] {
var result: AnalyticSegmentPair[] = [];
this._analyticUnitsSet.items.forEach(at => {
var segs = at.segments.findSegments(point, rangeDist);
segs.forEach(s => {
result.push({ anomalyType: at, segment: s });
@ -60,53 +61,51 @@ export class AnomalyController {
return result;
}
createAnomalyType() {
this._newAnomalyType = new AnomalyType();
this._creatingNewAnomalyType = true;
this._savingNewAnomalyType = false;
createNew() {
this._newAnalyticUnitType = new AnalyticUnit();
this._creatingNewAnalyticType = true;
this._savingNewAnalyticUnit = false;
}
async saveNewAnomalyType(metricExpanded: MetricExpanded, datasourceRequest: DatasourceRequest, panelId: number) {
this._savingNewAnomalyType = true;
await this._anomalyService.postNewAnomalyType(metricExpanded, datasourceRequest, this._newAnomalyType, panelId);
this._anomalyTypesSet.addAnomalyType(this._newAnomalyType);
this._creatingNewAnomalyType = false;
this._savingNewAnomalyType = false;
this.runAnomalyTypeAlertEnabledWaiter(this._newAnomalyType);
this._runAnomalyTypeStatusWaiter(this._newAnomalyType);
async saveNew(metricExpanded: MetricExpanded, datasourceRequest: DatasourceRequest, panelId: number) {
this._savingNewAnalyticUnit = true;
await this._analyticService.postNewAnalyticUnit(metricExpanded, datasourceRequest, this._newAnalyticUnitType, panelId);
this._analyticUnitsSet.addAnomalyType(this._newAnalyticUnitType);
this._creatingNewAnalyticType = false;
this._savingNewAnalyticUnit = false;
this.runEnabledWaiter(this._newAnalyticUnitType);
this._runStatusWaiter(this._newAnalyticUnitType);
}
get creatingAnomalyType() { return this._creatingNewAnomalyType; }
get savingAnomalyType() { return this._savingNewAnomalyType; }
get newAnomalyType(): AnomalyType { return this._newAnomalyType; }
get creatingNew() { return this._creatingNewAnalyticType; }
get saving() { return this._savingNewAnalyticUnit; }
get newAnalyticUnit(): AnalyticUnit { return this._newAnalyticUnitType; }
get graphLocked() { return this._graphLocked; }
set graphLocked(value) {
this._graphLocked = value;
}
set graphLocked(value) { this._graphLocked = value; }
get labelingAnomaly(): AnomalyType {
if(this._selectedAnomalyKey === null) {
get labelingAnomaly(): AnalyticUnit {
if(this._selectedAnalyticUnitKey === null) {
return null;
}
return this._anomalyTypesSet.byKey(this._selectedAnomalyKey);
return this._analyticUnitsSet.byKey(this._selectedAnalyticUnitKey);
}
async toggleAnomalyTypeLabelingMode(key: AnomalyKey) {
async toggleAnomalyTypeLabelingMode(key: AnalyticUnitKey) {
if(this.labelingAnomaly && this.labelingAnomaly.saving) {
throw new Error('Can`t toggel during saving');
}
if(this._selectedAnomalyKey === key) {
return this.disableAnomalyLabeling();
if(this._selectedAnalyticUnitKey === key) {
return this.disableLabeling();
}
await this.disableAnomalyLabeling();
this._selectedAnomalyKey = key;
await this.disableLabeling();
this._selectedAnalyticUnitKey = key;
this.labelingAnomaly.selected = true;
this.toggleAnomalyVisibility(key, true);
this.toggleVisibility(key, true);
}
async disableAnomalyLabeling() {
if(this._selectedAnomalyKey === null) {
async disableLabeling() {
if(this._selectedAnalyticUnitKey === null) {
return;
}
this.labelingAnomaly.saving = true;
@ -118,7 +117,7 @@ export class AnomalyController {
var anomaly = this.labelingAnomaly;
this.dropLabeling();
this._runAnomalyTypeStatusWaiter(anomaly);
this._runStatusWaiter(anomaly);
}
undoLabeling() {
@ -135,12 +134,12 @@ export class AnomalyController {
this._labelingDataAddedSegments.clear();
this._labelingDataDeletedSegments.clear();
this.labelingAnomaly.selected = false;
this._selectedAnomalyKey = null;
this._selectedAnalyticUnitKey = null;
this._tempIdCounted = -1;
}
get labelingMode(): boolean {
return this._selectedAnomalyKey !== null;
return this._selectedAnalyticUnitKey !== null;
}
get labelingDeleteMode(): boolean {
@ -155,37 +154,37 @@ export class AnomalyController {
this._labelingDataAddedSegments.addSegment(asegment);
}
get anomalyTypes(): AnomalyType[] {
return this._anomalyTypesSet.anomalyTypes;
get analyticUnits(): AnalyticUnit[] {
return this._analyticUnitsSet.items;
}
onAnomalyColorChange(key: AnomalyKey, value) {
this._anomalyTypesSet.byKey(key).color = value;
onAnomalyColorChange(key: AnalyticUnitKey, value) {
this._analyticUnitsSet.byKey(key).color = value;
}
fetchAnomalyTypesStatuses() {
this.anomalyTypes.forEach(a => this._runAnomalyTypeStatusWaiter(a));
this.analyticUnits.forEach(a => this._runStatusWaiter(a));
}
async fetchAnomalyTypesSegments(from: number, to: number) {
if(!_.isNumber(from)) {
if(!_.isNumber(+from)) {
throw new Error('from isn`t number');
}
if(!_.isNumber(+to)) {
throw new Error('to isn`t number');
}
var tasks = this.anomalyTypes.map(a => this.fetchSegments(a, from, to));
var tasks = this.analyticUnits.map(a => this.fetchSegments(a, from, to));
return Promise.all(tasks);
}
async fetchSegments(anomalyType: AnomalyType, from: number, to: number): Promise<void> {
if(!_.isNumber(from)) {
async fetchSegments(anomalyType: AnalyticUnit, from: number, to: number): Promise<void> {
if(!_.isNumber(+from)) {
throw new Error('from isn`t number');
}
if(!_.isNumber(+to)) {
throw new Error('to isn`t number');
}
var allSegmentsList = await this._anomalyService.getSegments(anomalyType.key, from, to);
var allSegmentsList = await this._analyticService.getSegments(anomalyType.key, from, to);
var allSegmentsSet = new SegmentArray(allSegmentsList);
if(anomalyType.selected) {
this._labelingDataAddedSegments.getSegments().forEach(s => allSegmentsSet.addSegment(s));
@ -207,7 +206,7 @@ export class AnomalyController {
return [];
}
return this._anomalyService.updateSegments(
return this._analyticService.updateSegments(
anomaly.key, this._labelingDataAddedSegments, this._labelingDataDeletedSegments
);
}
@ -218,8 +217,8 @@ export class AnomalyController {
options.markings = [];
}
for(var i = 0; i < this.anomalyTypes.length; i++) {
var anomalyType = this.anomalyTypes[i];
for(var i = 0; i < this.analyticUnits.length; i++) {
var anomalyType = this.analyticUnits[i];
var borderColor = addAlphaToRGB(anomalyType.color, REGION_STROKE_ALPHA);
var fillColor = addAlphaToRGB(anomalyType.color, REGION_FILL_ALPHA);
var segments = anomalyType.segments.getSegments();
@ -273,13 +272,13 @@ export class AnomalyController {
}
removeAnomalyType(key) {
if(key === this._selectedAnomalyKey) {
if(key === this._selectedAnalyticUnitKey) {
this.dropLabeling();
}
this._anomalyTypesSet.removeAnomalyType(key);
this._analyticUnitsSet.removeAnomalyType(key);
}
private async _runAnomalyTypeStatusWaiter(anomalyType: AnomalyType) {
private async _runStatusWaiter(anomalyType: AnalyticUnit) {
if(anomalyType === undefined || anomalyType === null) {
throw new Error('anomalyType not defined');
}
@ -290,7 +289,7 @@ export class AnomalyController {
this._statusRunners.add(anomalyType.key);
var statusGenerator = this._anomalyService.getAnomalyTypeStatusGenerator(
var statusGenerator = this._analyticService.getAnomalyTypeStatusGenerator(
anomalyType.key, 1000
);
@ -312,18 +311,18 @@ export class AnomalyController {
this._statusRunners.delete(anomalyType.key);
}
async runAnomalyTypeAlertEnabledWaiter(anomalyType: AnomalyType) {
var enabled = await this._anomalyService.getAlertEnabled(anomalyType.key);
async runEnabledWaiter(anomalyType: AnalyticUnit) {
var enabled = await this._analyticService.getAlertEnabled(anomalyType.key);
if(anomalyType.alertEnabled !== enabled) {
anomalyType.alertEnabled = enabled;
this._emitter.emit('anomaly-type-alert-change', anomalyType);
}
}
async toggleAnomalyTypeAlertEnabled(anomalyType: AnomalyType) {
async toggleAnomalyTypeAlertEnabled(anomalyType: AnalyticUnit) {
var enabled = anomalyType.alertEnabled;
anomalyType.alertEnabled = undefined;
await this._anomalyService.setAlertEnabled(anomalyType.key, enabled);
await this._analyticService.setAlertEnabled(anomalyType.key, enabled);
anomalyType.alertEnabled = enabled;
this._emitter.emit('anomaly-type-alert-change', anomalyType);
}
@ -333,8 +332,8 @@ export class AnomalyController {
return this._tempIdCounted;
}
public toggleAnomalyVisibility(key: AnomalyKey, value?: boolean) {
var anomaly = this._anomalyTypesSet.byKey(key);
public toggleVisibility(key: AnalyticUnitKey, value?: boolean) {
var anomaly = this._analyticUnitsSet.byKey(key);
if(value !== undefined) {
anomaly.visible = value;
} else {

37
src/graph_renderer.ts

@ -3,13 +3,14 @@ import { GraphTooltip } from './graph_tooltip';
import { ThresholdManager } from './threshold_manager';
import { convertValuesToHistogram, getSeriesValues } from './histogram';
import {
AnomalyController,
AnalyticController,
REGION_FILL_ALPHA as ANOMALY_REGION_FILL_ALPHA,
REGION_STROKE_ALPHA as ANOMALY_REGION_STROKE_ALPHA,
REGION_DELETE_COLOR_LIGHT as ANOMALY_REGION_DELETE_COLOR_LIGHT,
REGION_DELETE_COLOR_DARK as ANOMALY_REGION_DELETE_COLOR_DARK
} from './controllers/anomaly_controller';
} from './controllers/analytic_controller';
import { GraphCtrl } from './module';
import './vendor/flot/jquery.flot';
import './vendor/flot/jquery.flot.time';
@ -38,14 +39,14 @@ const COLOR_SELECTION = '#666';
export class GraphRenderer {
private _anomalyController: AnomalyController;
private _ananlyticController: AnalyticController;
private data: any;
private tooltip: GraphTooltip;
private thresholdManager: ThresholdManager;
private panelWidth: number;
private plot: any;
private sortedSeries: any;
private ctrl: any;
private ctrl: GraphCtrl;
private dashboard: any;
private panel: any;
// private eventManager;
@ -71,9 +72,9 @@ export class GraphRenderer {
this.contextSrv = contextSrv;
this.scope = scope;
this._anomalyController = this.ctrl.anomalyController;
if(this._anomalyController === undefined) {
throw new Error('anomalyController is undefined');
this._ananlyticController = this.ctrl.analyticsController;
if(this._ananlyticController === undefined) {
throw new Error('ananlyticController is undefined');
}
@ -85,7 +86,7 @@ export class GraphRenderer {
this.thresholdManager = new ThresholdManager(this.ctrl);
this.tooltip = new GraphTooltip(
$elem, this.dashboard, scope, () => this.sortedSeries,
this._anomalyController.getAnomalySegmentsSearcher()
this._ananlyticController.getSegmentsSearcher()
);
// panel events
@ -111,18 +112,18 @@ export class GraphRenderer {
if(this._isAnomalyEvent(selectionEvent)) {
this.plot.clearSelection();
var id = this._anomalyController.getIdForNewLabelSegment()
var id = this._ananlyticController.getIdForNewLabelSegment()
var segment = new Segment(
id,
Math.round(selectionEvent.xaxis.from),
Math.round(selectionEvent.xaxis.to)
);
if(this._anomalyController.labelingDeleteMode) {
this._anomalyController.deleteLabelingAnomalySegmentsInRange(
if(this._ananlyticController.labelingDeleteMode) {
this._ananlyticController.deleteLabelingAnomalySegmentsInRange(
segment.from, segment.to
);
} else {
this._anomalyController.addLabelSegment(segment);
this._ananlyticController.addLabelSegment(segment);
}
this._renderPanel();
return;
@ -186,12 +187,12 @@ export class GraphRenderer {
});
$elem.mousedown(e => {
this._anomalyController.graphLocked = true;
this._ananlyticController.graphLocked = true;
this._chooseSelectionColor(e);
});
$(document).mouseup(e => {
this._anomalyController.graphLocked = false;
this._ananlyticController.graphLocked = false;
})
}
@ -336,7 +337,7 @@ export class GraphRenderer {
this._configureYAxisOptions(this.data);
this.thresholdManager.addFlotOptions(this.flotOptions, this.panel);
// this.eventManager.addFlotEvents(this.annotations, this.flotOptions);
this._anomalyController.updateFlotEvents(this.contextSrv.isEditor, this.flotOptions);
this._ananlyticController.updateFlotEvents(this.contextSrv.isEditor, this.flotOptions);
this.sortedSeries = this._sortSeries(this.data, this.panel);
this._callPlot(true);
@ -347,12 +348,12 @@ export class GraphRenderer {
var fillAlpha = 0.4;
var strokeAlpha = 0.4;
if(this._isAnomalyEvent(e)) {
if(this._anomalyController.labelingDeleteMode) {
if(this._ananlyticController.labelingDeleteMode) {
color = this.contextSrv.user.lightTheme ?
ANOMALY_REGION_DELETE_COLOR_LIGHT :
ANOMALY_REGION_DELETE_COLOR_DARK;
} else {
color = this._anomalyController.labelingAnomaly.color;
color = this._ananlyticController.labelingAnomaly.color;
}
fillAlpha = ANOMALY_REGION_FILL_ALPHA;
strokeAlpha = ANOMALY_REGION_STROKE_ALPHA;
@ -814,7 +815,7 @@ export class GraphRenderer {
private _isAnomalyEvent(obj: any) {
return (obj.ctrlKey || obj.metaKey) &&
this.contextSrv.isEditor &&
this._anomalyController.labelingMode;
this._ananlyticController.labelingMode;
}
}

4
src/graph_tooltip.ts

@ -1,4 +1,4 @@
import { AnomalyType, AnomalySegment, AnomalySegmentsSearcher } from "model/anomaly";
import { AnalyticSegmentsSearcher } from "model/analytic_unit";
export class GraphTooltip {
@ -11,7 +11,7 @@ export class GraphTooltip {
constructor(
private $elem: JQuery<HTMLElement>, private dashboard,
private scope, private getSeriesFn,
private _anomalySegmentsSearcher: AnomalySegmentsSearcher
private _anomalySegmentsSearcher: AnalyticSegmentsSearcher
) {
this.ctrl = scope.ctrl;
this.panel = this.ctrl.panel;

69
src/model/anomaly.ts → src/model/analytic_unit.ts

@ -5,12 +5,12 @@ import { Metric } from './metric';
import _ from 'lodash';
export type AnomalySermentPair = { anomalyType: AnomalyType, segment: AnomalySegment };
export type AnomalySegmentsSearcher = (point: number, rangeDist: number) => AnomalySermentPair[];
export type AnalyticSegmentPair = { anomalyType: AnalyticUnit, segment: AnalyticSegment };
export type AnalyticSegmentsSearcher = (point: number, rangeDist: number) => AnalyticSegmentPair[];
export type AnomalyKey = string;
export type AnalyticUnitKey = string;
export class AnomalySegment extends Segment {
export class AnalyticSegment extends Segment {
constructor(public labeled: boolean, key: SegmentKey, from: number, to: number) {
super(key, from, to);
if(!_.isBoolean(labeled)) {
@ -19,12 +19,12 @@ export class AnomalySegment extends Segment {
}
}
export class AnomalyType {
export class AnalyticUnit {
private _selected: boolean = false;
private _deleteMode: boolean = false;
private _saving: boolean = false;
private _segmentSet = new SegmentArray<AnomalySegment>();
private _segmentSet = new SegmentArray<AnalyticSegment>();
private _status: string;
private _error: string;
private _metric: Metric;
@ -42,7 +42,7 @@ export class AnomalyType {
//this._metric = new Metric(_panelObject.metric);
}
get key(): AnomalyKey { return this.name; }
get key(): AnalyticUnitKey { return this.name; }
set name(value: string) { this._panelObject.name = value; }
get name(): string { return this._panelObject.name; }
@ -74,18 +74,18 @@ export class AnomalyType {
get metric() { return this._metric; }
addLabeledSegment(segment: Segment): AnomalySegment {
var asegment = new AnomalySegment(true, segment.key, segment.from, segment.to);
addLabeledSegment(segment: Segment): AnalyticSegment {
var asegment = new AnalyticSegment(true, segment.key, segment.from, segment.to);
this._segmentSet.addSegment(asegment);
return asegment;
}
removeSegmentsInRange(from: number, to: number): AnomalySegment[] {
removeSegmentsInRange(from: number, to: number): AnalyticSegment[] {
return this._segmentSet.removeInRange(from, to);
}
get segments(): SegmentsSet<AnomalySegment> { return this._segmentSet; }
set segments(value: SegmentsSet<AnomalySegment>) {
get segments(): SegmentsSet<AnalyticSegment> { return this._segmentSet; }
set segments(value: SegmentsSet<AnalyticSegment>) {
this._segmentSet.setSegments(value.getSegments());
}
@ -111,56 +111,51 @@ export class AnomalyType {
get panelObject() { return this._panelObject; }
get alertEnabled(): boolean {
return this._alertEnabled;
}
set alertEnabled(value) {
this._alertEnabled = value;
}
get alertEnabled(): boolean { return this._alertEnabled; }
set alertEnabled(value) { this._alertEnabled = value;}
}
export class AnomalyTypesSet {
export class AnalyticUnitsSet {
private _mapAnomalyKeyIndex: Map<AnomalyKey, number>;
private _anomalyTypes: AnomalyType[];
private _mapKeyIndex: Map<AnalyticUnitKey, number>;
private _items: AnalyticUnit[];
constructor(private _panelObject: any[]) {
if(_panelObject === undefined) {
throw new Error('panel object can`t be undefined');
}
this._mapAnomalyKeyIndex = new Map<AnomalyKey, number>();
this._anomalyTypes = _panelObject.map(p => new AnomalyType(p));
this._mapKeyIndex = new Map<AnalyticUnitKey, number>();
this._items = _panelObject.map(p => new AnalyticUnit(p));
this._rebuildIndex();
}
get anomalyTypes() { return this._anomalyTypes; }
get items() { return this._items; }
addAnomalyType(anomalyType: AnomalyType) {
addAnomalyType(anomalyType: AnalyticUnit) {
this._panelObject.push(anomalyType.panelObject);
this._mapAnomalyKeyIndex[anomalyType.name] = this._anomalyTypes.length;
this._anomalyTypes.push(anomalyType);
this._mapKeyIndex[anomalyType.name] = this._items.length;
this._items.push(anomalyType);
}
removeAnomalyType(key: AnomalyKey) {
var index = this._mapAnomalyKeyIndex[key];
removeAnomalyType(key: AnalyticUnitKey) {
var index = this._mapKeyIndex[key];
this._panelObject.splice(index, 1);
this._anomalyTypes.splice(index, 1);
this._items.splice(index, 1);
this._rebuildIndex();
}
_rebuildIndex() {
this._anomalyTypes.forEach((a, i) => {
this._mapAnomalyKeyIndex[a.key] = i;
this._items.forEach((a, i) => {
this._mapKeyIndex[a.key] = i;
});
}
byKey(key: AnomalyKey): AnomalyType {
return this._anomalyTypes[this._mapAnomalyKeyIndex[key]];
byKey(key: AnalyticUnitKey): AnalyticUnit {
return this._items[this._mapKeyIndex[key]];
}
byIndex(index: number): AnomalyType {
return this._anomalyTypes[index];
byIndex(index: number): AnalyticUnit {
return this._items[index];
}
}

68
src/module.ts

@ -6,11 +6,11 @@ import template from './template';
import { GraphRenderer } from './graph_renderer';
import { GraphLegend } from './graph_legend';
import { DataProcessor } from './data_processor';
import { Metric, MetricExpanded } from './model/metric';
import { MetricExpanded } from './model/metric';
import { DatasourceRequest } from './model/datasource';
import { AnomalyKey, AnomalyType } from './model/anomaly';
import { AnomalyService } from './services/anomaly_service';
import { AnomalyController } from './controllers/anomaly_controller';
import { AnalyticUnitKey, AnalyticUnit } from './model/analytic_unit';
import { AnalyticService } from './services/analytic_service';
import { AnalyticController } from './controllers/analytic_controller';
import { axesEditorComponent } from './axes_editor';
@ -34,6 +34,7 @@ class GraphCtrl extends MetricsPanelCtrl {
alertState: any;
_panelPath: any;
_renderError: boolean = false;
annotationsPromise: any;
dataWarning: any;
@ -44,7 +45,7 @@ class GraphCtrl extends MetricsPanelCtrl {
datasourceRequest: DatasourceRequest;
patterns: Array<String> = ['General', 'Drops', 'Peaks', 'Jumps'];
anomalyTypes = []; // TODO: remove it later. Only for alert tab
anomalyController: AnomalyController;
analyticsController: AnalyticController;
_graphRenderer: GraphRenderer;
_graphLegend: GraphLegend;
@ -151,11 +152,11 @@ class GraphCtrl extends MetricsPanelCtrl {
this.processor = new DataProcessor(this.panel);
var anomalyService = new AnomalyService(this.backendURL, backendSrv as BackendSrv);
var anomalyService = new AnalyticService(this.backendURL, backendSrv as BackendSrv);
this.runBackendConnectivityCheck();
this.anomalyController = new AnomalyController(this.panel, anomalyService, this.events);
this.analyticsController = new AnalyticController(this.panel, anomalyService, this.events);
this.anomalyTypes = this.panel.anomalyTypes;
keybindingSrv.bind('d', this.onDKey.bind(this));
@ -168,12 +169,12 @@ class GraphCtrl extends MetricsPanelCtrl {
this.events.on('anomaly-type-alert-change', () => {
this.$scope.$digest()
});
this.events.on('anomaly-type-status-change', async (anomalyType: AnomalyType) => {
this.events.on('anomaly-type-status-change', async (anomalyType: AnalyticUnit) => {
if(anomalyType === undefined) {
throw new Error('anomalyType is undefined');
}
if(anomalyType.status === 'ready') {
await this.anomalyController.fetchSegments(anomalyType, +this.range.from, +this.range.to);
await this.analyticsController.fetchSegments(anomalyType, +this.range.from, +this.range.to);
}
this.render(this.seriesList);
this.$scope.$digest();
@ -189,7 +190,7 @@ class GraphCtrl extends MetricsPanelCtrl {
};
});
this.anomalyController.fetchAnomalyTypesStatuses();
this.analyticsController.fetchAnomalyTypesStatuses();
}
@ -210,7 +211,7 @@ class GraphCtrl extends MetricsPanelCtrl {
return;
}
var as = new AnomalyService(this.backendURL, this.backendSrv);
var as = new AnalyticService(this.backendURL, this.backendSrv);
var isOK = await as.isBackendOk();
if(!isOK) {
this.alertSrv.set(
@ -307,7 +308,7 @@ class GraphCtrl extends MetricsPanelCtrl {
var loadTasks = [
this.annotationsPromise,
this.anomalyController.fetchAnomalyTypesSegments(+this.range.from, +this.range.to)
this.analyticsController.fetchAnomalyTypesSegments(+this.range.from, +this.range.to)
];
var results = await Promise.all(loadTasks);
@ -382,7 +383,7 @@ class GraphCtrl extends MetricsPanelCtrl {
}
}
if(!this.anomalyController.graphLocked) {
if(!this.analyticsController.graphLocked) {
this._graphLegend.render();
this._graphRenderer.render(data);
}
@ -509,13 +510,13 @@ class GraphCtrl extends MetricsPanelCtrl {
return this._panelPath;
}
createNewAnomalyType() {
this.anomalyController.createAnomalyType();
createNew() {
this.analyticsController.createNew();
}
async saveAnomalyType() {
async saveNew() {
this.refresh();
await this.anomalyController.saveNewAnomalyType(
await this.analyticsController.saveNew(
new MetricExpanded(this.panel.datasource, this.panel.targets),
this.datasourceRequest,
this.panel.id
@ -524,17 +525,17 @@ class GraphCtrl extends MetricsPanelCtrl {
this.render(this.seriesList);
}
onAnomalyColorChange(key: AnomalyKey, value) {
this.anomalyController.onAnomalyColorChange(key, value);
onColorChange(key: AnalyticUnitKey, value) {
this.analyticsController.onAnomalyColorChange(key, value);
this.render();
}
onAnomalyRemove(key) {
this.anomalyController.removeAnomalyType(key as string);
onRemove(key) {
this.analyticsController.removeAnomalyType(key as string);
this.render();
}
onAnomalyCancelLabeling(key) {
onCancelLabeling(key) {
this.$scope.$root.appEvent('confirm-modal', {
title: 'Clear anomaly labeling',
text2: 'Your changes will be lost.',
@ -542,36 +543,39 @@ class GraphCtrl extends MetricsPanelCtrl {
icon: 'fa-warning',
altActionText: 'Save',
onAltAction: () => {
this.onToggleAnomalyTypeLabelingMode(key);
this.onToggleLabelingMode(key);
},
onConfirm: () => {
this.anomalyController.undoLabeling();
this.analyticsController.undoLabeling();
this.render();
},
});
}
async onToggleAnomalyTypeLabelingMode(key) {
await this.anomalyController.toggleAnomalyTypeLabelingMode(key as AnomalyKey);
async onToggleLabelingMode(key) {
await this.analyticsController.toggleAnomalyTypeLabelingMode(key as AnalyticUnitKey);
this.$scope.$digest();
this.render();
}
onDKey() {
if(!this.anomalyController.labelingMode) {
if(!this.analyticsController.labelingMode) {
return;
}
this.anomalyController.toggleDeleteMode();
this.analyticsController.toggleDeleteMode();
}
onAnomalyAlertChange(anomalyType: AnomalyType) {
this.anomalyController.toggleAnomalyTypeAlertEnabled(anomalyType);
onAnomalyAlertChange(anomalyType: AnalyticUnit) {
this.analyticsController.toggleAnomalyTypeAlertEnabled(anomalyType);
}
onAnomalyToggleVisibility(key: AnomalyKey) {
this.anomalyController.toggleAnomalyVisibility(key);
onToggleVisibility(key: AnalyticUnitKey) {
this.analyticsController.toggleVisibility(key);
this.render();
}
get renderError(): boolean { return this._renderError; }
set renderError(value: boolean) { this._renderError = value; }
}
export { GraphCtrl, GraphCtrl as PanelCtrl };

85
src/partials/tab_analytics.html

@ -1,18 +1,18 @@
<h5> Anomaly Types </h5>
<h5> Analytic Units </h5>
<div class="editor-row">
<div class="gf-form" ng-repeat="anomalyType in ctrl.anomalyController.anomalyTypes">
<div class="gf-form" ng-repeat="analyticUnit in ctrl.analyticsController.analyticUnits">
<label class="gf-form-label width-4"> Name </label>
<input
type="text" class="gf-form-input max-width-15"
ng-model="anomalyType.name"
ng-model="analyticUnit.name"
ng-disabled="true"
>
<label class="gf-form-label width-8"> Pattern type </label>
<label class="gf-form-label width-8"> Type </label>
<div class="gf-form-select-wrapper">
<select class="gf-form-input width-12"
ng-model="anomalyType.pattern"
ng-model="analyticUnit.pattern"
ng-options="pattern as pattern for pattern in ctrl.patterns"
ng-disabled="true"
/>
@ -30,21 +30,21 @@
<label class="gf-form-label width-6"> Color </label>
<span class="gf-form-label">
<color-picker
color="anomalyType.color"
onChange="ctrl.onAnomalyColorChange.bind(ctrl, anomalyType.key)"
color="analyticUnit.color"
onChange="ctrl.onAnomalyColorChange.bind(ctrl, analyticUnit.key)"
/>
</span>
<label class="gf-form-label" ng-style="anomalyType.status === 'learning' && { 'cursor': 'not-allowed' }">
<label class="gf-form-label" ng-style="analyticUnit.status === 'learning' && { 'cursor': 'not-allowed' }">
<a class="pointer" tabindex="1"
ng-click="ctrl.onToggleAnomalyTypeLabelingMode(anomalyType.key)"
ng-disabled="anomalyType.status === 'learning'"
ng-click="ctrl.onToggleLabelingMode(analyticUnit.key)"
ng-disabled="analyticUnit.status === 'learning'"
>
<i class="fa fa-bar-chart" ng-if="!anomalyType.saving"></i>
<i class="fa fa-spinner fa-spin" ng-if="anomalyType.saving"></i>
<b ng-if="anomalyType.selected && !anomalyType.deleteMode && !anomalyType.saving"> labeling </b>
<b ng-if="anomalyType.selected && anomalyType.deleteMode && !anomalyType.saving"> deleting </b>
<b ng-if="anomalyType.saving" ng-disabled="true"> saving... </b>
<i class="fa fa-bar-chart" ng-if="!analyticUnit.saving"></i>
<i class="fa fa-spinner fa-spin" ng-if="analyticUnit.saving"></i>
<b ng-if="analyticUnit.selected && !analyticUnit.deleteMode && !analyticUnit.saving"> labeling </b>
<b ng-if="analyticUnit.selected && analyticUnit.deleteMode && !analyticUnit.saving"> deleting </b>
<b ng-if="analyticUnit.saving" ng-disabled="true"> saving... </b>
</a>
</label>
@ -53,35 +53,35 @@
<label
class="gf-form-label text-center"
style="width: 4rem"
ng-if="anomalyType.alertEnabled === undefined"
ng-if="analyticUnit.alertEnabled === undefined"
bs-tooltip="'Alarting status isn`t available. Wait please.'"
>
<i class="fa fa-spinner fa-spin"></i>
</label>
<gf-form-switch
ng-if="anomalyType.alertEnabled !== undefined"
on-change="ctrl.onAnomalyAlertChange(anomalyType)"
checked="anomalyType.alertEnabled"
ng-if="analyticUnit.alertEnabled !== undefined"
on-change="ctrl.onAnomalyAlertChange(analyticUnit)"
checked="analyticUnit.alertEnabled"
style="height: 36px;"
/>
<label class="gf-form-label">
<a
ng-if="anomalyType.visible"
ng-disabled="anomalyType.selected"
ng-if="analyticUnit.visible"
ng-disabled="analyticUnit.selected"
bs-tooltip="'Hide. It`s visible now.'"
ng-click="ctrl.onAnomalyToggleVisibility(anomalyType.key)"
ng-click="ctrl.onToggleVisibility(analyticUnit.key)"
class="pointer"
>
<i class="fa fa-eye"></i>
</a>
<a
ng-if="!anomalyType.visible"
ng-disabled="anomalyType.selected"
ng-if="!analyticUnit.visible"
ng-disabled="analyticUnit.selected"
bs-tooltip="'Show. It`s hidden now.'"
ng-click="ctrl.onAnomalyToggleVisibility(anomalyType.key)"
ng-click="ctrl.onToggleVisibility(analyticUnit.key)"
class="pointer"
>
<i class="fa fa-eye-slash"></i>
@ -90,16 +90,16 @@
<label class="gf-form-label">
<a
ng-if="!anomalyType.selected"
ng-click="ctrl.onAnomalyRemove(anomalyType.key)"
ng-if="!analyticUnit.selected"
ng-click="ctrl.onRemove(analyticUnit.key)"
class="pointer"
>
<i class="fa fa-trash"></i>
</a>
<a
ng-if="anomalyType.selected"
ng-click="ctrl.onAnomalyCancelLabeling(anomalyType.key)"
ng-if="analyticUnit.selected"
ng-click="ctrl.onCancelLabeling(analyticUnit.key)"
class="pointer"
>
<i class="fa fa-ban"></i>
@ -107,43 +107,42 @@
</label>
<label>
<i ng-if="anomalyType.status === 'learning'" class="grafana-tip fa fa-leanpub ng-scope" bs-tooltip="'Learning'"></i>
<i ng-if="anomalyType.status === 'pending'" class="grafana-tip fa fa-list-ul ng-scope" bs-tooltip="'Pending'"></i>
<i ng-if="anomalyType.status === 'failed'" class="grafana-tip fa fa-exclamation-circle ng-scope" bs-tooltip="'Error: ' + anomalyType.error"></i>
<i ng-if="analyticUnit.status === 'learning'" class="grafana-tip fa fa-leanpub ng-scope" bs-tooltip="'Learning'"></i>
<i ng-if="analyticUnit.status === 'pending'" class="grafana-tip fa fa-list-ul ng-scope" bs-tooltip="'Pending'"></i>
<i ng-if="analyticUnit.status === 'failed'" class="grafana-tip fa fa-exclamation-circle ng-scope" bs-tooltip="'Error: ' + analyticUnit.error"></i>
</label>
</div>
</div>
<div class="editor-row" ng-if="ctrl.anomalyController.creatingAnomalyType">
<div class="editor-row" ng-if="ctrl.analyticsController.creatingNew">
<div class="gf-form">
<label class="gf-form-label width-4"> Name </label>
<input
type="text" class="gf-form-input max-width-15"
ng-model="ctrl.anomalyController.newAnomalyType.name"
ng-change="ctrl.onAnomalyNameChange()"
ng-model="ctrl.analyticsController.newAnalyticUnit.name"
>
<label class="gf-form-label width-8"> Pattern type </label>
<label class="gf-form-label width-8"> Type </label>
<div class="gf-form-select-wrapper">
<select class="gf-form-input width-12"
ng-model="ctrl.anomalyController.newAnomalyType.pattern"
ng-model="ctrl.analyticsController.newAnalyticUnit.pattern"
ng-options="pattern as pattern disable when (pattern !== 'General' && pattern !== 'Drops' && pattern !== 'Peaks') for pattern in ctrl.patterns"
/>
</div>
<label class="gf-form-label">
<a class="pointer" tabindex="1" ng-click="ctrl.saveAnomalyType()">
<b ng-if="!ctrl.anomalyController.savingAnomalyType"> create </b>
<b ng-if="ctrl.anomalyController.savingAnomalyType" ng-disabled="true"> saving... </b>
<a class="pointer" tabindex="1" ng-click="ctrl.saveNew()">
<b ng-if="!ctrl.analyticsController.saving"> create </b>
<b ng-if="ctrl.analyticsController.saving" ng-disabled="true"> saving... </b>
</a>
</label>
</div>
</div>
<div class="gf-form-button-row" ng-if="!ctrl.anomalyController.creatingAnomalyType">
<button class="btn btn-inverse" ng-click="ctrl.createNewAnomalyType()">
<div class="gf-form-button-row" ng-if="!ctrl.analyticsController.creatingAnalyticUnit">
<button class="btn btn-inverse" ng-click="ctrl.createNew()">
<i class="fa fa-plus"></i>
Add an Anomaly Type
Add Analytic Unit
</button>
</div>

18
src/services/anomaly_service.ts → src/services/analytic_service.ts

@ -2,17 +2,17 @@ import { Segment, SegmentKey } from '../model/segment';
import { MetricExpanded } from '../model/metric';
import { DatasourceRequest } from '../model/datasource';
import { SegmentsSet } from '../model/segment_set';
import { AnomalyKey, AnomalyType, AnomalySegment } from '../model/anomaly';
import { AnalyticUnitKey, AnalyticUnit, AnalyticSegment } from '../model/analytic_unit';
import { BackendSrv } from 'grafana/app/core/services/backend_srv';
export class AnomalyService {
export class AnalyticService {
constructor(private _backendURL: string, private _backendSrv: BackendSrv) {
}
async postNewAnomalyType(metric: MetricExpanded, datasourceRequest: DatasourceRequest, newAnomalyType: AnomalyType, panelId: number) {
async postNewAnalyticUnit(metric: MetricExpanded, datasourceRequest: DatasourceRequest, newAnomalyType: AnalyticUnit, panelId: number) {
return this._backendSrv.post(
this._backendURL + '/anomalies',
{
@ -35,7 +35,7 @@ export class AnomalyService {
}
async updateSegments(
key: AnomalyKey, addedSegments: SegmentsSet<Segment>, removedSegments: SegmentsSet<Segment>
key: AnalyticUnitKey, addedSegments: SegmentsSet<Segment>, removedSegments: SegmentsSet<Segment>
): Promise<SegmentKey[]> {
const getJSONs = (segs: SegmentsSet<Segment>) => segs.getSegments().map(segment => ({
@ -57,7 +57,7 @@ export class AnomalyService {
return data.added_ids as SegmentKey[];
}
async getSegments(key: AnomalyKey, from?: number, to?: number): Promise<AnomalySegment[]> {
async getSegments(key: AnalyticUnitKey, from?: number, to?: number): Promise<AnalyticSegment[]> {
var payload: any = { predictor_id: key };
if(from !== undefined) {
payload['from'] = from;
@ -73,10 +73,10 @@ export class AnomalyService {
throw new Error('Server didn`t return segments array');
}
var segments = data.segments as { id: number, start: number, finish: number, labeled: boolean }[];
return segments.map(s => new AnomalySegment(s.labeled, s.id, s.start, s.finish));
return segments.map(s => new AnalyticSegment(s.labeled, s.id, s.start, s.finish));
}
async * getAnomalyTypeStatusGenerator(key: AnomalyKey, duration: number) {
async * getAnomalyTypeStatusGenerator(key: AnalyticUnitKey, duration: number) {
let statusCheck = async () => {
var data = await this._backendSrv.get(
this._backendURL + '/anomalies/status', { name: key }
@ -95,7 +95,7 @@ export class AnomalyService {
}
async getAlertEnabled(key: AnomalyKey): Promise<boolean> {
async getAlertEnabled(key: AnalyticUnitKey): Promise<boolean> {
var data = await this._backendSrv.get(
this._backendURL + '/alerts', { predictor_id: key }
);
@ -103,7 +103,7 @@ export class AnomalyService {
}
async setAlertEnabled(key: AnomalyKey, value: boolean): Promise<void> {
async setAlertEnabled(key: AnalyticUnitKey, value: boolean): Promise<void> {
return this._backendSrv.post(
this._backendURL + '/alerts', { predictor_id: key, enable: value }
);
Loading…
Cancel
Save