import {EventEmitter, Injectable} from '@angular/core'; import {ApiService, LshData, Parameters, RawData, State, StateNode, TableInfoData} from './api.service'; @Injectable({ providedIn: 'root' }) /** * This service acts as the state of the entire application. Components can subscribe to EventEmitters within this state to update their * contents. */ export class StateService { /** * These are all LSH specific variables. The variables can be accessed using the getters and setters */ public currStateIndex = 0; public maxStateIndex = 0; public states: {[idx: number]: StateNode} = {}; private _rawData: RawData[]; private _lshData: LshData; private _queryWindow: number[][]; private _weights: number[]; private _labels = {}; private _lshParameters: number[]; private _selection: number[]; public computedTime = 0; public windowSize = 120; public nrOfTables = 5; public hashSize = 5; public stepSize = 200; public loadingText = ''; /** * These are all GUI variables */ public loadingProgress = 0; public querySelectionMode = true; private _currentTab: number; private _sliderValue; /** * These are all EventEmitters. Subscribe to these if you want to be informed about an update in state. */ public onNewData: EventEmitter = new EventEmitter(); public onNewWindows: EventEmitter = new EventEmitter(); public onNewQuery: EventEmitter = new EventEmitter(); public onNewLshData: EventEmitter = new EventEmitter(); public onNewLabels: EventEmitter = new EventEmitter(); public onNewTab: EventEmitter = new EventEmitter(); public onNewSlider: EventEmitter = new EventEmitter(); public onNewSelection: EventEmitter = new EventEmitter(); constructor(private api: ApiService) { this._selection = [0]; this.initialize(); } /** * This function initializes the application. It retrieves the raw data and creates windows. */ async initialize(): Promise { this.loadingProgress = 0; await this.getRawData(); // this.loadingProgress = 50; // await this.createWindows(); this.loadingProgress = 100; } /** * This function resets the application. It re-creates the windows */ async reset(): Promise { this.loadingProgress = 50; await this.createWindows(); this.loadingProgress = 100; } /** * This function retrieves the raw data */ async getRawData(): Promise { this.rawData = await this.api.readFile(); console.log('Printing raw data:'); console.log(this.rawData); } /** * This function creates the windows on the server side */ async createWindows(): Promise { await this.api.createWindows(this.parameters); this.onNewWindows.emit(); } /** * This function performs the first iteration of LSH */ async lshInitial(): Promise { this._weights = Array(this._queryWindow.length).fill(1); const t0 = new Date().getTime(); this.loadingText = 'Calculating optimal LSH parameters'; this._lshParameters = await this.api.getParameters(); this.loadingText = 'Creating LSH model'; const lshData = await this.api.lshUpdate(this._queryWindow, this._weights, this._lshParameters); this.computedTime = new Date().getTime() - t0; this.loadingText = ''; this.lshData = lshData; } /** * This function performs every other iteration of LSH */ async update(labels, hashFunctions): Promise { this.loadingText = 'Calculating new model parameters'; this._weights = await this.api.getWeights(this._queryWindow, labels, this._weights, hashFunctions); const t0 = new Date().getTime(); this.loadingText = 'Creating LSH model'; const lshData = await this.api.lshUpdate(this._queryWindow, this._weights, this._lshParameters); this.computedTime = new Date().getTime() - t0; this.loadingText = ''; this.lshData = lshData; } /** * This function retrieves additional information given a table */ async getTableInfo(table: number[][]): Promise { return await this.api.getTableInfo(table); } /** * This function retrieves the query */ async getQueryWindow(windowIndex: number | {[index: number]: boolean}, querySize, startIndex): Promise { this.queryWindow = await this.api.getQueryWindow(windowIndex, querySize, startIndex); console.log('Printing query:'); console.log(this.queryWindow); return this._queryWindow; } /** * This function retrieves the window given the window index */ async getWindow(indices: number[]): Promise { return await this.api.getWindowByIndices(indices); } public async saveState() { this.maxStateIndex++; if (this.currStateIndex > 0) { if (!this.states[this.currStateIndex].children) { this.states[this.currStateIndex].children = []; } this.states[this.currStateIndex].children.push(this.maxStateIndex); } this.states[this.maxStateIndex] = { id: this.maxStateIndex, state: this.state, image: undefined, children: undefined }; console.log(this.states[this.maxStateIndex]); this.currStateIndex = this.maxStateIndex; } public loadState(stateIndex) { const stateNode = this.states[stateIndex]; this.currStateIndex = Number(stateNode.id); this._lshData = stateNode.state.lshData; this.queryWindow = stateNode.state.queryWindow; this._weights = stateNode.state.weights; this.labels = stateNode.state.labels; this.onNewLshData.emit(); } /** * These are all setters and getters */ public set rawData(v: RawData[]) { this._rawData = v; this.onNewData.emit(); } public get rawData(): RawData []{ return this._rawData; } public set lshData(v: LshData) { this._lshData = v; this.saveState(); console.log(this.states); this.onNewLshData.emit(); } public get lshData(): LshData { return this._lshData; } public set labels(v) { this._labels = v; this.onNewLabels.emit(); } public get labels() { return this._labels; } public set currentTab(v: number) { this._currentTab = v; this.onNewTab.emit(); } public get currentTab(): number { return this._currentTab; } public set sliderValue(v: number) { this._sliderValue = v; this.onNewSlider.emit(v); } public get sliderValue(): number { return this._sliderValue; } public set selection(v: number[]) { this._selection = v; this.onNewSelection.emit(v); } public get selection(): number[] { return this._selection; } public set queryWindow(v: number[][]) { this._queryWindow = v; this.onNewQuery.emit(); } public get queryWindow(): number[][] { return this._queryWindow; } public get lshParameters(): number[] { return this._lshParameters; } public get parameters(): Parameters { return { windowsize: this.windowSize, hashsize: this.hashSize, tablesize: this.nrOfTables, stepsize: this.stepSize }; } public get colors(): string[] { return ['#377eb8', '#ff7f00', '#4daf4a', '#f781bf', '#a65628', '#984ea3', '#999999', '#e41a1c', '#dede00']; } public get state(): State { return { lshData: this.lshData, queryWindow: this.queryWindow, weights: this._weights, labels: this.labels }; } }