added help component, improved prediction with model templates
This commit is contained in:
@ -1,12 +1,53 @@
|
||||
<h2>Prediction</h2>
|
||||
|
||||
<h4 *ngIf="result !== '' || loading" [@inOut]>
|
||||
Result: {{result}}<rb-loading-spinner *ngIf="loading"></rb-loading-spinner>
|
||||
</h4>
|
||||
<rb-tab-panel (tabChanged)="groupChange($event)">
|
||||
<ng-container *ngFor="let group of d.arr.modelGroups; index as i">
|
||||
<div *rbTabPanelItem="group.group; id: i"></div>
|
||||
</ng-container>
|
||||
</rb-tab-panel>
|
||||
|
||||
<rb-form-file name="spectrum-upload" label="spectrum file" maxSize="10000000" class="space-below"
|
||||
(ngModelChange)="fileToArray($event)" placeholder="Select file or drag and drop" dragDrop ngModel>
|
||||
</rb-form-file>
|
||||
<rb-form-select label="Model" (change)="result = undefined" [(ngModel)]="activeModelIndex">
|
||||
<option *ngFor="let model of activeGroup.models; index as i" [value]="i">{{model.name}}</option>
|
||||
</rb-form-select>
|
||||
|
||||
<div *ngIf="result" class="result" [@inOut]>
|
||||
<ng-container *ngIf="multipleSamples; else singleSampleResult">
|
||||
<h4 *ngFor="let prediction of result.predictions; index as i">
|
||||
{{spectrumNames[i]}}: {{prediction}} {{activeGroup.models[activeModelIndex].label}}
|
||||
</h4>
|
||||
</ng-container>
|
||||
<ng-template #singleSampleResult>
|
||||
<h4>
|
||||
Average result: {{result.meanPrediction}} {{activeGroup.models[activeModelIndex].label}},
|
||||
standard deviation: {{result.std}}
|
||||
</h4>
|
||||
<a href="javascript:" class="rb-details-toggle" rbDetailsToggle #triggerDetails="rbDetailsToggle">Details</a>
|
||||
<div *ngIf="triggerDetails.open" class="space-below">
|
||||
<p *ngFor="let prediction of result.predictions; index as i">
|
||||
{{spectrumNames[i]}}: {{prediction}} {{activeGroup.models[activeModelIndex].label}}
|
||||
</p>
|
||||
</div>
|
||||
</ng-template>
|
||||
</div>
|
||||
|
||||
<div class="file-input space-below">
|
||||
<rb-form-file name="spectrum-upload" label="spectrum file" maxSize="10000000" class="space-below" multiple
|
||||
(ngModelChange)="fileToArray($event)" placeholder="Select file or drag and drop" dragDrop ngModel>
|
||||
</rb-form-file>
|
||||
|
||||
<rb-loading-spinner *ngIf="loading; else predictButton"></rb-loading-spinner>
|
||||
<ng-template #predictButton>
|
||||
<rb-icon-button icon="forward-right" mode="primary" *ngIf="spectrumNames.length; else placeholder"
|
||||
(click)="loadPrediction()">
|
||||
Predict
|
||||
</rb-icon-button>
|
||||
<ng-template #placeholder><div></div></ng-template>
|
||||
</ng-template>
|
||||
|
||||
<rb-form-checkbox name="multiple-samples" [(ngModel)]="multipleSamples">
|
||||
multiple samples
|
||||
</rb-form-checkbox>
|
||||
</div>
|
||||
|
||||
<div class="dpt-chart">
|
||||
<canvas baseChart
|
||||
|
@ -2,3 +2,17 @@
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.file-input {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto;
|
||||
grid-column-gap: 1rem;
|
||||
}
|
||||
|
||||
.result {
|
||||
margin: 30px 0;
|
||||
|
||||
h4 {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,15 @@ import { Component, OnInit } from '@angular/core';
|
||||
import {ChartOptions} from 'chart.js';
|
||||
import {ApiService} from '../services/api.service';
|
||||
import {animate, style, transition, trigger} from '@angular/animations';
|
||||
import cloneDeep from 'lodash/cloneDeep';
|
||||
import {DataService} from '../services/data.service';
|
||||
import {ModelItemModel} from '../models/model-item.model';
|
||||
|
||||
interface PredictionResult {
|
||||
meanPrediction: string;
|
||||
std: string;
|
||||
predictions: string[];
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app-prediction',
|
||||
@ -24,11 +33,16 @@ import {animate, style, transition, trigger} from '@angular/animations';
|
||||
})
|
||||
export class PredictionComponent implements OnInit {
|
||||
|
||||
readonly predictionUrl = 'https://definma-model-test.apps.de1.bosch-iot-cloud.com/predict';
|
||||
result = '';
|
||||
result: PredictionResult;
|
||||
loading = false;
|
||||
activeGroup: ModelItemModel = new ModelItemModel();
|
||||
activeModelIndex = 0;
|
||||
multipleSamples = false; // if true, spectra belong to different samples, otherwise multiple spectra from the same sample are given
|
||||
spectrumNames: string[] = [];
|
||||
spectrum: string[][] = [[]];
|
||||
chart = [{
|
||||
flattenedSpectra = [];
|
||||
chart = [];
|
||||
readonly chartInit = {
|
||||
data: [],
|
||||
label: 'Spectrum',
|
||||
showLine: true,
|
||||
@ -36,7 +50,7 @@ export class PredictionComponent implements OnInit {
|
||||
pointRadius: 0,
|
||||
borderColor: '#00a8b0',
|
||||
borderWidth: 2
|
||||
}];
|
||||
};
|
||||
readonly chartOptions: ChartOptions = {
|
||||
scales: {
|
||||
xAxes: [{ticks: {min: 400, max: 4000, stepSize: 400, reverse: true}}],
|
||||
@ -50,25 +64,53 @@ export class PredictionComponent implements OnInit {
|
||||
};
|
||||
|
||||
constructor(
|
||||
private api: ApiService
|
||||
) { }
|
||||
private api: ApiService,
|
||||
public d: DataService
|
||||
) {
|
||||
this.chart[0] = cloneDeep(this.chartInit);
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.d.load('modelGroups', () => {
|
||||
this.activeGroup = this.d.arr.modelGroups[0];
|
||||
});
|
||||
}
|
||||
|
||||
fileToArray(files) {
|
||||
const fileReader = new FileReader();
|
||||
fileReader.onload = () => {
|
||||
this.spectrum = fileReader.result.toString().split('\r\n').map(e => e.split(','));
|
||||
this.loading = true;
|
||||
this.api.post<{result: string}>(this.predictionUrl, this.spectrum, data => {
|
||||
this.result = data.result;
|
||||
this.loading = false;
|
||||
});
|
||||
this.chart[0].data = this.spectrum.map(e => ({x: parseFloat(e[0]), y: parseFloat(e[1])}));
|
||||
console.log(this.chart);
|
||||
};
|
||||
fileReader.readAsText(files[0]);
|
||||
this.loading = true;
|
||||
this.flattenedSpectra = [];
|
||||
this.chart = [];
|
||||
let load = files.length;
|
||||
this.spectrumNames = files.map(e => e.name);
|
||||
for (const i in files) {
|
||||
if (files.hasOwnProperty(i)) {
|
||||
const fileReader = new FileReader();
|
||||
fileReader.onload = () => {
|
||||
this.spectrum = fileReader.result.toString().split('\r\n').map(e => e.split(',').map(el => parseFloat(el))) as any;
|
||||
this.flattenedSpectra[i] = {labels: this.spectrum.map(e => e[0]), values: this.spectrum.map(e => e[1])};
|
||||
this.chart[i] = cloneDeep(this.chartInit);
|
||||
this.chart[i].data = this.spectrum.map(e => ({x: parseFloat(e[0]), y: parseFloat(e[1])}));
|
||||
load --;
|
||||
if (load <= 0) {
|
||||
this.loadPrediction();
|
||||
}
|
||||
};
|
||||
fileReader.readAsText(files[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
loadPrediction() {
|
||||
this.loading = true;
|
||||
console.log(this.activeModelIndex);
|
||||
this.api.post<PredictionResult>(this.activeGroup.models[this.activeModelIndex].url, this.flattenedSpectra, data => {
|
||||
this.result = data;
|
||||
this.loading = false;
|
||||
});
|
||||
}
|
||||
|
||||
groupChange(index) {
|
||||
this.activeGroup = this.d.arr.modelGroups[index];
|
||||
this.result = undefined;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user