Browse Source

copy types from hastic-grafana-app

pull/25/head
Alexey Velikiy 3 years ago
parent
commit
cecc19f1a7
  1. 2
      client/package.json
  2. 6
      client/src/components/hastic_pod/index.ts
  3. 195
      client/src/types/analytic_units/index.ts
  4. 105
      client/src/types/colors.ts
  5. 20
      client/src/types/detection.ts
  6. 36
      client/src/types/segment.ts
  7. 101
      client/src/types/segment_array.ts
  8. 14
      client/src/types/segment_set.ts
  9. 6
      client/src/types/user.ts
  10. 10
      client/yarn.lock

2
client/package.json

@ -12,8 +12,10 @@
"@chartwerk/line-pod": "^0.4.0",
"@kyvg/vue3-notification": "^2.3.4",
"@types/lodash": "^4.14.176",
"@types/tinycolor2": "^1.4.3",
"axios": "^0.23.0",
"lodash": "^4.17.21",
"tinycolor2": "^1.4.2",
"vue": "^3.0.0",
"vue-class-component": "^8.0.0-0",
"vue-router": "^4.0.0-0",

6
client/src/components/hastic_pod/index.ts

@ -109,13 +109,13 @@ export class HasticPod extends LinePod {
const x = this.xScale(from);
const y = 0;
const w = 100;
const h = 100;
const w = this.xScale(to) - x;
const h = this.height
const r = this.chartContainer
.append('rect')
.attr('x', x)
.attr('y', x)
.attr('y', y)
.attr('width', w)
.attr('height', h)
.attr('fill', 'red')

195
client/src/types/analytic_units/index.ts

@ -0,0 +1,195 @@
import { SegmentsSet } from '@/types/segment_set';
import { SegmentArray } from '@/types/segment_array';
import { Segment, SegmentId } from '@/types/segment';
import { DetectionSpan } from '../detection';
import { ANALYTIC_UNIT_COLORS, DEFAULT_DELETED_SEGMENT_COLOR } from '@/types/colors';
import _ from 'lodash';
// TODO: move types to ./types
export enum DetectorType {
PATTERN = 'pattern',
THRESHOLD = 'threshold',
ANOMALY = 'anomaly'
};
export enum LabelingMode {
LABELING = 'LABELING',
UNLABELING = 'UNLABELING',
DELETING = 'DELETING',
NOT_IN_LABELING_MODE = 'NOT_IN_LABELING_MODE'
};
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, public deleted = false) {
super(id, from, to);
if(!_.isBoolean(this.labeled)) {
throw new Error('labeled value is not boolean');
}
if(labeled && deleted) {
throw new Error('Segment can`t be both labeled and deleted');
}
}
}
const DEFAULTS = {
id: null,
name: 'AnalyticUnitName',
type: 'GENERAL',
detectorType: DetectorType.PATTERN,
labeledColor: ANALYTIC_UNIT_COLORS[0],
deletedColor: DEFAULT_DELETED_SEGMENT_COLOR,
alert: false,
visible: true,
collapsed: false
};
const LABELING_MODES = [];
export class AnalyticUnit {
private _labelingMode: LabelingMode = LabelingMode.LABELING;
private _selected: boolean = false;
private _saving: boolean = false;
private _segmentSet = new SegmentArray<AnalyticSegment>();
private _detectionSpans: DetectionSpan[];
private _inspect = false;
private _changed = false;
private _status: string;
private _error: string;
// TODO: serverObject -> fields
constructor(protected _serverObject?: any) {
if(_serverObject === undefined) {
this._serverObject = _.clone(DEFAULTS);
}
_.defaults(this._serverObject, DEFAULTS);
}
toJSON() {
return {
id: this.id,
name: this.name,
// TODO: enum type
// TODO: type -> subType
type: this.type,
// TODO: detectorType -> type
detectorType: this.detectorType,
labeledColor: this.labeledColor,
deletedColor: this.deletedColor,
alert: this.alert,
visible: this.visible,
collapsed: this.collapsed
};
}
get id(): AnalyticUnitId { return this._serverObject.id; }
set id(value: AnalyticUnitId) { this._serverObject.id = value; }
set name(value: string) { this._serverObject.name = value; }
get name(): string { return this._serverObject.name; }
set detectorType(value: DetectorType) { this._serverObject.detectorType = value; }
get detectorType(): DetectorType { return this._serverObject.detectorType; }
set type(value: string) { this._serverObject.type = value; }
get type(): string { return this._serverObject.type; }
set labeledColor(value: string) { this._serverObject.labeledColor = value; }
get labeledColor(): string { return this._serverObject.labeledColor; }
set deletedColor(value: string) { this._serverObject.deletedColor = value; }
get deletedColor(): string { return this._serverObject.deletedColor; }
get collapsed(): boolean { return this._serverObject.collapsed; }
set collapsed(value: boolean) { this._serverObject.collapsed = value; }
set alert(value: boolean) { this._serverObject.alert = value; }
get alert(): boolean { return this._serverObject.alert; }
get selected(): boolean { return this._selected; }
set selected(value: boolean) { this._selected = value; }
get labelingMode(): LabelingMode { return this._labelingMode; }
set labelingMode(value: LabelingMode) { this._labelingMode = value; }
get saving(): boolean { return this._saving; }
set saving(value: boolean) { this._saving = value; }
get changed(): boolean { return this._changed; }
set changed(value: boolean) { this._changed = value; }
get inspect(): boolean { return this._inspect; }
set inspect(value: boolean) { this._inspect = value; }
get visible(): boolean {
return (this._serverObject.visible === undefined) ? true : this._serverObject.visible
}
set visible(value: boolean) {
this._serverObject.visible = value;
}
addSegment(segment: Segment, deleted: boolean): AnalyticSegment {
const addedSegment = new AnalyticSegment(!deleted, segment.id, segment.from, segment.to, deleted);
this._segmentSet.addSegment(addedSegment);
return addedSegment;
}
removeSegmentsInRange(from: number, to: number): AnalyticSegment[] {
let deletedSegments = this._segmentSet.removeInRange(from, to);
return deletedSegments;
}
get segments(): SegmentsSet<AnalyticSegment> { return this._segmentSet; }
set segments(value: SegmentsSet<AnalyticSegment>) {
this._segmentSet.setSegments(value.getSegments());
}
get detectionSpans(): DetectionSpan[] { return this._detectionSpans; }
set detectionSpans(value: DetectionSpan[]) { this._detectionSpans = value; }
get status() { return this._status; }
set status(value) {
// TODO: use enum
if(
value !== '404' &&
value !== 'READY' &&
value !== 'LEARNING' &&
value !== 'DETECTION' &&
value !== 'PENDING' &&
value !== 'FAILED' &&
value !== 'SUCCESS' &&
value !== null
) {
throw new Error('Unsupported status value: ' + value);
}
this._status = value;
}
get error() { return this._error; }
set error(value) { this._error = value; }
get isActiveStatus() {
switch(this.status) {
case '404':
case 'READY':
case 'FAILED':
return false;
}
return true;
}
get serverObject() { return this._serverObject; }
// TODO: make it abstract
get labelingModes() {
return LABELING_MODES;
}
}

