Browse Source

WIP Display anti-segments #66 (#67)

* WIP

* Render deleted segments and trash icon in tooltip
master
rozetko 6 years ago committed by Alexey Velikiy
parent
commit
6f9ac9245b
  1. 26
      src/controllers/analytic_controller.ts
  2. 28
      src/graph_tooltip.ts
  3. 10
      src/models/analytic_unit.ts
  4. 1
      src/module.ts
  5. 10
      src/services/analytic_service.ts

26
src/controllers/analytic_controller.ts

@ -24,6 +24,8 @@ export const REGION_STROKE_ALPHA = 0.9;
export const REGION_DELETE_COLOR_LIGHT = '#d1d1d1';
export const REGION_DELETE_COLOR_DARK = 'white';
const LABELED_SEGMENT_BORDER_COLOR = 'black';
const DELETED_SEGMENT_FILL_COLOR = 'black';
const DELETED_SEGMENT_BORDER_COLOR = 'black';
export class AnalyticController {
@ -59,7 +61,7 @@ export class AnalyticController {
this._analyticUnitsSet.items.forEach(at => {
var segs = at.segments.findSegments(point, rangeDist);
segs.forEach(s => {
result.push({ anomalyType: at, segment: s });
result.push({ analyticUnit: at, segment: s });
})
})
return result;
@ -125,7 +127,8 @@ export class AnalyticController {
var newIds = await this._saveLabelingData();
this._labelingDataAddedSegments.getSegments().forEach((s, i) => {
this.labelingAnomaly.segments.updateId(s.id, newIds[i]);
})
});
this.labelingAnomaly.saving = false;
var anomaly = this.labelingAnomaly;
@ -138,7 +141,7 @@ export class AnalyticController {
this.labelingAnomaly.segments.remove(s.id);
});
this._labelingDataDeletedSegments.getSegments().forEach(s => {
this.labelingAnomaly.segments.addSegment(s);
s.deleted = false;
});
this.dropLabeling();
}
@ -254,18 +257,32 @@ export class AnalyticController {
let labeledSegmentBorderColor = tinycolor(LABELED_SEGMENT_BORDER_COLOR).toRgbString();
labeledSegmentBorderColor = addAlphaToRGB(labeledSegmentBorderColor, REGION_STROKE_ALPHA);
let deletedSegmentFillColor = tinycolor(DELETED_SEGMENT_FILL_COLOR).toRgbString();
deletedSegmentFillColor = addAlphaToRGB(deletedSegmentFillColor, REGION_STROKE_ALPHA);
let deletedSegmentBorderColor = tinycolor(DELETED_SEGMENT_BORDER_COLOR).toRgbString();
deletedSegmentBorderColor = addAlphaToRGB(deletedSegmentBorderColor, REGION_STROKE_ALPHA);
segments.forEach(s => {
let segmentBorderColor;
let segmentFillColor = fillColor;
if(s.labeled) {
segmentBorderColor = labeledSegmentBorderColor;
} else {
segmentBorderColor = borderColor;
}
if(this.labelingDeleteMode) {
if(s.deleted) {
segmentBorderColor = deletedSegmentBorderColor;
segmentFillColor = deletedSegmentFillColor;
}
}
var expanded = s.expandDist(rangeDist, 0.01);
options.grid.markings.push({
xaxis: { from: expanded.from, to: expanded.to },
color: fillColor
color: segmentFillColor
});
options.grid.markings.push({
xaxis: { from: expanded.from, to: expanded.from },
@ -281,7 +298,6 @@ export class AnalyticController {
}
deleteLabelingAnomalySegmentsInRange(from: number, to: number) {
console.log('deleteLabelingAnomalySegmentsInRange was called')
var allRemovedSegs = this.labelingAnomaly.removeSegmentsInRange(from, to);
allRemovedSegs.forEach(s => {
if(!this._labelingDataAddedSegments.has(s.id)) {

28
src/graph_tooltip.ts

@ -10,7 +10,7 @@ export class GraphTooltip {
private _lastItem = undefined;
constructor(
private $elem: JQuery<HTMLElement>, private dashboard,
private $elem: JQuery<HTMLElement>, private dashboard,
private scope, private getSeriesFn,
private _anomalySegmentsSearcher: AnalyticSegmentsSearcher
) {
@ -53,7 +53,7 @@ export class GraphTooltip {
}
pos.pageX = this.$elem.offset().left + pointOffset.left;
pos.pageY = this.$elem.offset().top + this.$elem.height() * pos.panelRelY;
var isVisible = pos.pageY >= $(window).scrollTop() &&
var isVisible = pos.pageY >= $(window).scrollTop() &&
pos.pageY <= $(window).innerHeight() + $(window).scrollTop();
if (!isVisible) {
this.clear(plot);
@ -148,7 +148,7 @@ export class GraphTooltip {
}
};
destroy() {
this._visible = false;
this.$tooltip.remove();
@ -199,21 +199,31 @@ export class GraphTooltip {
segments.forEach(s => {
var from = this.dashboard.formatDate(s.segment.from, 'HH:mm:ss.SSS');
var to = this.dashboard.formatDate(s.segment.to, 'HH:mm:ss.SSS');
if(s.segment.deleted && !s.analyticUnit.deleteMode) {
return;
}
let icon;
if (s.segment.labeled) {
icon = 'fa-thumb-tack';
} else if (s.segment.deleted) {
icon = 'fa-trash';
} else {
icon = 'fa-search-plus';
}
result += `
<div class="graph-tooltip-list-item">
<div class="graph-tooltip-series-name">
<i class="fa fa-exclamation" style="color:${s.anomalyType.color}"></i>
${s.anomalyType.name}:
<i class="fa fa-exclamation" style="color:${s.analyticUnit.color}"></i>
${s.analyticUnit.name}:
</div>
<div class="graph-tooltip-value">
<i class="fa ${ s.segment.labeled ? "fa-thumb-tack" : "fa-search-plus" }" aria-hidden="true"></i>
<i class="fa ${ icon }" aria-hidden="true"></i>
${from} ${to}
</div>
</div>
`;
});
return result;
}

10
src/models/analytic_unit.ts

@ -8,13 +8,13 @@ import { ANALYTIC_UNIT_COLORS } from '../colors';
import _ from 'lodash';
export type AnalyticSegmentPair = { anomalyType: AnalyticUnit, segment: AnalyticSegment };
export type AnalyticSegmentPair = { analyticUnit: AnalyticUnit, segment: AnalyticSegment };
export type AnalyticSegmentsSearcher = (point: number, rangeDist: number) => AnalyticSegmentPair[];
export type AnalyticUnitId = string;
export class AnalyticSegment extends Segment {
constructor(public labeled: boolean, id: SegmentId, from: number, to: number) {
constructor(public labeled: boolean, id: SegmentId, from: number, to: number, public deleted = false) {
super(id, from, to);
if(!_.isBoolean(labeled)) {
throw new Error('labeled value is not boolean');
@ -85,7 +85,11 @@ export class AnalyticUnit {
}
removeSegmentsInRange(from: number, to: number): AnalyticSegment[] {
return this._segmentSet.removeInRange(from, to);
let deletedSegments = this._segmentSet.removeInRange(from, to);
deletedSegments.forEach(s => {
s.deleted = true;
});
return deletedSegments;
}
get segments(): SegmentsSet<AnalyticSegment> { return this._segmentSet; }

1
src/module.ts

@ -576,6 +576,7 @@ class GraphCtrl extends MetricsPanelCtrl {
return;
}
this.analyticsController.toggleDeleteMode();
this.refresh();
}
onAnomalyAlertChange(anomalyType: AnalyticUnit) {

10
src/services/analytic_service.ts

@ -42,15 +42,15 @@ export class AnalyticService {
): Promise<SegmentId[]> {
const getJSONs = (segs: SegmentsSet<Segment>) => segs.getSegments().map(segment => ({
"from": segment.from,
"to": segment.to
from: segment.from,
to: segment.to
}));
var payload = {
id,
addedSegments: getJSONs(addedSegments),
removedSegments: removedSegments.getSegments().map(s => s.id)
}
};
var data = await this._backendSrv.patch(this._backendURL + '/segments', payload);
if(data.addedIds === undefined) {
@ -75,8 +75,8 @@ export class AnalyticService {
if(data.segments === undefined) {
throw new Error('Server didn`t return segments array');
}
var segments = data.segments as { id: SegmentId, from: number, to: number, labeled: boolean }[];
return segments.map(s => new AnalyticSegment(s.labeled, s.id, s.from, s.to));
var segments = data.segments as { id: SegmentId, from: number, to: number, labeled: boolean, deleted: boolean }[];
return segments.map(s => new AnalyticSegment(s.labeled, s.id, s.from, s.to, s.deleted));
}
async * getStatusGenerator(id: AnalyticUnitId, duration: number) {

Loading…
Cancel
Save