Browse Source

hastic pod abstract class begin

pull/25/head
Alexey Velikiy 3 years ago
parent
commit
011f6fff9e
  1. 6
      client/src/components/Graph.vue
  2. 192
      client/src/components/pods/hastic_pod.ts
  3. 201
      client/src/components/pods/pattern_pod.ts

6
client/src/components/Graph.vue

@ -7,7 +7,7 @@
<script lang="ts">
import { defineComponent, watch } from 'vue';
import { TimeRange } from "@/types";
import { HasticPod } from "./pods/hastic_pod";
import { PatternPod } from "./pods/pattern_pod";
import { getMetrics } from '../services/metrics.service';
import { getSegments, postSegment, deleteSegment } from '../services/segments.service';
import { LineTimeSerie } from "@chartwerk/line-pod";
@ -17,6 +17,7 @@ import { Segment, SegmentId } from '@/types/segment';
import _ from "lodash";
// TODO: move to store
async function resolveData(range: TimeRange): Promise<{
timeserie: LineTimeSerie[],
@ -80,7 +81,7 @@ export default defineComponent({
props: {},
mounted() {
var s = new SegmentArray();
this.pod = new HasticPod(
this.pod = new PatternPod(
document.getElementById('chart'),
resolveData.bind(this),
addSegment.bind(this),
@ -91,6 +92,7 @@ export default defineComponent({
},
// 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) {

192
client/src/components/pods/hastic_pod.ts

@ -4,36 +4,16 @@ import { BrushOrientation } from "@chartwerk/core";
import { SegmentsSet } from "@/types/segment_set";
import { ANALYTIC_UNIT_COLORS } from "@/types/colors"
import { Segment, SegmentId, SegmentType } from "@/types/segment";
import { TimeRange } from '@/types';
export type UpdateDataCallback = (range: TimeRange) => Promise<{
timeserie: LineTimeSerie[],
segments: Segment[]
}>;
export type CreateSegmentCallback = (segment: Segment) => Promise<SegmentId>;
export type DeleteSegmentCallback = (from: number, to: number) => Promise<number>;
export class HasticPod extends LinePod {
private _udc: UpdateDataCallback;
private _csc: CreateSegmentCallback;
private _dsc: DeleteSegmentCallback;
private _aKeyIsDown: boolean;
private _sKeyIsDown: boolean;
private _dKeyIsDown: boolean;
private _labelBrush: boolean;
private _antiLabelBrush: boolean;
private _deleteBrush: boolean;
export abstract class HasticPod<T> extends LinePod {
protected segmentsContainer;
constructor(
el: HTMLElement,
udc: UpdateDataCallback,
csc: CreateSegmentCallback,
dsc: DeleteSegmentCallback,
private _segmentSet: SegmentsSet<Segment>
protected udc: T,
protected segmentSet: SegmentsSet<Segment>
) {
super(el, undefined, {
renderLegend: false,
@ -46,47 +26,13 @@ export class HasticPod extends LinePod {
}
},
eventsCallbacks: {
zoomIn: range => { this._updateRange(range) },
zoomIn: range => { this.updateRange(range) },
zoomOut: ({x, y}) => { this._zoomOut({x, y}) },
panningEnd: range => { this._updateRange(range) }
panningEnd: range => { this.updateRange(range) }
}
});
this._csc = csc;
this._dsc = dsc;
this._sKeyIsDown = false;
this._aKeyIsDown = false;
this._dKeyIsDown = false;
this._labelBrush = false;
this._antiLabelBrush = false;
window.addEventListener("keydown", e => {
if(e.code == "KeyA") {
this._aKeyIsDown = true;
}
if(e.code == "KeyS") {
this._sKeyIsDown = true;
}
if(e.code == 'KeyD') {
this._dKeyIsDown = true;
}
});
window.addEventListener("keyup", (e) => {
if(e.code == "KeyA") {
this._aKeyIsDown = false;
}
if(e.code == "KeyS") {
this._sKeyIsDown = false;
}
if(e.code == 'KeyD') {
this._dKeyIsDown = false;
}
});
this._udc = udc;
this.fetchData();
}
@ -95,25 +41,6 @@ export class HasticPod extends LinePod {
this.renderSegments();
}
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;
console.log('took from range from state');
} else {
console.log('took from range from default');
}
console.log(from + " ---- " + to);
this._udc({ from, to })
.then(resp => {
this.updateSegments(resp.segments);
this.updateData(resp.timeserie, undefined, true);
})
.catch(() => { /* set "error" message */ })
}
protected addEvents(): void {
this.initBrush();
@ -126,98 +53,9 @@ export class HasticPod extends LinePod {
.on('dblclick.zoom', this.zoomOut.bind(this));
}
protected onBrushStart(): void {
if(this._sKeyIsDown) {
this._labelBrush = true;
this.svg.select('.selection')
.attr('fill', 'red');
} else if (this._aKeyIsDown) {
this._antiLabelBrush = true;
this.svg.select('.selection')
.attr('fill', 'blue');
} else if (this._dKeyIsDown) {
this._deleteBrush = true;
this.svg.select('.selection')
.attr('fill', 'darkgreen');
}
// 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 {
if(!this._labelBrush && !this._antiLabelBrush && !this._deleteBrush) {
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._labelBrush) {
this.addSegment(startTimestamp, endTimestamp, SegmentType.LABEL);
this._labelBrush = false;
}
if(this._antiLabelBrush) {
this.addSegment(startTimestamp, endTimestamp, SegmentType.ANTI_LABEL);
this._antiLabelBrush = false;
}
if(this._deleteBrush) {
this.deleteSegment(startTimestamp, endTimestamp);
this._deleteBrush = false;
}
}
}
protected async addSegment(from: number, to: number, type: SegmentType): Promise<void> {
const id = this.getNewTempSegmentId();
from = Math.floor(from);
to = Math.ceil(to);
if (from > to) {
const t = from;
from = to;
to = t;
}
const segment = new Segment(id, from, to, type);
//const storedId =
await this._csc(segment);
this.fetchData();
// segment.id = storedId;
// this._segmentSet.addSegment(segment);
// this.renderSegment(segment);
}
protected async deleteSegment(from: number, to: number): Promise<void> {
from = Math.floor(from);
to = Math.ceil(to);
if (from > to) {
const t = from;
from = to;
to = t;
}
await this._dsc(from, to);
this.fetchData();
}
protected renderSegments(): void {
const segments = this._segmentSet.getSegments();
const segments = this.segmentSet.getSegments();
// TODO: this is a bad hack, don't know why
if(this.metricContainer == null) {
return;
@ -254,27 +92,17 @@ export class HasticPod extends LinePod {
}
}
private async _updateRange(range: AxisRange[]) {
protected async updateRange(range: AxisRange[]) {
// in assumption that range have been changed
console.log('update range.....');
console.log(range)
this.fetchData();
}
private _zoomOut({x, y}): void {
protected _zoomOut({x, y}): void {
this.fetchData();
}
protected updateSegments(segments: Segment[]): void {
this._segmentSet.clear();
this._segmentSet.setSegments(segments);
}
abstract fetchData();
// TODO: move to "controller"
private _tempIdCounted = -1;
public getNewTempSegmentId(): SegmentId {
this._tempIdCounted--;
return this._tempIdCounted.toString();
}
}

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

@ -1,6 +1,203 @@
import { HasticPod } from './hastic_pod';
import { TimeRange } from '@/types';
import { Segment, SegmentId, SegmentType } 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 type CreateSegmentCallback = (segment: Segment) => Promise<SegmentId>;
export type DeleteSegmentCallback = (from: number, to: number) => Promise<number>;
export class PatternPod extends HasticPod<UpdateDataCallback> {
private _udc: UpdateDataCallback;
private _csc: CreateSegmentCallback;
private _dsc: DeleteSegmentCallback;
private _aKeyIsDown: boolean;
private _sKeyIsDown: boolean;
private _dKeyIsDown: boolean;
private _labelBrush: boolean;
private _antiLabelBrush: boolean;
private _deleteBrush: boolean;
constructor(
el: HTMLElement,
udc: UpdateDataCallback,
csc: CreateSegmentCallback,
dsc: DeleteSegmentCallback,
segmentSet: SegmentsSet<Segment>
) {
super(el, udc, segmentSet)
this._csc = csc;
this._dsc = dsc;
this._sKeyIsDown = false;
this._aKeyIsDown = false;
this._dKeyIsDown = false;
this._labelBrush = false;
this._antiLabelBrush = false;
window.addEventListener("keydown", e => {
if(e.code == "KeyA") {
this._aKeyIsDown = true;
}
if(e.code == "KeyS") {
this._sKeyIsDown = true;
}
if(e.code == 'KeyD') {
this._dKeyIsDown = true;
}
});
window.addEventListener("keyup", (e) => {
if(e.code == "KeyA") {
this._aKeyIsDown = false;
}
if(e.code == "KeyS") {
this._sKeyIsDown = false;
}
if(e.code == 'KeyD') {
this._dKeyIsDown = false;
}
});
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;
console.log('took from range from state');
} else {
console.log('took from range from default');
}
console.log(from + " ---- " + to);
this.udc({ from, to })
.then(resp => {
this.updateSegments(resp.segments);
this.updateData(resp.timeserie, undefined, true);
})
.catch(() => { /* set "error" message */ })
}
protected onBrushStart(): void {
if(this._sKeyIsDown) {
this._labelBrush = true;
this.svg.select('.selection')
.attr('fill', 'red');
} else if (this._aKeyIsDown) {
this._antiLabelBrush = true;
this.svg.select('.selection')
.attr('fill', 'blue');
} else if (this._dKeyIsDown) {
this._deleteBrush = true;
this.svg.select('.selection')
.attr('fill', 'darkgreen');
}
// 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 {
if(!this._labelBrush && !this._antiLabelBrush && !this._deleteBrush) {
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._labelBrush) {
this.addSegment(startTimestamp, endTimestamp, SegmentType.LABEL);
this._labelBrush = false;
}
if(this._antiLabelBrush) {
this.addSegment(startTimestamp, endTimestamp, SegmentType.ANTI_LABEL);
this._antiLabelBrush = false;
}
if(this._deleteBrush) {
this.deleteSegment(startTimestamp, endTimestamp);
this._deleteBrush = false;
}
}
}
protected async addSegment(from: number, to: number, type: SegmentType): Promise<void> {
const id = this.getNewTempSegmentId();
from = Math.floor(from);
to = Math.ceil(to);
if (from > to) {
const t = from;
from = to;
to = t;
}
const segment = new Segment(id, from, to, type);
//const storedId =
await this._csc(segment);
this.fetchData();
// segment.id = storedId;
// this._segmentSet.addSegment(segment);
// this.renderSegment(segment);
}
protected async deleteSegment(from: number, to: number): Promise<void> {
from = Math.floor(from);
to = Math.ceil(to);
if (from > to) {
const t = from;
from = to;
to = t;
}
await this._dsc(from, to);
this.fetchData();
}
protected updateSegments(segments: Segment[]): void {
this.segmentSet.clear();
this.segmentSet.setSegments(segments);
}
// TODO: move to "controller"
private _tempIdCounted = -1;
public getNewTempSegmentId(): SegmentId {
this._tempIdCounted--;
return this._tempIdCounted.toString();
}
export class PatternPod extends HasticPod {
}
Loading…
Cancel
Save