105
client/src/types/colors.ts

@ -0,0 +1,105 @@
import tinycolor from 'tinycolor2';
import { DetectionStatus } from '@/types/detection';
export const PALETTE_ROWS = 4;
export const PALETTE_COLUMNS = 14;
export const DEFAULT_ANNOTATION_COLOR = 'rgba(0, 211, 255, 1)';
export const OK_COLOR = 'rgba(11, 237, 50, 1)';
export const NO_DATA_COLOR = 'rgba(150, 150, 150, 1)';
export const REGION_FILL_ALPHA = 0.09;
let colors = [
'#7EB26D',
'#EAB839',
'#6ED0E0',
'#EF843C',
'#E24D42',
'#1F78C1',
'#BA43A9',
'#705DA0',
'#508642',
'#CCA300',
'#447EBC',
'#C15C17',
'#890F02',
'#0A437C',
'#6D1F62',
'#584477',
'#B7DBAB',
'#F4D598',
'#70DBED',
'#F9BA8F',
'#F29191',
'#82B5D8',
'#E5A8E2',
'#AEA2E0',
'#629E51',
'#E5AC0E',
'#64B0C8',
'#E0752D',
'#BF1B00',
'#0A50A1',
'#962D82',
'#614D93',
'#9AC48A',
'#F2C96D',
'#65C5DB',
'#F9934E',
'#EA6460',
'#5195CE',
'#D683CE',
'#806EB7',
'#3F6833',
'#967302',
'#2F575E',
'#99440A',
'#58140C',
'#052B51',
'#511749',
'#3F2B5B',
'#E0F9D7',
'#FCEACA',
'#CFFAFF',
'#F9E2D2',
'#FCE2DE',
'#BADFF4',
'#F9D9F9',
'#DEDAF7',
];
export const ANALYTIC_UNIT_COLORS = [
'#FF99FF',
'#71b1f9',
'#aee9fb',
'#9ce677',
'#f88990',
'#f9e26e',
'#f8c171',
];
export const DEFAULT_DELETED_SEGMENT_COLOR = '#00f0ff';
export const REGION_UNLABEL_COLOR_LIGHT = '#d1d1d1';
export const REGION_UNLABEL_COLOR_DARK = 'white';
export const LABELED_SEGMENT_BORDER_COLOR = 'black';
export const DELETED_SEGMENT_BORDER_COLOR = 'black';
export const SEGMENT_FILL_ALPHA = 0.5;
export const SEGMENT_STROKE_ALPHA = 0.8;
export const LABELING_MODE_ALPHA = 0.7;
export const DETECTION_STATUS_COLORS = new Map<DetectionStatus, string>([
[DetectionStatus.READY, 'green'],
[DetectionStatus.RUNNING, 'gold'],
[DetectionStatus.FAILED, 'red']
]);
export function hexToHsl(color) {
return tinycolor(color).toHsl();
}
export function hslToHex(color) {
return tinycolor(color).toHexString();
}
export default colors;

20
client/src/types/detection.ts

@ -0,0 +1,20 @@
import { AnalyticUnitId } from '@/types/analytic_units/';
export enum DetectionStatus {
READY = 'READY',
RUNNING = 'RUNNING',
FAILED = 'FAILED'
};
export type DetectionSpan = {
id: AnalyticUnitId,
status: DetectionStatus,
from: number,
to: number
};
export const DETECTION_STATUS_TEXT = new Map<DetectionStatus, string>([
[DetectionStatus.READY, '[DetectionStatus]: done'],
[DetectionStatus.RUNNING, '[DetectionStatus]: running...'],
[DetectionStatus.FAILED, '[DetectionStatus]: failed']
]);

36
client/src/types/segment.ts

@ -0,0 +1,36 @@
export type SegmentId = string;
export class Segment {
constructor(private _id: SegmentId, public from: number, public to: number) {
if(this._id === undefined) {
throw new Error('id is undefined');
}
if(isNaN(+from)) {
throw new Error('from can`t be NaN');
}
if(isNaN(+to)) {
throw new Error('to can`t be NaN');
}
}
get id(): SegmentId { return this._id; }
set id(value) { this._id = value; }
get middle() { return (this.from + this.to) / 2; }
get length() {
return Math.max(this.from, this.to) - Math.min(this.from, this.to);
}
expandDist(allDist: number, portion: number): Segment {
var p = Math.round(this.middle - allDist * portion / 2);
var q = Math.round(this.middle + allDist * portion / 2);
p = Math.min(p, this.from);
q = Math.max(q, this.to);
return new Segment(this._id, p, q);
}
equals(segment: Segment) {
return this._id === segment._id;
}
}

101
client/src/types/segment_array.ts

