Browse Source

threshold pod

pull/25/head
Alexey Velikiy 3 years ago
parent
commit
6ac770f3d5
  1. 91
      client/src/components/Graph.vue
  2. 6
      client/src/components/pods/pattern_pod.ts
  3. 50
      client/src/components/pods/threshold_pod.ts
  4. 11
      client/src/services/segments.service.ts

91
client/src/components/Graph.vue

@ -16,10 +16,12 @@ import { SegmentArray } from '@/types/segment_array';
import { Segment, SegmentId } from '@/types/segment'; import { Segment, SegmentId } from '@/types/segment';
import _ from "lodash"; import _ from "lodash";
import { AnalyticUnitType } from '@/types/analytic_units';
import { ThresholdPod } from './pods/threshold_pod';
// TODO: move to store // TODO: move to store
async function resolveData(range: TimeRange): Promise<{ async function resolveDataPatterns(range: TimeRange): Promise<{
timeserie: LineTimeSerie[], timeserie: LineTimeSerie[],
segments: Segment[] segments: Segment[]
}> { }> {
@ -47,6 +49,37 @@ async function resolveData(range: TimeRange): Promise<{
} }
} }
// TODO: move to store
// TODO: remove code repetition
async function resolveDataThreshold(range: TimeRange): Promise<{
timeserie: LineTimeSerie[],
segments: Segment[]
}> {
const endTime = Math.floor(range.to);
const startTime = Math.floor(range.from);
const step = Math.max(Math.round((endTime - startTime) / 5000), 1);
try {
// TODO: request in parallel
let [target, values] = await getMetrics(startTime, endTime, step);
let segments = await getSegments(startTime, endTime, false);
return {
timeserie: [{ target: target, datapoints: values, color: 'green' }],
segments: segments
}
} catch (e) {
this.$notify({
title: "Error during extracting data",
text: e,
type: 'error'
});
console.error(e);
}
}
// TODO: move to store // TODO: move to store
async function addSegment(segment: Segment): Promise<SegmentId> { async function addSegment(segment: Segment): Promise<SegmentId> {
try { try {
@ -76,32 +109,29 @@ async function _deleteSegment(from: number, to: number): Promise<number> {
} }
} }
// TODO: convert to class component
export default defineComponent({ export default defineComponent({
name: 'Graph', name: 'Graph',
props: {}, props: {},
mounted() { mounted() {
var s = new SegmentArray(); this.rebuildGraph();
this.pod = new PatternPod(
document.getElementById('chart'),
resolveData.bind(this),
addSegment.bind(this),
_deleteSegment.bind(this),
s
);
this.pod.render();
}, },
// TODO: it's a hack: listen real events about analytics update and use store // TODO: it's a hack: listen real events about analytics update and use store
watch: { watch: {
// TODO: choose pog based on config type // TODO: choose pog based on config type
analyticUnitConfig(newConfig, prevConfig) { analyticUnitConfig(newConfig, prevConfig) {
console.log("CONFIG CHANGED");
if(prevConfig == null) { if(prevConfig == null) {
return; return;
} }
console.log(prevConfig); // TODO: remove this hack
console.log(newConfig); if(!_.isEqual(_.keys(newConfig),_.keys(prevConfig))) {
return;
}
this.rerender(); this.rerender();
},
analyticUnitType(newType, prevType) {
this.rebuildGraph();
} }
}, },
methods: { methods: {
@ -112,11 +142,44 @@ export default defineComponent({
async deleteAllSegments() { async deleteAllSegments() {
await _deleteSegment.bind(this)(0, Date.now()); await _deleteSegment.bind(this)(0, Date.now());
this.rerender(); this.rerender();
},
rebuildGraph() {
let child = document.getElementById('chart').children[0];
if(child != undefined) {
document.getElementById('chart').removeChild(child);
}
var sa = new SegmentArray();
const aut = this.analyticUnitType;
if(aut == null) {
return;
}
if(aut === AnalyticUnitType.PATTERN) {
this.pod = new PatternPod(
document.getElementById('chart'),
resolveDataPatterns.bind(this),
addSegment.bind(this),
_deleteSegment.bind(this),
sa
);
}
if(aut === AnalyticUnitType.THRESHOLD) {
this.pod = new ThresholdPod(
document.getElementById('chart'),
resolveDataThreshold.bind(this),
sa
);
}
this.pod.render();
} }
}, },
computed: { computed: {
analyticUnitConfig() { analyticUnitConfig() {
return this.$store.state.analyticUnitConfig; return this.$store.state.analyticUnitConfig;
},
analyticUnitType() {
return this.$store.state.analyticUnitType;
} }
} }
}); });

6
client/src/components/pods/pattern_pod.ts

@ -16,7 +16,6 @@ export type DeleteSegmentCallback = (from: number, to: number) => Promise<number
export class PatternPod extends HasticPod<UpdateDataCallback> { export class PatternPod extends HasticPod<UpdateDataCallback> {
private _udc: UpdateDataCallback;
private _csc: CreateSegmentCallback; private _csc: CreateSegmentCallback;
private _dsc: DeleteSegmentCallback; private _dsc: DeleteSegmentCallback;
@ -68,13 +67,8 @@ export class PatternPod extends HasticPod<UpdateDataCallback> {
this._dKeyIsDown = false; this._dKeyIsDown = false;
} }
}); });
this.fetchData();
} }
public fetchData(): void { public fetchData(): void {
let to = Math.floor(Date.now() / 1000); let to = Math.floor(Date.now() / 1000);
let from = to - 50000; // -50000 seconds let from = to - 50000; // -50000 seconds

50
client/src/components/pods/threshold_pod.ts

@ -0,0 +1,50 @@
import { HasticPod } from './hastic_pod';
import { TimeRange } from '@/types';
import { Segment } from "@/types/segment";
import { LineTimeSerie } from '@chartwerk/line-pod';
import { SegmentsSet } from '@/types/segment_set';
export type UpdateDataCallback = (range: TimeRange) => Promise<{
timeserie: LineTimeSerie[],
segments: Segment[]
}>;
export class ThresholdPod extends HasticPod<UpdateDataCallback> {
constructor(
el: HTMLElement,
udc: UpdateDataCallback,
segmentSet: SegmentsSet<Segment>
) {
super(el, udc, segmentSet)
this.fetchData();
}
public fetchData(): void {
let to = Math.floor(Date.now() / 1000);
let from = to - 50000; // -50000 seconds
if(!(this.state.xValueRange[0] == 0 && this.state.xValueRange[1] == 1)) {
[from, to] = this.state?.xValueRange;
}
this.udc({ from, to })
.then(resp => {
this.updateSegments(resp.segments);
this.updateData(resp.timeserie, undefined, true);
})
.catch(() => { /* set "error" message */ })
}
protected updateSegments(segments: Segment[]): void {
this.segmentSet.clear();
this.segmentSet.setSegments(segments);
}
}

11
client/src/services/segments.service.ts

@ -7,18 +7,21 @@ import _ from 'lodash';
const SEGMENTS_API_URL = API_URL + "segments/"; const SEGMENTS_API_URL = API_URL + "segments/";
const ANALYTICS_API_URL = API_URL + "analytics/"; const ANALYTICS_API_URL = API_URL + "analytics/";
export async function getSegments(from: number, to: number): Promise<Segment[]> { export async function getSegments(from: number, to: number, withLabeling = true): Promise<Segment[]> {
if(from >= to) { if(from >= to) {
throw new Error("`from` can`t be less than `to`"); throw new Error("`from` can`t be less than `to`");
} }
const uri = SEGMENTS_API_URL + `?from=${from}&to=${to}`; let result = [];
const res = await axios.get(uri); if (withLabeling) {
const uri = SEGMENTS_API_URL + `?from=${from}&to=${to}`;
const res = await axios.get(uri);
result = res["data"] as any[];
}
const uriAnalytics = ANALYTICS_API_URL + `?from=${from}&to=${to}`; const uriAnalytics = ANALYTICS_API_URL + `?from=${from}&to=${to}`;
const resAnalytics = await axios.get(uriAnalytics); const resAnalytics = await axios.get(uriAnalytics);
const result = res["data"] as any[];
const resultAnalytics = resAnalytics["data"] as any[]; const resultAnalytics = resAnalytics["data"] as any[];
return result.concat(resultAnalytics).map(Segment.fromObject); return result.concat(resultAnalytics).map(Segment.fromObject);

Loading…
Cancel
Save