From 6ac770f3d54a175006cebfbb8bd26bc2cb5233a2 Mon Sep 17 00:00:00 2001 From: Alexey Velikiy Date: Wed, 10 Nov 2021 04:37:58 +0300 Subject: [PATCH] threshold pod --- client/src/components/Graph.vue | 91 +++++++++++++++++---- client/src/components/pods/pattern_pod.ts | 6 -- client/src/components/pods/threshold_pod.ts | 50 +++++++++++ client/src/services/segments.service.ts | 11 ++- 4 files changed, 134 insertions(+), 24 deletions(-) diff --git a/client/src/components/Graph.vue b/client/src/components/Graph.vue index 40fbc92..26d31f2 100644 --- a/client/src/components/Graph.vue +++ b/client/src/components/Graph.vue @@ -16,10 +16,12 @@ import { SegmentArray } from '@/types/segment_array'; import { Segment, SegmentId } from '@/types/segment'; import _ from "lodash"; +import { AnalyticUnitType } from '@/types/analytic_units'; +import { ThresholdPod } from './pods/threshold_pod'; // TODO: move to store -async function resolveData(range: TimeRange): Promise<{ +async function resolveDataPatterns(range: TimeRange): Promise<{ timeserie: LineTimeSerie[], 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 async function addSegment(segment: Segment): Promise { try { @@ -76,32 +109,29 @@ async function _deleteSegment(from: number, to: number): Promise { } } +// TODO: convert to class component export default defineComponent({ name: 'Graph', props: {}, mounted() { - var s = new SegmentArray(); - this.pod = new PatternPod( - document.getElementById('chart'), - resolveData.bind(this), - addSegment.bind(this), - _deleteSegment.bind(this), - s - ); - this.pod.render(); + this.rebuildGraph(); }, // TODO: it's a hack: listen real events about analytics update and use store watch: { // TODO: choose pog based on config type analyticUnitConfig(newConfig, prevConfig) { - console.log("CONFIG CHANGED"); if(prevConfig == null) { return; } - console.log(prevConfig); - console.log(newConfig); - + // TODO: remove this hack + if(!_.isEqual(_.keys(newConfig),_.keys(prevConfig))) { + return; + } + this.rerender(); + }, + analyticUnitType(newType, prevType) { + this.rebuildGraph(); } }, methods: { @@ -112,11 +142,44 @@ export default defineComponent({ async deleteAllSegments() { await _deleteSegment.bind(this)(0, Date.now()); 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: { analyticUnitConfig() { return this.$store.state.analyticUnitConfig; + }, + analyticUnitType() { + return this.$store.state.analyticUnitType; } } }); diff --git a/client/src/components/pods/pattern_pod.ts b/client/src/components/pods/pattern_pod.ts index 1ad93fe..d169e6d 100644 --- a/client/src/components/pods/pattern_pod.ts +++ b/client/src/components/pods/pattern_pod.ts @@ -16,7 +16,6 @@ export type DeleteSegmentCallback = (from: number, to: number) => Promise { - private _udc: UpdateDataCallback; private _csc: CreateSegmentCallback; private _dsc: DeleteSegmentCallback; @@ -68,13 +67,8 @@ export class PatternPod extends HasticPod { this._dKeyIsDown = false; } }); - - - this.fetchData(); - } - public fetchData(): void { let to = Math.floor(Date.now() / 1000); let from = to - 50000; // -50000 seconds diff --git a/client/src/components/pods/threshold_pod.ts b/client/src/components/pods/threshold_pod.ts index e69de29..a8c0a14 100644 --- a/client/src/components/pods/threshold_pod.ts +++ b/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 { + + constructor( + el: HTMLElement, + udc: UpdateDataCallback, + segmentSet: SegmentsSet + ) { + 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); + } + +} \ No newline at end of file diff --git a/client/src/services/segments.service.ts b/client/src/services/segments.service.ts index ef8e915..694e2e0 100644 --- a/client/src/services/segments.service.ts +++ b/client/src/services/segments.service.ts @@ -7,18 +7,21 @@ import _ from 'lodash'; const SEGMENTS_API_URL = API_URL + "segments/"; const ANALYTICS_API_URL = API_URL + "analytics/"; -export async function getSegments(from: number, to: number): Promise { +export async function getSegments(from: number, to: number, withLabeling = true): Promise { if(from >= to) { throw new Error("`from` can`t be less than `to`"); } - const uri = SEGMENTS_API_URL + `?from=${from}&to=${to}`; - const res = await axios.get(uri); + let result = []; + 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 resAnalytics = await axios.get(uriAnalytics); - const result = res["data"] as any[]; const resultAnalytics = resAnalytics["data"] as any[]; return result.concat(resultAnalytics).map(Segment.fromObject);