diff --git a/client/src/components/Graph.vue b/client/src/components/Graph.vue index 151bf6b..e2e71cb 100644 --- a/client/src/components/Graph.vue +++ b/client/src/components/Graph.vue @@ -147,6 +147,7 @@ async function _deleteSegment(from: number, to: number): Promise { } } + // TODO: convert to class component export default defineComponent({ name: 'Graph', @@ -211,10 +212,19 @@ export default defineComponent({ this.pod = new AnomalyPod( document.getElementById('chart'), resolveDataAnomaly.bind(this), + this.setSeasonality.bind(this), sa ); } this.pod.render(); + }, + setSeasonality(from: number, to: number) { + let cfg = _.clone(this.analyticUnitConfig); + // TODO: get 10 (step) from API config + cfg.seasonality = Math.ceil(Math.abs(from - to) / 10) * 10; + console.log("cfg.seasonality: " + cfg.seasonality); + + this.$store.dispatch('patchConfig', { Anomaly: cfg }); } }, computed: { diff --git a/client/src/components/pods/anomaly_pod.ts b/client/src/components/pods/anomaly_pod.ts index bd76470..0c080c9 100644 --- a/client/src/components/pods/anomaly_pod.ts +++ b/client/src/components/pods/anomaly_pod.ts @@ -5,6 +5,8 @@ import { Segment } from "@/types/segment"; import { LineTimeSerie } from '@chartwerk/line-pod'; import { SegmentsSet } from '@/types/segment_set'; +import * as _ from 'lodash'; + export type UpdateDataCallback = (range: TimeRange) => Promise<{ timeserie: LineTimeSerie[], @@ -12,22 +14,84 @@ export type UpdateDataCallback = (range: TimeRange) => Promise<{ segments: Segment[] }>; -import * as _ from 'lodash'; +export type SetSeasonalityCallback = (from: number, to: number) => void; export class AnomalyPod extends HasticPod { + private _ssc: SetSeasonalityCallback; + private _hsr: AnomalyHSR; + private _zKeyIsDown: boolean; + + private _labelSeasonality: boolean; + constructor( el: HTMLElement, udc: UpdateDataCallback, + ssc: SetSeasonalityCallback, segmentSet: SegmentsSet ) { - super(el, udc, segmentSet) + super(el, udc, segmentSet); + this._zKeyIsDown = false; + this._ssc = ssc; + + window.addEventListener("keydown", e => { + if(e.code == "KeyZ") { + this._zKeyIsDown = true; + } + }); + + window.addEventListener("keyup", (e) => { + if(e.code == "KeyZ") { + this._zKeyIsDown = false; + } + }); + this.fetchData(); } + protected onBrushStart(): void { + if(this._zKeyIsDown) { + this._labelSeasonality = true; + this.svg.select('.selection') + .attr('fill', 'orange'); + } + + // TODO: move to state + this.isBrushing === true; + const selection = this.d3.event.selection; + if(selection !== null && selection.length > 0) { + this.brushStartSelection = this.d3.event.selection[0]; + } + this.onMouseOut(); + } + + protected onBrushEnd(): void { + console.log("END"); + if(!this._labelSeasonality) { + super.onBrushEnd(); + } else { + const extent = this.d3.event.selection; + this.isBrushing === false; + if(extent === undefined || extent === null || extent.length < 2) { + return; + } + this.chartContainer + .call(this.brush.move, null); + + const startTimestamp = this.xScale.invert(extent[0]); + const endTimestamp = this.xScale.invert(extent[1]); + + if(this._labelSeasonality) { + this._ssc(startTimestamp, endTimestamp); + this._labelSeasonality = false; + } + } + } + + public fetchData(): void { let to = Math.floor(Date.now() / 1000); let from = to - 50000; // -50000 seconds @@ -76,9 +140,7 @@ export class AnomalyPod extends HasticPod { .attr('pointer-events', 'none') .attr('points', points); - // render timestamp - - + // seasonality grid let ts = this._hsr.timestamp; this._renderHSRGridLine(ts, true); ts -= this._hsr.seasonality; diff --git a/client/src/components/pods/hastic_pod.ts b/client/src/components/pods/hastic_pod.ts index 5572f9a..c209dce 100644 --- a/client/src/components/pods/hastic_pod.ts +++ b/client/src/components/pods/hastic_pod.ts @@ -92,9 +92,6 @@ export abstract class HasticPod extends LinePod { } protected async updateRange(range: AxisRange[]) { - // in assumption that range have been changed - console.log('update range.....'); - console.log(range) this.fetchData(); } diff --git a/client/src/components/pods/pattern_pod.ts b/client/src/components/pods/pattern_pod.ts index 4ae40d0..0aa1f9a 100644 --- a/client/src/components/pods/pattern_pod.ts +++ b/client/src/components/pods/pattern_pod.ts @@ -114,7 +114,7 @@ export class PatternPod extends HasticPod { this.onMouseOut(); } - protected onBrushEnd(): void { + protected onBrushEnd(): void { if(!this._labelBrush && !this._antiLabelBrush && !this._deleteBrush) { super.onBrushEnd(); } else { diff --git a/client/src/services/analytics.service.ts b/client/src/services/analytics.service.ts index 2a08aa3..03ccc13 100644 --- a/client/src/services/analytics.service.ts +++ b/client/src/services/analytics.service.ts @@ -8,7 +8,7 @@ import { getGenerator } from '@/utils'; import _ from 'lodash'; import { AnalyticUnitType, AnlyticUnitConfig, - PatternConfig, ThresholdConfig, AnomalyConfig + PatternConfig, ThresholdConfig, AnomalyConfig } from "@/types/analytic_units"; import { AnomalyHSR } from "@/types"; diff --git a/client/src/views/Home.vue b/client/src/views/Home.vue index 8f2ea92..fe2989d 100644 --- a/client/src/views/Home.vue +++ b/client/src/views/Home.vue @@ -19,7 +19,7 @@
Hold
S
to label patterns; Hold
A
to label anti patterns
- Holde key
D
to delete patterns + Hold
D
to delete patterns

Correlation score: @@ -33,8 +33,10 @@
- Alpha: -
+ Hold
Z
to set seasonality timespan +
+ Confidence:
Seasonality: