import { Injectable } from '@angular/core'; import { Observable, throwError } from 'rxjs'; import { catchError, map } from 'rxjs/operators'; import { VisualizationDataApi } from '../api/visualization-data-api.service'; import { VisualizationData } from '../models/visualization-data'; import { VisualizationsDataService } from './visualizations-data.service'; import { ClusterVisualizationDataMapper } from '../mappers/cluster-visualization-data-mapper'; import { RadarChartDataMapper } from '../mappers/radar-chart-data-mapper'; import { Clusterables } from '../models/clusterables-enum'; import { SseDataMapper } from '../mappers/sse-data-mapper'; import { Clusterable } from '../models/clusterable'; import { TimeAfterHint } from '../models/time-after-hint'; import { WrongFlags } from '../models/wrong-flags'; @Injectable() export class VisualizationsDataConcreteService extends VisualizationsDataService { private readonly messageBase = 'VisualizationsDataService cannot connect to API: '; protected _selectedFeature: Clusterables; set selectedFeature(value: Clusterables) { this._selectedFeature = value; } get selectedFeature(): Clusterables { return this._selectedFeature; } constructor(private visualizationApi: VisualizationDataApi) { super(); } getData( trainingDefinitionId: number, numOfClusters: number, instanceIds: number[], level: number, ): Observable<VisualizationData> { switch (this._selectedFeature) { case Clusterables.WrongFlags: return this.visualizationApi .getVisualizationData(trainingDefinitionId, 'wrong-answers', numOfClusters, instanceIds, level) .pipe( map((data: any) => ClusterVisualizationDataMapper.fromDTO(data)), catchError((error) => { return throwError(this.messageBase + error.message); }), ); case Clusterables.TimeAfterHint: return this.visualizationApi .getVisualizationData(trainingDefinitionId, 'hints', numOfClusters, instanceIds, level) .pipe( map((data: any) => ClusterVisualizationDataMapper.fromDTO(data)), catchError((error) => { return throwError(this.messageBase + error.message); }), ); default: return new Observable<VisualizationData>(); } } getRadarData( trainingDefinitionId: number, numOfClusters: number, instanceIds: number[], level: number, ): Observable<VisualizationData> { return this.visualizationApi.getRadarChartData(trainingDefinitionId, numOfClusters, instanceIds, level).pipe( map((data: any) => RadarChartDataMapper.fromDTO(data)), catchError((error) => { return throwError(this.messageBase + error.message); }), ); } getLineData( trainingDefinitionId: number, numOfClusters: number, instanceIds: number[], level: number, ): Observable<any> { switch (this._selectedFeature) { case Clusterables.WrongFlags: return this.visualizationApi .getFeatureSSE(trainingDefinitionId, 'wrong-answers', numOfClusters, instanceIds, level) .pipe( map((data: any) => SseDataMapper.fromDTO(data)), catchError((error) => { return throwError(this.messageBase + error.message); }), ); case Clusterables.TimeAfterHint: return this.visualizationApi .getFeatureSSE(trainingDefinitionId, 'hints', numOfClusters, instanceIds, level) .pipe( map((data: any) => SseDataMapper.fromDTO(data)), catchError((error) => { return throwError(this.messageBase + error.message); }), ); case Clusterables.NDimensional: return this.visualizationApi .getFeatureSSE(trainingDefinitionId, 'n-dimensional', numOfClusters, instanceIds, level) .pipe( map((data: any) => SseDataMapper.fromDTO(data)), catchError((error) => { return throwError(this.messageBase + error.message); }), ); } } getOption(point: Clusterable, feature = this._selectedFeature): number { switch (feature) { case Clusterables.TimeAfterHint: return (point as TimeAfterHint).level; } return 0; } getX(value: any, feature = this._selectedFeature): number { switch (feature) { case Clusterables.WrongFlags: return (value as WrongFlags).wrongFlagsSubmittedNormalized; case Clusterables.TimeAfterHint: return (value as TimeAfterHint).timeSpentAfterHintNormalized; case Clusterables.NDimensional: break; } const tmp = value as WrongFlags; return tmp.wrongFlagsSubmittedNormalized; } getY(value: any, feature = this._selectedFeature): number { switch (feature) { case Clusterables.WrongFlags: return (value as WrongFlags).timePlayedNormalized; case Clusterables.TimeAfterHint: return (value as TimeAfterHint).wrongFlagsAfterHintNormalized; case Clusterables.NDimensional: break; } const tmp = value as WrongFlags; return tmp.timePlayedNormalized; } getXLabel(feature = this._selectedFeature): string { switch (feature) { case Clusterables.WrongFlags: return 'Wrong answers submitted'; case Clusterables.TimeAfterHint: return 'Time spent after using hint'; } return 'Feature X'; } getYLabel(feature = this._selectedFeature): string { switch (feature) { case Clusterables.WrongFlags: return 'Time played'; case Clusterables.TimeAfterHint: return 'Wrong answers after using hint'; } return 'Feature Y'; } }