diff --git a/projects/nshmp-apps/src/app/source/rates/components/content/content.component.html b/projects/nshmp-apps/src/app/source/rates/components/content/content.component.html index a6bc4a015c7426fa1426fea2a9d1340e67c4a94d..edd8a3d073b8220b0c0c1e6ad07932265badf5a5 100644 --- a/projects/nshmp-apps/src/app/source/rates/components/content/content.component.html +++ b/projects/nshmp-apps/src/app/source/rates/components/content/content.component.html @@ -5,4 +5,28 @@ <app-plots /> </ng-template> </mat-tab> + + <!-- Rate data --> + <mat-tab label="Rate Data" [disabled]="hasData() === false"> + <ng-template matTabContent> + <nshmp-lib-ng-data-table-panel + [table]="rateTableData()" + buttonText="Export rates as CSV" + title="Rates" + filename="rates {{ parameters() }}.csv" + /> + </ng-template> + </mat-tab> + + <!-- Probability data --> + <mat-tab label="Probability Data" [disabled]="hasData() === false"> + <ng-template matTabContent> + <nshmp-lib-ng-data-table-panel + [table]="probabilityTableData()" + buttonText="Export probabilities as CSV" + title="Probabilities" + filename="probabilities {{ parameters() }}.csv" + /> + </ng-template> + </mat-tab> </mat-tab-group> diff --git a/projects/nshmp-apps/src/app/source/rates/components/content/content.component.ts b/projects/nshmp-apps/src/app/source/rates/components/content/content.component.ts index 4f73685ba1c4a710e012061a0e6e389a2e172694..25a104a07d9f27ca1e6ae8c958ea9e5d038de6f5 100644 --- a/projects/nshmp-apps/src/app/source/rates/components/content/content.component.ts +++ b/projects/nshmp-apps/src/app/source/rates/components/content/content.component.ts @@ -1,13 +1,41 @@ -import {Component} from '@angular/core'; +import {Component, computed} from '@angular/core'; import {MatTabsModule} from '@angular/material/tabs'; +import {NshmpLibNgDataTablePanelComponent} from '@ghsc/nshmp-lib-ng/nshmp'; +import {plotUtils} from '@ghsc/nshmp-lib-ng/plot'; +import {AppService} from '../../services/app.service'; import {PlotsComponent} from '../plots/plots.component'; @Component({ - imports: [MatTabsModule, PlotsComponent], + imports: [MatTabsModule, PlotsComponent, NshmpLibNgDataTablePanelComponent], selector: 'app-content', standalone: true, styleUrl: './content.component.scss', templateUrl: './content.component.html', }) -export class ContentComponent {} +export class ContentComponent { + hasData = this.service.hasData; + + parameters = computed(() => { + const {distance, latitude, longitude, model, timespan} = + this.service.formGroup.getRawValue(); + + return `${model} ${longitude} ${latitude} ${distance}km ${timespan}yr`; + }); + + probabilityTableData = computed(() => + plotUtils.plotDataToTableData(this.service.plots().probability, { + addLabel: true, + }) + ); + + rateTableData = computed(() => + plotUtils.plotDataToTableData(this.service.plots().rate, { + addLabel: true, + yLabelTransform: () => 'Rate (1/yr)', + yValueFormat: (y: number) => y.toExponential(4), + }) + ); + + constructor(private service: AppService) {} +} diff --git a/projects/nshmp-apps/src/app/source/rates/components/parameter-summary/parameter-summary.component.html b/projects/nshmp-apps/src/app/source/rates/components/parameter-summary/parameter-summary.component.html new file mode 100644 index 0000000000000000000000000000000000000000..d596d5681017ff71a8c2195d82518d33ff00377d --- /dev/null +++ b/projects/nshmp-apps/src/app/source/rates/components/parameter-summary/parameter-summary.component.html @@ -0,0 +1,45 @@ +<div class="grid-row parameter-summary"> + <div class="grid-col-12 tablet:grid-col-6"> + <mat-list class="parameter-list"> + <!-- Model --> + <mat-list-item> + <span class="parameter">Model</span>: + {{ toDisplay(formGroup.value.model, service.availableModels()) }} + </mat-list-item> + + <!-- Longitude --> + <mat-list-item> + <span class="parameter">Latitude</span>: + @if (!isNaN(formGroup.value.latitude)) { + {{ formGroup.value.latitude }} + } + ° + </mat-list-item> + + <!-- Latitude --> + <mat-list-item> + <span class="parameter">Longitude</span>: + @if (!isNaN(formGroup.value.longitude)) { + {{ formGroup.value.longitude }} + } + ° + </mat-list-item> + </mat-list> + </div> + + <div class="grid-col-12 tablet:grid-col-6"> + <mat-list class="parameter-list"> + <!-- Distance --> + <mat-list-item> + <span class="parameter">Cutoff Distance</span>: + {{ formGroup.value.distance }} km + </mat-list-item> + + <!-- Timespan --> + <mat-list-item> + <span class="parameter">Timespan</span>: + {{ formGroup.value.timespan }} yr + </mat-list-item> + </mat-list> + </div> +</div> diff --git a/projects/nshmp-apps/src/app/source/rates/components/parameter-summary/parameter-summary.component.scss b/projects/nshmp-apps/src/app/source/rates/components/parameter-summary/parameter-summary.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/projects/nshmp-apps/src/app/source/rates/components/parameter-summary/parameter-summary.component.spec.ts b/projects/nshmp-apps/src/app/source/rates/components/parameter-summary/parameter-summary.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..03b132274cd3084ca2728ffd70a1566f0da6aa42 --- /dev/null +++ b/projects/nshmp-apps/src/app/source/rates/components/parameter-summary/parameter-summary.component.spec.ts @@ -0,0 +1,30 @@ +import {provideHttpClient} from '@angular/common/http'; +import {ComponentFixture, TestBed} from '@angular/core/testing'; +import {provideNoopAnimations} from '@angular/platform-browser/animations'; +import {provideRouter} from '@angular/router'; + +import {ParameterSummaryComponent} from './parameter-summary.component'; + +describe('ParameterSummaryComponent', () => { + let component: ParameterSummaryComponent; + let fixture: ComponentFixture<ParameterSummaryComponent>; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [ParameterSummaryComponent], + providers: [ + provideHttpClient(), + provideRouter([]), + provideNoopAnimations(), + ], + }).compileComponents(); + + fixture = TestBed.createComponent(ParameterSummaryComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/projects/nshmp-apps/src/app/source/rates/components/parameter-summary/parameter-summary.component.ts b/projects/nshmp-apps/src/app/source/rates/components/parameter-summary/parameter-summary.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..fc35dec54a444de1c5fe4862e6174b36739c201b --- /dev/null +++ b/projects/nshmp-apps/src/app/source/rates/components/parameter-summary/parameter-summary.component.ts @@ -0,0 +1,22 @@ +import {Component} from '@angular/core'; +import {MatListModule} from '@angular/material/list'; +import {nshmpUtils} from '@ghsc/nshmp-lib-ng/nshmp'; + +import {AppService} from '../../services/app.service'; + +@Component({ + imports: [MatListModule], + selector: 'app-parameter-summary', + standalone: true, + styleUrl: './parameter-summary.component.scss', + templateUrl: './parameter-summary.component.html', +}) +export class ParameterSummaryComponent { + isNaN = Number.isNaN; + /** Function to get display from a `Parameter` */ + toDisplay = nshmpUtils.parameterToDisplay; + + formGroup = this.service.formGroup; + + constructor(public service: AppService) {} +} diff --git a/projects/nshmp-apps/src/app/source/rates/components/plots/plots.component.html b/projects/nshmp-apps/src/app/source/rates/components/plots/plots.component.html index e88f420e90814b762607df5e6d77936c93b895d4..4918f861473223225efba508b45152a7c81d3f3e 100644 --- a/projects/nshmp-apps/src/app/source/rates/components/plots/plots.component.html +++ b/projects/nshmp-apps/src/app/source/rates/components/plots/plots.component.html @@ -13,5 +13,25 @@ } </mat-expansion-panel> } + + <!-- Parameter summary --> + <mat-expansion-panel expanded> + <mat-expansion-panel-header> + <mat-panel-title>Parameter Summary</mat-panel-title> + </mat-expansion-panel-header> + + <mat-divider /> + <app-parameter-summary /> + </mat-expansion-panel> + + <!-- App metadata --> + <mat-expansion-panel expanded> + <mat-expansion-panel-header> + <mat-panel-title>Application Metadata</mat-panel-title> + </mat-expansion-panel-header> + + <mat-divider /> + <nshmp-lib-ng-app-metadata [repositories]="repositories()" /> + </mat-expansion-panel> </mat-accordion> </nshmp-lib-ng-plots-container> diff --git a/projects/nshmp-apps/src/app/source/rates/components/plots/plots.component.ts b/projects/nshmp-apps/src/app/source/rates/components/plots/plots.component.ts index 6b0069cef453ad95a1b5bdc7b0ae8953b45861bf..9cf3905b8475fdb78f705a9e3dae7c95c7d20c40 100644 --- a/projects/nshmp-apps/src/app/source/rates/components/plots/plots.component.ts +++ b/projects/nshmp-apps/src/app/source/rates/components/plots/plots.component.ts @@ -1,12 +1,14 @@ import {Component, computed} from '@angular/core'; import {MatDivider} from '@angular/material/divider'; import {MatExpansionModule} from '@angular/material/expansion'; +import {NshmpLibNgAppMetadataComponent} from '@ghsc/nshmp-lib-ng/nshmp'; import { NshmpLibNgPlotComponent, NshmpLibNgPlotsContainerComponent, } from '@ghsc/nshmp-lib-ng/plot'; import {AppService} from '../../services/app.service'; +import {ParameterSummaryComponent} from '../parameter-summary/parameter-summary.component'; @Component({ imports: [ @@ -14,6 +16,8 @@ import {AppService} from '../../services/app.service'; MatDivider, NshmpLibNgPlotComponent, NshmpLibNgPlotsContainerComponent, + ParameterSummaryComponent, + NshmpLibNgAppMetadataComponent, ], selector: 'app-plots', standalone: true, @@ -26,5 +30,8 @@ export class PlotsComponent { this.service.plots().probability, ]); + /** Repo metadata */ + repositories = computed(() => this.service.usage()?.metadata.repositories); + constructor(private service: AppService) {} } diff --git a/projects/nshmp-apps/src/app/source/rates/services/app.service.ts b/projects/nshmp-apps/src/app/source/rates/services/app.service.ts index c4862fb17d812a2ac919bcfc4009855946465129..908b6ae8dcc84134f9e1762532dae1a9ea82fe8b 100644 --- a/projects/nshmp-apps/src/app/source/rates/services/app.service.ts +++ b/projects/nshmp-apps/src/app/source/rates/services/app.service.ts @@ -99,6 +99,14 @@ export class AppService ); } + get hasData(): Signal<boolean> { + return computed( + () => + this.state().rateResponse !== null && + this.state().probabilityResponse !== null + ); + } + /** * Add form group validators. */ diff --git a/projects/nshmp-apps/src/app/source/source.routes.ts b/projects/nshmp-apps/src/app/source/source.routes.ts index 185850d6772e7f8f41ee496f2f7eceb36f40eb68..36e53d53bbf319fb4fc9ff83332325089d2da692 100644 --- a/projects/nshmp-apps/src/app/source/source.routes.ts +++ b/projects/nshmp-apps/src/app/source/source.routes.ts @@ -20,11 +20,11 @@ const routes: Routes = [ path: 'mfd', }, // Rates application - // { - // loadComponent: () => - // import('./rates/app.component').then(com => com.AppComponent), - // path: 'rates', - // }, + { + loadComponent: () => + import('./rates/app.component').then(com => com.AppComponent), + path: 'rates', + }, ]; /**