From ec6816d0d9a737f9fe70ec8d77f15afcd4720354 Mon Sep 17 00:00:00 2001 From: TAMARA JERINIC Date: Thu, 26 May 2022 00:58:36 +0200 Subject: Ispravljen raspored prikaza metrika, svaka vrednost i odgovarajuća vrednost na validacionom skupu se prikazuju na pojedinačnom grafiku. Metrike su filtrirane u zavisnosti od tipa problema. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../_charts/line-chart/line-chart.component.ts | 249 +++++++++++++++++++-- 1 file changed, 234 insertions(+), 15 deletions(-) (limited to 'frontend/src/app/_elements/_charts/line-chart/line-chart.component.ts') diff --git a/frontend/src/app/_elements/_charts/line-chart/line-chart.component.ts b/frontend/src/app/_elements/_charts/line-chart/line-chart.component.ts index 7d21129c..acba7201 100644 --- a/frontend/src/app/_elements/_charts/line-chart/line-chart.component.ts +++ b/frontend/src/app/_elements/_charts/line-chart/line-chart.component.ts @@ -1,5 +1,7 @@ -import { Component, AfterViewInit, ElementRef, ViewChild } from '@angular/core'; +import { Component, AfterViewInit, ElementRef, ViewChild, Input } from '@angular/core'; import { Chart } from 'chart.js'; +import Experiment from 'src/app/_data/Experiment'; +import Model, { ProblemType } from 'src/app/_data/Model'; @Component({ selector: 'app-line-chart', @@ -23,14 +25,18 @@ export class LineChartComponent implements AfterViewInit { wrapper!: ElementRef; @ViewChild('canvas') canvas!: ElementRef; - + @Input() experiment!:Experiment; constructor() { } width = 700; height = 400; - - myChart!: Chart; + history: any[] = []; + myChartAcc!: Chart; + myChartMae!: Chart; + myChartMse!: Chart; + myChartLoss!: Chart; + ProblemType=ProblemType; resize() { this.width = this.wrapper.nativeElement.offsetWidth; this.height = this.wrapper.nativeElement.offsetHeight; @@ -69,14 +75,69 @@ export class LineChartComponent implements AfterViewInit { this.dataValMSE.length = 0; this.dataValMSE.push(...myValMse); - this.myChart.update(); + this.myChartAcc.update(); + this.myChartLoss.update(); + this.myChartMae.update(); + this.myChartMse.update(); } + updateAll(history: any[],totalEpochs:number) { + const myAcc: number[] = []; + const myMae: number[] = []; + const myMse: number[] = []; + const myLoss: number[] = []; + const myValLoss: number[] = []; + const myValAcc: number[] = []; + const myValMAE: number[] = []; + const myValMSE: number[] = []; + + const myEpochs: number[] = []; + this.history = history; + this.history.forEach((metrics, epoch) => { + if(totalEpochs>100) + { + let epochEstimate=epoch*Math.round(Math.sqrt(totalEpochs)) + if(epochEstimate>totalEpochs) + epochEstimate=totalEpochs; + myEpochs.push(epochEstimate); + } + else + myEpochs.push(epoch + 1); + for (let key in metrics) { + let value = metrics[key]; + if (key === 'accuracy') { + myAcc.push(parseFloat(value)); + } + else if (key === 'loss') { + myLoss.push(parseFloat(value)); + } + else if (key === 'mae') { + myMae.push(parseFloat(value)); + } + else if (key === 'mse') { + myMse.push(parseFloat(value)); + } + else if (key === 'val_acc') { + myValAcc.push(parseFloat(value)); + } + else if (key === 'val_loss') { + myValLoss.push(parseFloat(value)); + } + else if (key === 'val_mae') { + myValMAE.push(parseFloat(value)); + } + else if (key === 'val_mse') { + myValMSE.push(parseFloat(value)); + } + } + }); + this.update(myEpochs, myAcc, myLoss, myMae, myMse, myValAcc,myValLoss,myValMAE,myValMSE); + } ngAfterViewInit(): void { window.addEventListener('resize', () => { this.resize() }); this.resize(); - this.myChart = new Chart("myChart", + this.myChartAcc = new Chart("myChartacc", { type: 'line', data: { @@ -92,7 +153,59 @@ export class LineChartComponent implements AfterViewInit { label: 'Val_Accuracy', data: this.dataValAcc, borderWidth: 1 + } + ] + }, + options: { + responsive: true, + maintainAspectRatio: true, + + plugins: { + legend: { + labels: { + // This more specific font property overrides the global property + color:'white', + font: { + size: 10 + } + } + } + }, + scales: { + x: { + ticks: { + color: 'white' + }, + grid: { + color: "rgba(0, 99, 171, 0.5)" + }, + }, + y: { + beginAtZero: true, + ticks: { + color: 'white' + + }, + grid: { + color: "rgba(0, 99, 171, 0.5)" + } + } + }, + animation: { + duration: 0 + } + + } + }, + + ); + this.myChartLoss = new Chart("myChartloss", + { + type: 'line', + data: { + labels: this.dataEpoch, + datasets: [ { label: 'Loss', data: this.dataLOSS, @@ -103,16 +216,58 @@ export class LineChartComponent implements AfterViewInit { data: this.dataValLoss, borderWidth: 1 }, - { - label: 'MAE', - data: this.dataMAE, - borderWidth: 1 + ] + }, + options: { + responsive: true, + maintainAspectRatio: true, + + plugins: { + legend: { + labels: { + // This more specific font property overrides the global property + color:'white', + font: { + size: 10 + } + } + } }, - { - label: 'Val_MAE', - data: this.dataValMAE, - borderWidth: 1 + scales: { + x: { + ticks: { + color: 'white' + }, + grid: { + color: "rgba(0, 99, 171, 0.5)" + }, + }, + y: { + beginAtZero: true, + ticks: { + color: 'white' + + }, + grid: { + color: "rgba(0, 99, 171, 0.5)" + } + } + }, + animation: { + duration: 0 + } + + } + }, + + ); + this.myChartMse = new Chart("myChartmse", + { + type: 'line', + data: { + labels: this.dataEpoch, + datasets: [ { label: 'MSE', data: this.dataMSE, @@ -166,8 +321,72 @@ export class LineChartComponent implements AfterViewInit { } } - } + }, + ); + this.myChartMae = new Chart("myChartmae", + { + type: 'line', + data: { + labels: this.dataEpoch, + datasets: [ + { + label: 'MAE', + data: this.dataMAE, + borderWidth: 1 + }, + { + label: 'Val_MAE', + data: this.dataValMAE, + borderWidth: 1 + }, + ] + }, + options: { + responsive: true, + maintainAspectRatio: true, + + plugins: { + legend: { + labels: { + // This more specific font property overrides the global property + color:'white', + font: { + size: 10 + } + } + } + }, + scales: { + x: { + ticks: { + color: 'white' + }, + grid: { + color: "rgba(0, 99, 171, 0.5)" + }, + }, + y: { + beginAtZero: true, + ticks: { + color: 'white' + + }, + grid: { + color: "rgba(0, 99, 171, 0.5)" + } + } + + }, + animation: { + duration: 0 + } + + } + }, + + ); + } } -- cgit v1.2.3 From c6f1ca72c5ada7fc42985e129da362796883cb2f Mon Sep 17 00:00:00 2001 From: TAMARA JERINIC Date: Thu, 26 May 2022 17:21:32 +0200 Subject: Dodato imenovanje osa. --- .../_charts/line-chart/line-chart.component.css | 2 +- .../_charts/line-chart/line-chart.component.ts | 42 +++++++++++++++++++++- 2 files changed, 42 insertions(+), 2 deletions(-) (limited to 'frontend/src/app/_elements/_charts/line-chart/line-chart.component.ts') diff --git a/frontend/src/app/_elements/_charts/line-chart/line-chart.component.css b/frontend/src/app/_elements/_charts/line-chart/line-chart.component.css index ea150b0f..7dbbde7a 100644 --- a/frontend/src/app/_elements/_charts/line-chart/line-chart.component.css +++ b/frontend/src/app/_elements/_charts/line-chart/line-chart.component.css @@ -7,7 +7,7 @@ canvas{ border-radius: 5px; margin: 0; font-size: 11 !important; - padding: 10px; + padding: 0; } .ns-col{ margin: 5px; diff --git a/frontend/src/app/_elements/_charts/line-chart/line-chart.component.ts b/frontend/src/app/_elements/_charts/line-chart/line-chart.component.ts index acba7201..2b97d6b4 100644 --- a/frontend/src/app/_elements/_charts/line-chart/line-chart.component.ts +++ b/frontend/src/app/_elements/_charts/line-chart/line-chart.component.ts @@ -159,7 +159,6 @@ export class LineChartComponent implements AfterViewInit { options: { responsive: true, maintainAspectRatio: true, - plugins: { legend: { labels: { @@ -179,6 +178,11 @@ export class LineChartComponent implements AfterViewInit { grid: { color: "rgba(0, 99, 171, 0.5)" }, + title: { + display: true, + text: 'Epoha', + color:"white" + } }, y: { beginAtZero: true, @@ -188,6 +192,11 @@ export class LineChartComponent implements AfterViewInit { }, grid: { color: "rgba(0, 99, 171, 0.5)" + }, + title: { + display: true, + text: 'Vrednost', + color:"white" } } @@ -200,6 +209,7 @@ export class LineChartComponent implements AfterViewInit { }, ); + if(this.experiment.type==ProblemType.BinaryClassification || this.experiment.type==ProblemType.MultiClassification){} this.myChartLoss = new Chart("myChartloss", { type: 'line', @@ -241,6 +251,11 @@ export class LineChartComponent implements AfterViewInit { grid: { color: "rgba(0, 99, 171, 0.5)" }, + title: { + display: true, + text: 'Epoha', + color:"white" + } }, y: { beginAtZero: true, @@ -250,6 +265,11 @@ export class LineChartComponent implements AfterViewInit { }, grid: { color: "rgba(0, 99, 171, 0.5)" + }, + title: { + display: true, + text: 'Vrednost', + color:"white" } } @@ -303,6 +323,11 @@ export class LineChartComponent implements AfterViewInit { grid: { color: "rgba(0, 99, 171, 0.5)" }, + title: { + display: true, + text: 'Epoha', + color:"white" + } }, y: { beginAtZero: true, @@ -312,6 +337,11 @@ export class LineChartComponent implements AfterViewInit { }, grid: { color: "rgba(0, 99, 171, 0.5)" + }, + title: { + display: true, + text: 'Vrednost', + color:"white" } } @@ -365,6 +395,11 @@ export class LineChartComponent implements AfterViewInit { grid: { color: "rgba(0, 99, 171, 0.5)" }, + title: { + display: true, + text: 'Epoha', + color:"white" + } }, y: { beginAtZero: true, @@ -374,6 +409,11 @@ export class LineChartComponent implements AfterViewInit { }, grid: { color: "rgba(0, 99, 171, 0.5)" + }, + title: { + display: true, + text: 'Vrednost', + color:"white" } } -- cgit v1.2.3 From 854e21f08d1c876cf62c7a360bd5bd142675d705 Mon Sep 17 00:00:00 2001 From: Danijel Anđelković Date: Fri, 3 Jun 2022 22:17:06 +0200 Subject: Dodao mogucnost download-ovanja H5 fajla za prediktor. Popravio bug kada se tooltipovi nisu uvak pojavljivali kada bi trebalo. Popravio bug sa layout-om grafa modela. --- .../_charts/line-chart/line-chart.component.css | 45 +++- .../_charts/line-chart/line-chart.component.html | 29 +-- .../_charts/line-chart/line-chart.component.ts | 230 +++++++++++---------- .../src/app/_elements/folder/folder.component.html | 22 +- .../_elements/form-model/form-model.component.html | 6 +- .../_pages/experiment/experiment.component.html | 2 +- .../app/_pages/experiment/experiment.component.ts | 8 +- frontend/src/app/_services/predictors.service.ts | 4 + 8 files changed, 200 insertions(+), 146 deletions(-) (limited to 'frontend/src/app/_elements/_charts/line-chart/line-chart.component.ts') diff --git a/frontend/src/app/_elements/_charts/line-chart/line-chart.component.css b/frontend/src/app/_elements/_charts/line-chart/line-chart.component.css index 7dbbde7a..9694119d 100644 --- a/frontend/src/app/_elements/_charts/line-chart/line-chart.component.css +++ b/frontend/src/app/_elements/_charts/line-chart/line-chart.component.css @@ -1,17 +1,46 @@ -canvas{ +.canvas-container { + height: 50%; + margin: 5px; +} + +.bottom { + height: 10%; +} - width:100% !important; - height:100% !important; +canvas { + max-height: 100%; border: 1px solid var(--ns-primary); background-color: var(--ns-bg-dark-100); border-radius: 5px; margin: 0; font-size: 11 !important; padding: 0; - } -.ns-col{ - margin: 5px; } -.hide{ - display: none; + +.ns-col { + margin: 5px; +} + +.hide { + display: none; } + +.dl-button { + position: relative; + color: var(--offwhite); + border-radius: 4px; + border: 1px solid var(--ns-primary); + background-color: var(--ns-bg-dark-50); + margin: 5px; + padding: 10px; + cursor: pointer; + z-index: 1001; + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; +} + +.dl-button:hover { + background-color: var(--ns-primary); +} \ No newline at end of file diff --git a/frontend/src/app/_elements/_charts/line-chart/line-chart.component.html b/frontend/src/app/_elements/_charts/line-chart/line-chart.component.html index e36d0dcf..a81f9dc4 100644 --- a/frontend/src/app/_elements/_charts/line-chart/line-chart.component.html +++ b/frontend/src/app/_elements/_charts/line-chart/line-chart.component.html @@ -1,24 +1,29 @@ -
-
-
- +
+
+
+
-
- +
+
-
-
- +
+
+
-
- +
+
+
+ +
+
-
\ No newline at end of file diff --git a/frontend/src/app/_elements/_charts/line-chart/line-chart.component.ts b/frontend/src/app/_elements/_charts/line-chart/line-chart.component.ts index 2b97d6b4..ceff02bd 100644 --- a/frontend/src/app/_elements/_charts/line-chart/line-chart.component.ts +++ b/frontend/src/app/_elements/_charts/line-chart/line-chart.component.ts @@ -1,7 +1,10 @@ -import { Component, AfterViewInit, ElementRef, ViewChild, Input } from '@angular/core'; +import { Component, AfterViewInit, ElementRef, ViewChild, Input, ViewChildren, QueryList } from '@angular/core'; import { Chart } from 'chart.js'; +import FileSaver from 'file-saver'; import Experiment from 'src/app/_data/Experiment'; import Model, { ProblemType } from 'src/app/_data/Model'; +import Predictor from 'src/app/_data/Predictor'; +import { PredictorsService } from 'src/app/_services/predictors.service'; @Component({ selector: 'app-line-chart', @@ -15,19 +18,34 @@ export class LineChartComponent implements AfterViewInit { dataMAE: number[] = []; dataMSE: number[] = []; dataLOSS: number[] = []; - dataValAcc:number[]=[]; - dataValMAE:number[]=[]; - dataValMSE:number[]=[]; - dataValLoss:number[]=[]; + dataValAcc: number[] = []; + dataValMAE: number[] = []; + dataValMSE: number[] = []; + dataValLoss: number[] = []; dataEpoch: number[] = []; @ViewChild('wrapper') wrapper!: ElementRef; - @ViewChild('canvas') - canvas!: ElementRef; - @Input() experiment!:Experiment; - constructor() { - + @ViewChildren('canvas') + canvas!: QueryList; + @Input() experiment!: Experiment; + @Input() predictor?: Predictor; + + + downloadFile() { + if (!this.predictor) { + return; + } + + const fileId = this.predictor.h5FileId; + if (fileId != undefined) + this.predictorsService.downloadH5(fileId).subscribe((response) => { + FileSaver.saveAs(response, fileId + '.h5'); + }); + } + + constructor(private predictorsService: PredictorsService) { + } width = 700; height = 400; @@ -36,18 +54,13 @@ export class LineChartComponent implements AfterViewInit { myChartMae!: Chart; myChartMse!: Chart; myChartLoss!: Chart; - ProblemType=ProblemType; + ProblemType = ProblemType; resize() { - this.width = this.wrapper.nativeElement.offsetWidth; + //this.width = this.wrapper.nativeElement.offsetWidth; this.height = this.wrapper.nativeElement.offsetHeight; - - if (this.canvas) { - this.canvas.nativeElement.width = this.width; - this.canvas.nativeElement.height = this.height; - } } - update(myEpochs: number[], myAcc: number[], myLoss: number[], myMae: number[], myMse: number[], myValAcc:number[],myValLoss:number[],myValMae:number[],myValMse:number[]) { - + update(myEpochs: number[], myAcc: number[], myLoss: number[], myMae: number[], myMse: number[], myValAcc: number[], myValLoss: number[], myValMae: number[], myValMse: number[]) { + this.dataEpoch.length = 0; this.dataEpoch.push(...myEpochs); @@ -80,7 +93,7 @@ export class LineChartComponent implements AfterViewInit { this.myChartMae.update(); this.myChartMse.update(); } - updateAll(history: any[],totalEpochs:number) { + updateAll(history: any[], totalEpochs: number) { const myAcc: number[] = []; const myMae: number[] = []; const myMse: number[] = []; @@ -93,11 +106,10 @@ export class LineChartComponent implements AfterViewInit { const myEpochs: number[] = []; this.history = history; this.history.forEach((metrics, epoch) => { - if(totalEpochs>100) - { - let epochEstimate=epoch*Math.round(Math.sqrt(totalEpochs)) - if(epochEstimate>totalEpochs) - epochEstimate=totalEpochs; + if (totalEpochs > 100) { + let epochEstimate = epoch * Math.round(Math.sqrt(totalEpochs)) + if (epochEstimate > totalEpochs) + epochEstimate = totalEpochs; myEpochs.push(epochEstimate); } else @@ -131,10 +143,10 @@ export class LineChartComponent implements AfterViewInit { } }); - this.update(myEpochs, myAcc, myLoss, myMae, myMse, myValAcc,myValLoss,myValMAE,myValMSE); + this.update(myEpochs, myAcc, myLoss, myMae, myMse, myValAcc, myValLoss, myValMAE, myValMSE); } ngAfterViewInit(): void { - + window.addEventListener('resize', () => { this.resize() }); this.resize(); this.myChartAcc = new Chart("myChartacc", @@ -147,27 +159,27 @@ export class LineChartComponent implements AfterViewInit { label: 'Accuracy', data: this.dataAcc, borderWidth: 1, - + }, { label: 'Val_Accuracy', data: this.dataValAcc, borderWidth: 1 - } + } ] }, options: { - responsive: true, - maintainAspectRatio: true, + //responsive: true, + //maintainAspectRatio: true, plugins: { legend: { - labels: { - // This more specific font property overrides the global property - color:'white', - font: { - size: 10 - } + labels: { + // This more specific font property overrides the global property + color: 'white', + font: { + size: 10 } + } } }, scales: { @@ -181,14 +193,14 @@ export class LineChartComponent implements AfterViewInit { title: { display: true, text: 'Epoha', - color:"white" + color: "white" } }, y: { beginAtZero: true, ticks: { color: 'white' - + }, grid: { color: "rgba(0, 99, 171, 0.5)" @@ -196,7 +208,7 @@ export class LineChartComponent implements AfterViewInit { title: { display: true, text: 'Vrednost', - color:"white" + color: "white" } } @@ -207,40 +219,40 @@ export class LineChartComponent implements AfterViewInit { } }, - + ); - if(this.experiment.type==ProblemType.BinaryClassification || this.experiment.type==ProblemType.MultiClassification){} + if (this.experiment.type == ProblemType.BinaryClassification || this.experiment.type == ProblemType.MultiClassification) { } this.myChartLoss = new Chart("myChartloss", { type: 'line', data: { labels: this.dataEpoch, datasets: [ - { - label: 'Loss', - data: this.dataLOSS, - borderWidth: 1 - }, - { - label: 'Val_Loss', - data: this.dataValLoss, - borderWidth: 1 - }, + { + label: 'Loss', + data: this.dataLOSS, + borderWidth: 1 + }, + { + label: 'Val_Loss', + data: this.dataValLoss, + borderWidth: 1 + }, ] }, options: { - responsive: true, - maintainAspectRatio: true, + //responsive: true, + //maintainAspectRatio: true, plugins: { legend: { - labels: { - // This more specific font property overrides the global property - color:'white', - font: { - size: 10 - } + labels: { + // This more specific font property overrides the global property + color: 'white', + font: { + size: 10 } + } } }, scales: { @@ -254,14 +266,14 @@ export class LineChartComponent implements AfterViewInit { title: { display: true, text: 'Epoha', - color:"white" + color: "white" } }, y: { beginAtZero: true, ticks: { color: 'white' - + }, grid: { color: "rgba(0, 99, 171, 0.5)" @@ -269,7 +281,7 @@ export class LineChartComponent implements AfterViewInit { title: { display: true, text: 'Vrednost', - color:"white" + color: "white" } } @@ -280,7 +292,7 @@ export class LineChartComponent implements AfterViewInit { } }, - + ); this.myChartMse = new Chart("myChartmse", { @@ -288,31 +300,31 @@ export class LineChartComponent implements AfterViewInit { data: { labels: this.dataEpoch, datasets: [ - { - label: 'MSE', - data: this.dataMSE, - borderWidth: 1 - }, - { - label: 'Val_MSE', - data: this.dataValMSE, - borderWidth: 1 - } + { + label: 'MSE', + data: this.dataMSE, + borderWidth: 1 + }, + { + label: 'Val_MSE', + data: this.dataValMSE, + borderWidth: 1 + } ] }, options: { - responsive: true, - maintainAspectRatio: true, + //responsive: true, + //maintainAspectRatio: true, plugins: { legend: { - labels: { - // This more specific font property overrides the global property - color:'white', - font: { - size: 10 - } + labels: { + // This more specific font property overrides the global property + color: 'white', + font: { + size: 10 } + } } }, scales: { @@ -326,14 +338,14 @@ export class LineChartComponent implements AfterViewInit { title: { display: true, text: 'Epoha', - color:"white" + color: "white" } }, y: { beginAtZero: true, ticks: { color: 'white' - + }, grid: { color: "rgba(0, 99, 171, 0.5)" @@ -341,7 +353,7 @@ export class LineChartComponent implements AfterViewInit { title: { display: true, text: 'Vrednost', - color:"white" + color: "white" } } @@ -352,7 +364,7 @@ export class LineChartComponent implements AfterViewInit { } }, - + ); this.myChartMae = new Chart("myChartmae", { @@ -360,31 +372,31 @@ export class LineChartComponent implements AfterViewInit { data: { labels: this.dataEpoch, datasets: [ - { - label: 'MAE', - data: this.dataMAE, - borderWidth: 1 - }, - { - label: 'Val_MAE', - data: this.dataValMAE, - borderWidth: 1 - }, + { + label: 'MAE', + data: this.dataMAE, + borderWidth: 1 + }, + { + label: 'Val_MAE', + data: this.dataValMAE, + borderWidth: 1 + }, ] }, options: { - responsive: true, - maintainAspectRatio: true, + //responsive: true, + //maintainAspectRatio: true, plugins: { legend: { - labels: { - // This more specific font property overrides the global property - color:'white', - font: { - size: 10 - } + labels: { + // This more specific font property overrides the global property + color: 'white', + font: { + size: 10 } + } } }, scales: { @@ -398,14 +410,14 @@ export class LineChartComponent implements AfterViewInit { title: { display: true, text: 'Epoha', - color:"white" + color: "white" } }, y: { beginAtZero: true, ticks: { color: 'white' - + }, grid: { color: "rgba(0, 99, 171, 0.5)" @@ -413,7 +425,7 @@ export class LineChartComponent implements AfterViewInit { title: { display: true, text: 'Vrednost', - color:"white" + color: "white" } } @@ -424,9 +436,9 @@ export class LineChartComponent implements AfterViewInit { } }, - + ); - + } } diff --git a/frontend/src/app/_elements/folder/folder.component.html b/frontend/src/app/_elements/folder/folder.component.html index 34cd4693..5d5e7822 100644 --- a/frontend/src/app/_elements/folder/folder.component.html +++ b/frontend/src/app/_elements/folder/folder.component.html @@ -76,16 +76,16 @@ {{file.lastUpdated | date}}
- -
-
+
@@ -122,11 +122,11 @@
- -
-
-
+
+
diff --git a/frontend/src/app/_pages/experiment/experiment.component.html b/frontend/src/app/_pages/experiment/experiment.component.html index abb5a6d5..2e5a269c 100644 --- a/frontend/src/app/_pages/experiment/experiment.component.html +++ b/frontend/src/app/_pages/experiment/experiment.component.html @@ -67,7 +67,7 @@
- +