@ -0,0 +1,101 @@
import { SegmentsSet } from './segment_set';
import { Segment, SegmentId } from './segment';
export class SegmentArray<T extends Segment> implements SegmentsSet<T> {
private _segments: T[];
private _keyToSegment: Map<SegmentId, T> = new Map<SegmentId, T>();
constructor(private segments?: T[]) {
this.setSegments(segments);
}
getSegments(from?: number, to?: number): T[] {
if(from === undefined) {
from = -Infinity;
}
if(to === undefined) {
to = Infinity;
}
var result = [];
for(var i = 0; i < this._segments.length; i++) {
var s = this._segments[i];
if(from <= s.from && s.to <= to) {
result.push(s);
}
}
return result;
}
setSegments(segments: T[]) {
this._segments = [];
this._keyToSegment.clear();
if(segments) {
segments.forEach(s => {
this.addSegment(s);
});
}
}
addSegment(segment: T) {
if(this.has(segment.id)) {
throw new Error(`Segment with key ${segment.id} exists in set`);
}
this._keyToSegment.set(segment.id, segment);
this._segments.push(segment);
}
findSegments(point: number, rangeDist: number): T[] {
return this._segments.filter(s => {
const expanded = s.expandDist(rangeDist, 0.01);
return (expanded.from <= point) && (point <= expanded.to);
});
}
removeInRange(from: number, to: number): T[] {
var deleted = [];
var newSegments = [];
for(var i = 0; i < this._segments.length; i++) {
var s = this._segments[i];
if(from <= s.from && s.to <= to) {
this._keyToSegment.delete(s.id);
deleted.push(s);
} else {
newSegments.push(s);
}
}
this._segments = newSegments;
return deleted;
}
get length() {
return this._segments.length;
}
clear() {
this._segments = [];
this._keyToSegment.clear();
}
has(key: SegmentId): boolean {
return this._keyToSegment.has(key);
}
remove(key: SegmentId): boolean {
if(!this.has(key)) {
return false;
}
var index = this._segments.findIndex(s => s.id === key);
this._segments.splice(index, 1);
this._keyToSegment.delete(key);
return true;
}
updateId(fromKey: SegmentId, toKey: SegmentId) {
var segment = this._keyToSegment.get(fromKey);
this._keyToSegment.delete(fromKey);
segment.id = toKey;
this._keyToSegment.set(toKey, segment);
}
}

14
client/src/types/segment_set.ts

@ -0,0 +1,14 @@
import { Segment, SegmentId } from '@/types/segment'
export interface SegmentsSet<T extends Segment> {
getSegments(from?: number, to?: number): T[];
setSegments(segments: T[]): void;
addSegment(segment: T): void;
findSegments(point: number, rangeDist: number): T[];
removeInRange(from: number, to: number): T[];
remove(id: SegmentId): boolean;
has(id: SegmentId): boolean;
clear(): void;
updateId(fromId: SegmentId, toId: SegmentId): void;
length: number;
}

6
client/src/types/user.ts

@ -1,5 +1,5 @@
export class User {
public username?: String
public email?: String
public password?: String
public username?: String
public email?: String
public password?: String
}

10
client/yarn.lock

@ -691,6 +691,11 @@
resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.8.tgz#b94a4391c85666c7b73299fd3ad79d4faa435310"
integrity sha512-ipixuVrh2OdNmauvtT51o3d8z12p6LtFW9in7U79der/kwejjdNchQC5UMn5u/KxNoM7VHHOs/l8KS8uHxhODQ==
"@types/tinycolor2@^1.4.3":
version "1.4.3"
resolved "https://registry.yarnpkg.com/@types/tinycolor2/-/tinycolor2-1.4.3.tgz#ed4a0901f954b126e6a914b4839c77462d56e706"
integrity sha512-Kf1w9NE5HEgGxCRyIcRXR/ZYtDv0V8FVPtYHwLxl0O+maGX0erE77pQlD0gpP+/KByMZ87mOA79SjifhSB3PjQ==
"@types/uglify-js@*":
version "3.13.1"
resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.13.1.tgz#5e889e9e81e94245c75b6450600e1c5ea2878aea"
@ -8912,6 +8917,11 @@ timsort@^0.3.0:
resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4"
integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=
tinycolor2@^1.4.2:
version "1.4.2"
resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.2.tgz#3f6a4d1071ad07676d7fa472e1fac40a719d8803"
integrity sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA==
tmp@^0.0.33:
version "0.0.33"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"

Loading…
Cancel
Save